AWS DynamoDB基础使用

因AWS并没有提供mongodb的云服务。所以需要将数据库从mongodb切换到AWS 的dynamodb。

Dynamodb 提供了本地调试版本,本文主要介绍dynamodb本地调试使用。
PS:说句题外话,刚接触感觉很难用,文档感觉已经很久没有维护了。

数据库环境:Linux(Dynamodb环境)
server环境:AWS SDK
server端语言: nodejs(ubuntu)

1 Dynamodb 基本概念

Amazon DynamoDB是一款完全托管的NoSQL数据库服务,可提供快速,可预测的性能和无缝可扩展性。

1.1 DynamoDB 基本结构

DynamoDB 几个概念:tables, items, and attributes。(表,项目和属性)
Table是一个item集合, 每个item又是attributes集合。可以对应理解为mongodb中 集合 文档 属性。
例: People表中的某个项目包含名为PersonID,LastName, FirstName等的属性。

1.2 DynamoDB中主键的概念

DynamoDB不像mongodb默认情况下会生成_id来唯一标识某条数据。所以在DynamoDB中就有了主键的概念。
指定表的主键。主键唯一标识表中的每个项目。(指定某个属性为主键)

DynamoDB支持两种不同的主键:
1 分区键
DynamoDB使用分区键的值作为内部散列函数的输入。散列函数的输出确定项目将存储在其中的分区(DynamoDB内部的物理存储)。
2 复合主键(分区键和排序键)
DynamoDB使用分区键值作为内部散列函数的输入。散列函数的输出确定项目将存储在其中的分区(DynamoDB内部的物理存储)。所有具有相同分区键的项目都按照排序键值存储在一起。
在具有分区键和排序键的表中,有可能两个项具有相同的分区键值。但是,这两个项目必须具有不同的排序键值。
PS:这里我们实际使用上遇到了一个问题,在分区间不同的情况下,确保某个属性唯一还没有找到比较好的方法。

2 部署DynamoDB到本地服务器

1 下载并解压DynamoDB code
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
将code 放到linux 服务器上解压

2 安装Java运行环境(apt 大法)

3 在dynamodb 目录下运行(默认为8000端口)

java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

PS:本地DynamoDb 也不提供图形管理界面

3 测试DynamoDB

以下代码均基于nodejs 的AWS SDK.代码来自官方文档,个人做了相应注释,第一次运行代码可能需要配置AWS身份认证。

官方文档:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.NodeJs.html
API文档 : https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html

新建一个文件夹:安装AWS-SDK

npm install aws-sdk

以下操作均基于主键。

3.1 创建表

var AWS = require("aws-sdk");
AWS.config.update({
  region: "us-west-2",                          //使用哪个区域的aws服务
  endpoint: "http://localhost:8000" //dynamodb位置
});
var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Movies",//表名
    KeySchema: [       //主键
        { AttributeName: "year", KeyType: "HASH"},  //Partition key 分区键
        { AttributeName: "title", KeyType: "RANGE" }  //Sort key    排序键
    ],
    AttributeDefinitions: [//主键数据类型    
        { AttributeName: "year", AttributeType: "N" },//N Number
        { AttributeName: "title", AttributeType: "S" }   //S String
    ],
    ProvisionedThroughput: { //DynamoDB吞吐量配置
        ReadCapacityUnits: 10, 
        WriteCapacityUnits: 10
    }
};
dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

3.2 增加

var docClient = new AWS.DynamoDB.DocumentClient();

var table = "Movies";
var year = 2015;
var title = "The Big New Movie";
var params = {
    TableName:table,//要操作的表名
    Item:{
        "year": year,//主键-分区间
        "title": title,//主键-排序键
        "info":{     //其他属性
            "plot": "Nothing happens at all.",
            "rating": 0
        }
    }
};
console.log("Adding a new item...");
docClient.put(params, function(err, data) {
    if (err) {
        console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Added item:", JSON.stringify(data, null, 2));
    }
});

3.3 读取

var docClient = new AWS.DynamoDB.DocumentClient()
var table = "Movies";//表名必须填
var year = 2015;  //待查询的分区键
var title = "The Big New Movie";//待查询的排序键   如果表建立时设置为复合主键的话,分区键排序键必须都存在
var params = {
    TableName: table,
    Key:{
        "year": year,
        "title": title
    }
};
docClient.get(params, function(err, data) {
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
    }
});

3.4 更新

您可以使用该update方法修改现有项目。您可以更新现有属性的值,添加新属性或删除属性。

var table = "Movies";
var year = 2015;
var title = "The Big New Movie";
// Update the item, unconditionally,
var params = {
    TableName:table,
    Key:{
        "year": year,//分区键
        "title": title//排序键   主键在update接口必须
    },
    UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a",//想要改变值的表达式
    ExpressionAttributeValues:{      //为想要改变的值赋值 
        ":r":5.5,
        ":p":"Everything happens all at once.",
        ":a":["Larry", "Moe", "Curly"]
    },
    ReturnValues:"UPDATED_NEW"//返回更新值,即下中data
};
console.log("Updating the item...");
docClient.update(params, function(err, data) {
   console.log(data);
    if (err) {
        console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
    }
});

该程序用UpdateExpression描述您要对指定项目执行的所有更新。
该ReturnValues参数指示DynamoDB仅返回更新的属性(”UPDATED_NEW”)。
所有以#开头的表示属性名变量;以:开头的表示属性值变量

3.5 删除

通过主键删除表中的单个项目。您可以执行条件删除操作,
条件删除仅适用于在满足特定条件的情况下删除项目。如果满足这些条件,DynamoDB将执行删除操作。否则,该项目不会被删除

var table = "Movies";
var year = 2015;
var title = "The Big New Movie";

var params = {
    TableName:table,//待删除操作的表
    Key:{
        "year":year,//分区键
        "title":title//排序键
    },
    ConditionExpression:"info.rating <= :val",//删除条件表达式
    ExpressionAttributeValues: {
        ":val": 5.0   //条件值 
    }
};
console.log("Attempting a conditional delete...");
docClient.delete(params, function(err, data) {
    if (err) {
        console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
    }
});

以上代码将会执行失败因为不满住条件将
“:val”: 5.0 改为”:val”: 6.0 即可成功

具体更实践用法(query index …)将在下篇blog中说明。

4 一段辅助调试的code

用于遍历表 删除表 查看DynamoDB所有表

var AWS = require("aws-sdk");
let Instructions =`
*******使用说明***********
node demo.js scanall 表名
node demo.js listtables
node demo.js delete 表名
*******使用说明***********`
console.log(Instructions);

AWS.config.update({
  region: "us-west-1",
  endpoint: "http://localhost:8000"
});
var dynamodb = new AWS.DynamoDB();
var docClient = new AWS.DynamoDB.DocumentClient();
var arguments = process.argv.splice(2);
console.log('所传递的参数是:', arguments);

if(arguments[0]  === "delete")
{
    let TableName = arguments[1];
    var params = {
        TableName: TableName
    };
    dynamodb.deleteTable(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else     console.log(data);           // successful response
    });
}
else if (arguments[0] === "scanall") {
    var params = {};
    params.TableName = arguments[1] ? arguments[1] : "users";
    console.log(JSON.stringify(params));
    dynamodb.scan(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else {
            for (var info in data.Items) {
                console.log("{");

                for (var key in data.Items[info]) {
                    console.log("  ", key, ": ", JSON.stringify(data.Items[info][key]));
                }
                console.log("}");
            }
        }
    });
}
else if(arguments[0]  === "listtables")
{
    dynamodb.listTables(function (err, data) {
        console.log('listTables:', data.TableNames);
    });
}
else {
    console.error("operate only support delete scanall listtables");
}

猜你喜欢

转载自blog.csdn.net/m0_37263637/article/details/80501548