Difference between revisions of "Dynamodb"

From John Freier
Jump to: navigation, search
 
(5 intermediate revisions by the same user not shown)
Line 2: Line 2:
  
 
This is a NoSQL database.
 
This is a NoSQL database.
 +
 +
== DynamoDB Local ==
 +
Amazon has a local version of the DynamoDB that can be downloaded and ran, for development purposes.
 +
 +
1. Download the dynamodb_local_latest.tar.gz
 +
2. Extract
 +
3. Run
 +
  java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
 +
 +
When ran a file gets created that holds the data.  If deleted...data lost.
 +
  shared-local-instance.db
  
 
== Partition Key and Sort Key ==
 
== Partition Key and Sort Key ==
 
There are two types of keys that can be used to define a primary key.
 
There are two types of keys that can be used to define a primary key.
  
Partition keys are the how the database separates data in the backend.
+
Partition keys are the how the database separates data in the backend.  There are used to optimize queries.
 +
When using `scan`, DynamoDB will go through ever record in the table, when using `query`, it will look in the partition.
  
 
Sort keys allow you to sort data by a secondary column.
 
Sort keys allow you to sort data by a secondary column.
Line 12: Line 24:
 
If more sorting is required, take a look at using Local Global Index.
 
If more sorting is required, take a look at using Local Global Index.
  
== Secondary Global Index ==
+
When adding data, which ever is setup...These fields will be required, all other data is optional.
 +
 
 +
== Global Secondary Index ==
 
This allows you to create a super table from the base table, to allow for different keys and sorting when using the `query` command.
 
This allows you to create a super table from the base table, to allow for different keys and sorting when using the `query` command.
  
Line 24: Line 38:
 
   var params = {
 
   var params = {
 
       TableName: "statements",
 
       TableName: "statements",
       AttributeDefinitions: [{
+
       AttributeDefinitions: [{     // Attributes are the items that are used in the key definitions and GSI/LSI.
 
               AttributeName: "id",
 
               AttributeName: "id",
               AttributeType: "S"
+
               AttributeType: "S"   // S - String
 
           },
 
           },
 
           {
 
           {
 
               AttributeName: "time",
 
               AttributeName: "time",
               AttributeType: "N"
+
               AttributeType: "N"   // N - Number
 
           },
 
           },
 
           {
 
           {
Line 58: Line 72:
 
           ],
 
           ],
 
           Projection: {
 
           Projection: {
               ProjectionType: 'ALL'
+
               ProjectionType: 'ALL'   // KEY_ONLY, INCLUDE, ALL - This holds the columns that are used in the GSI and returned when queried.
 
           },
 
           },
 
           ProvisionedThroughput: {
 
           ProvisionedThroughput: {
Line 81: Line 95:
 
Example query
 
Example query
 
     this.findLatest = async function(table, userId) {
 
     this.findLatest = async function(table, userId) {
        console.log('userId:' + userId + ' table:' + table);
 
 
         var params = {
 
         var params = {
 
             TableName: table,
 
             TableName: table,
             IndexName: 'statement_user_index',
+
             IndexName: 'statement_user_index',     // Must have the indexName too query against an GSI index.
             KeyConditionExpression: 'userId = :userId',
+
             KeyConditionExpression: 'userId = :userId',   // Must contain the key
             ExpressionAttributeValues: { ':userId': userId },
+
             ExpressionAttributeValues: { ':userId': userId }, // Used like prepared statements.
             Limit: 1,
+
             Limit: 1, // Number of results returned (optional)
             ScanIndexForward: false
+
             ScanIndexForward: false // Ascending or Descending. (Optional)
 
         };
 
         };
 
         try {
 
         try {
 
             const results = await docClient.query(params).promise();
 
             const results = await docClient.query(params).promise();
            console.log('Find latest ', results);
 
 
             return results.Items;
 
             return results.Items;
 
         } catch (err) {
 
         } catch (err) {
Line 101: Line 113:
  
  
== Local Global Index ==
+
== Local Secondary Index ==
Local global index, creates a super table on top of the base table to allow for more sorting abilities.
+
This creates a super table on top of the base table to allow for more sorting abilities only.
 +
 
 +
Example
 +
  var AWS = require("aws-sdk");
 +
  AWS.config.update({
 +
      region: "local",
 +
      endpoint: "http://localhost:8000"
 +
  });
 +
  var dynamodb = new AWS.DynamoDB();
 +
  var params = {
 +
      TableName: "statements",
 +
      AttributeDefinitions: [{    // Attributes are the items that are used in the key definitions and GSI/LSI.
 +
              AttributeName: "id",
 +
              AttributeType: "S"  // S - String
 +
          },
 +
          {
 +
              AttributeName: "time",
 +
              AttributeType: "N"  // N - Number
 +
          },
 +
          {
 +
              AttributeName: "userId",
 +
              AttributeType: "S"
 +
          }
 +
      ],
 +
      KeySchema: [{
 +
              AttributeName: "id",
 +
              KeyType: "HASH"
 +
          }, //Partition key
 +
          {
 +
              AttributeName: "userId",
 +
              KeyType: "RANGE"
 +
          }, //Sort key
 +
      ],
 +
      LocalSecondaryIndexes: [{
 +
          IndexName: 'statement_user_index',
 +
          KeySchema: [{
 +
                  AttributeName: "id",  // Must have the same key as the base.
 +
                  KeyType: "HASH"
 +
              },
 +
              {
 +
                  AttributeName: 'time',  // This is the secondary sort key.
 +
                  KeyType: 'RANGE',
 +
              }
 +
          ],
 +
          Projection: {
 +
              ProjectionType: 'ALL'    // KEY_ONLY, INCLUDE, ALL - This holds the columns that are used in the GSI and returned when queried.
 +
          },
 +
          ProvisionedThroughput: {
 +
              WriteCapacityUnits: 5,
 +
              ReadCapacityUnits: 5
 +
          }
 +
      }],
 +
      ProvisionedThroughput: {
 +
          ReadCapacityUnits: 5,
 +
          WriteCapacityUnits: 5
 +
      }
 +
  };
 +
  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));
 +
      }
 +
  });
 +
 
 +
 
 +
== Get a record ==
 +
        var params = {
 +
            TableName: table,
 +
            Key: {
 +
                "id": id
 +
            }
 +
        };
 +
        try {
 +
            const results = await docClient.get(params).promise();
 +
            console.log('Find by id ' + id, JSON.stringify(results, null, 2));
 +
            return results;
 +
        } catch (err) {
 +
            console.log(err);
 +
            throw err;
 +
        };
 +
 
 +
 
 +
== Add a record ==
 +
        var params = {
 +
            TableName: table,
 +
            Item: entity
 +
        };
 +
        try {
 +
            const results = await docClient.put(params).promise();
 +
            console.log('Added ', entity);
 +
            return entity;
 +
        } catch (err) {
 +
            console.log(err);
 +
            throw err;
 +
        };
 +
 
 +
 
 +
== Delete a record ==
 +
        var params = {
 +
            TableName: table,
 +
            Key: {
 +
              id: id
 +
            }
 +
        };
 +
        try {
 +
            const results = await docClient.delete(params).promise();
 +
            console.log('Removed ' + id + " from " + table);
 +
            return results;
 +
        } catch (err) {
 +
            console.log(err);
 +
            throw err;
 +
        };

Latest revision as of 13:17, 5 January 2023

DynamoDB is an AWS product that has a stand alone app for development but is really suppose to be built out in AWS where they handle the administration/OPS.

This is a NoSQL database.

DynamoDB Local

Amazon has a local version of the DynamoDB that can be downloaded and ran, for development purposes.

1. Download the dynamodb_local_latest.tar.gz 2. Extract 3. Run

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

When ran a file gets created that holds the data. If deleted...data lost.

 shared-local-instance.db

Partition Key and Sort Key

There are two types of keys that can be used to define a primary key.

Partition keys are the how the database separates data in the backend. There are used to optimize queries. When using `scan`, DynamoDB will go through ever record in the table, when using `query`, it will look in the partition.

Sort keys allow you to sort data by a secondary column.

If more sorting is required, take a look at using Local Global Index.

When adding data, which ever is setup...These fields will be required, all other data is optional.

Global Secondary Index

This allows you to create a super table from the base table, to allow for different keys and sorting when using the `query` command.

Example

 var AWS = require("aws-sdk");
 AWS.config.update({
     region: "local",
     endpoint: "http://localhost:8000"
 });
 var dynamodb = new AWS.DynamoDB();
 var params = {
     TableName: "statements",
     AttributeDefinitions: [{     // Attributes are the items that are used in the key definitions and GSI/LSI.
             AttributeName: "id",
             AttributeType: "S"   // S - String
         },
         {
             AttributeName: "time",
             AttributeType: "N"   // N - Number
         },
         {
             AttributeName: "userId",
             AttributeType: "S"
         }
     ],
     KeySchema: [{
             AttributeName: "id",
             KeyType: "HASH"
         }, //Partition key
         {
             AttributeName: "userId",
             KeyType: "RANGE"
         }, //Sort key 
     ],
     GlobalSecondaryIndexes: [{
         IndexName: 'statement_user_index',
         KeySchema: [{
                 AttributeName: 'userId',
                 KeyType: 'HASH',
             },
             {
                 AttributeName: 'time',
                 KeyType: 'RANGE',
             }
         ],
         Projection: {
             ProjectionType: 'ALL'    // KEY_ONLY, INCLUDE, ALL - This holds the columns that are used in the GSI and returned when queried.
         },
         ProvisionedThroughput: {
             WriteCapacityUnits: 5,
             ReadCapacityUnits: 5
         }
     }],
     ProvisionedThroughput: {
         ReadCapacityUnits: 5,
         WriteCapacityUnits: 5
     }
 };
 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));
     }
 });


Example query

   this.findLatest = async function(table, userId) {
       var params = {
           TableName: table,
           IndexName: 'statement_user_index',     // Must have the indexName too query against an GSI index.
           KeyConditionExpression: 'userId = :userId',   // Must contain the key
           ExpressionAttributeValues: { ':userId': userId },  // Used like prepared statements.
           Limit: 1,  // Number of results returned (optional)
           ScanIndexForward: false  // Ascending or Descending. (Optional)
       };
       try {
           const results = await docClient.query(params).promise();
           return results.Items;
       } catch (err) {
           console.log(err);
           throw err;
       };
   }


Local Secondary Index

This creates a super table on top of the base table to allow for more sorting abilities only.

Example

 var AWS = require("aws-sdk");
 AWS.config.update({
     region: "local",
     endpoint: "http://localhost:8000"
 });
 var dynamodb = new AWS.DynamoDB();
 var params = {
     TableName: "statements",
     AttributeDefinitions: [{     // Attributes are the items that are used in the key definitions and GSI/LSI.
             AttributeName: "id",
             AttributeType: "S"   // S - String
         },
         {
             AttributeName: "time",
             AttributeType: "N"   // N - Number
         },
         {
             AttributeName: "userId",
             AttributeType: "S"
         }
     ],
     KeySchema: [{
             AttributeName: "id",
             KeyType: "HASH"
         }, //Partition key
         {
             AttributeName: "userId",
             KeyType: "RANGE"
         }, //Sort key 
     ],
     LocalSecondaryIndexes: [{
         IndexName: 'statement_user_index',
         KeySchema: [{
                 AttributeName: "id",   // Must have the same key as the base.
                 KeyType: "HASH"
             },
             {
                 AttributeName: 'time',  // This is the secondary sort key.
                 KeyType: 'RANGE',
             }
         ],
         Projection: {
             ProjectionType: 'ALL'    // KEY_ONLY, INCLUDE, ALL - This holds the columns that are used in the GSI and returned when queried.
         },
         ProvisionedThroughput: {
             WriteCapacityUnits: 5,
             ReadCapacityUnits: 5
         }
     }],
     ProvisionedThroughput: {
         ReadCapacityUnits: 5,
         WriteCapacityUnits: 5
     }
 };
 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));
     }
 });


Get a record

       var params = {
           TableName: table,
           Key: {
               "id": id
           }
       };
       try {
           const results = await docClient.get(params).promise();
           console.log('Find by id ' + id, JSON.stringify(results, null, 2));
           return results;
       } catch (err) {
           console.log(err);
           throw err;
       };


Add a record

       var params = {
           TableName: table,
           Item: entity
       };
       try {
           const results = await docClient.put(params).promise();
           console.log('Added ', entity);
           return entity;
       } catch (err) {
           console.log(err);
           throw err;
       };


Delete a record

       var params = {
           TableName: table,
           Key: {
             id: id
           }
       };
       try {
           const results = await docClient.delete(params).promise();
           console.log('Removed ' + id + " from " + table);
           return results;
       } catch (err) {
           console.log(err);
           throw err;
       };