DynamoDB 現在有提供本地端使用的 docker image,接下來我們就使用它來進行練習吧。
本機 DynamoDB 表現和 AWS 上的 DynamoDB 有一些差異,不過只是基本操作練習的話不影響。
預設資料都會被儲存在記憶體中,所以重開資料就會消失。
安裝 Docker 的部分網路上有很多相關教學,這邊就不贅述了,如果不熟指令的人可以選擇安裝 Docker Desktop 使用它提供的畫面操作。
取得 dynamodb-local 的 image。
> docker pull amazon/dynamodb-local
將該 image run 起來,指定 port 1234
(或其他你想要的 port 也可以),並命名為 ironman-dynamodb-demo
。
> docker run -p 1234:8000 --name ironman-dynamodb-demo amazon/dynamodb-local
接著安裝 AWS CLI 並設定 Configure,讓我們可以透過 CLI 對剛剛 run 起來的 dynamodb-local 進行操作。
下載位置
可以執行 aws --version
看看有沒有顯示版本,來確認是否安裝成功。
> aws --version
得到結果:
aws-cli/2.7.31 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
其中的 AWS Access Key ID
和 AWS Secret Access Key
隨意設定,Default region name
可從 AWS Region 清單中任意挑一個。
> aws cofigure
AWS Access Key ID [None]: JustTypeSomething
AWS Secret Access Key [None]: JustTypeSomething
Default region name [None]: ap-southeast-1
Default output format [None]:
建立好環境之後,我們就可以透過 CLI 對 DB 進行操作了。假設我們要建立一個「使用者通知設定」的系統,資料表設計如下:
Throughput 相關資訊這邊不再花篇幅描述,請見官方文件。
> aws dynamodb create-table --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--attribute-definitions ^
AttributeName=UserId,AttributeType=S ^
AttributeName=NotificationMethod,AttributeType=S ^
--key-schema ^
AttributeName=UserId,KeyType=HASH ^
AttributeName=NotificationMethod,KeyType=RANGE ^
--provisioned-throughput ^
ReadCapacityUnits=5,WriteCapacityUnits=5
成功建立的話,會輸出該 Table 的資訊。
{
"TableDescription": {
"AttributeDefinitions": [
{
"AttributeName": "UserId",
"AttributeType": "S"
},
{
"AttributeName": "NotificationMethod",
"AttributeType": "S"
}
],
"TableName": "NotificationSettings",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "NotificationMethod",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2022-09-16T00:52:29.563000+08:00",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T08:00:00+08:00",
"LastDecreaseDateTime": "1970-01-01T08:00:00+08:00",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/NotificationSettings"
}
}
也可以透過查看現有的 Table 清單,確認是否建立成功。
> aws dynamodb list-tables --endpoint-url http://localhost:1234
得到結果:
{
"TableNames": [
"NotificationSettings"
]
}
使用者 Anderson 設定以 Email 接收通知。
> aws dynamodb put-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--item ^
"{\"UserId\":{\"S\":\"Anderson\"},\"NotificationMethod\":{\"S\":\"Email\"},\"Address\":{\"S\":\"anderson123@mail.com\"}}"
使用者 Betty 設定以 Email 和 Android App 推播接收通知。
> aws dynamodb put-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--item ^
"{\"UserId\":{\"S\":\"Betty\"},\"NotificationMethod\":{\"S\":\"Email\"},\"Address\":{\"S\":\"betty456@mail.com\"}}"
> aws dynamodb put-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--item ^
"{\"UserId\":{\"S\":\"Betty\"},\"NotificationMethod\":{\"S\":\"Android\"},\"RegistrationId\":{\"S\":\"b2fe650c-b19a-4556-b5c4-43fcbd6b478e\"}}"
接著我們查詢看看剛剛新增的資料是否都有成功寫入資料庫中。
查詢 Anderson 的 Email 通知設定:
> aws dynamodb get-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key "{\"UserId\":{\"S\":\"Anderson\"},\"NotificationMethod\":{\"S\":\"Email\"}}"
得到結果:
{
"Item": {
"Address": {
"S": "anderson123@mail.com"
},
"UserId": {
"S": "Anderson"
},
"NotificationMethod": {
"S": "Email"
}
}
}
查詢 Betty 的 Email 通知設定:
> aws dynamodb get-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key "{\"UserId\":{\"S\":\"Betty\"},\"NotificationMethod\":{\"S\":\"Email\"}}"
得到結果:
{
"Item": {
"Address": {
"S": "betty456@mail.com"
},
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Email"
}
}
}
查詢 Betty 的 Android App 推播通知設定:
> aws dynamodb get-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key "{\"UserId\":{\"S\":\"Betty\"},\"NotificationMethod\":{\"S\":\"Android\"}}"
得到結果:
{
"Item": {
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Android"
},
"RegistrationId": {
"S": "b2fe650c-b19a-4556-b5c4-43fcbd6b478e"
}
}
}
查詢不存在的資料,如 Anderson 的 Android App 推播通知設定,則不會有任何回傳。
只指定 Partition Key 進行查詢,可以取得該 Partition Key 下的所有 Items。
查詢 Betty 的所有通知設定:
> aws dynamodb query --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key-condition-expression "UserId = :name" ^
--expression-attribute-values "{\":name\":{\"S\":\"Betty\"}}"
得到結果:
{
"Items": [
{
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Android"
},
"RegistrationId": {
"S": "b2fe650c-b19a-4556-b5c4-43fcbd6b478e"
}
},
{
"Address": {
"S": "betty456@mail.com"
},
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Email"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
接著試著修改 Betty 的 Email,更多的表達式規格請見官方文件,另外透過參數 --return-value ALL_NEW
要求回傳新資料。
> aws dynamodb update-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key "{\"UserId\":{\"S\":\"Betty\"},\"NotificationMethod\":{\"S\":\"Email\"}}" ^
--update-expression "SET Address = :newval" ^
--expression-attribute-values "{\":newval\":{\"S\":\"new_betty456@mail.com\"}}" ^
--return-values ALL_NEW
得到結果:
{
"Attributes": {
"Address": {
"S": "new_betty456@mail.com"
},
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Email"
}
}
}
最後透過 CLI 將 Anderson 的資料刪除。
> aws dynamodb delete-item --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--key "{\"UserId\":{\"S\":\"Anderson\"},\"NotificationMethod\":{\"S\":\"Email\"}}"
除了最基本的 CRUD 操作,多數應用情境同時也會有一些非 PK 的查詢的需求,這時就需要透過 Secondary Index 達成。
建立 Address 欄位的 Global Secondary Index:
> aws dynamodb update-table --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--attribute-definitions AttributeName=Address,AttributeType=S ^
--global-secondary-index-updates "[{\"Create\":{\"IndexName\":\"Address-Index\",\"KeySchema\":[{\"AttributeName\":\"Address\",\"KeyType\":\"HASH\"}],\"ProvisionedThroughput\":{\"ReadCapacityUnits\":10,\"WriteCapacityUnits\":5},\"Projection\":{\"ProjectionType\":\"ALL\"}}}]"
得到結果:
{
"TableDescription": {
"AttributeDefinitions": [
{
"AttributeName": "Address",
"AttributeType": "S"
},
{
"AttributeName": "UserId",
"AttributeType": "S"
},
{
"AttributeName": "NotificationMethod",
"AttributeType": "S"
}
],
"TableName": "NotificationSettings",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "NotificationMethod",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2022-09-17T02:48:57.773000+08:00",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T08:00:00+08:00",
"LastDecreaseDateTime": "1970-01-01T08:00:00+08:00",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"TableSizeBytes": 327,
"ItemCount": 5,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/NotificationSettings",
"GlobalSecondaryIndexes": [
{
"IndexName": "Address-Index",
"KeySchema": [
{
"AttributeName": "Address",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexStatus": "CREATING",
"Backfilling": false,
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 5
},
"IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/NotificationSettings/index/Address-Index"
}
]
}
}
建立好 Address 的 Index 後,就可以使用 Address 進行查詢:
> aws dynamodb query --endpoint-url http://localhost:1234 ^
--table-name NotificationSettings ^
--index-name Address-Index ^
--key-condition-expression "Address = :addr" ^
--expression-attribute-values "{\":addr\":{\"S\":\"new_betty456@mail.com\"}}"
得到結果:
{
"Items": [
{
"Address": {
"S": "new_betty456@mail.com"
},
"UserId": {
"S": "Betty"
},
"NotificationMethod": {
"S": "Email"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}