使用全局二级索引创建DynamoDB表

时间:2013-12-22 21:49:08

标签: php database-design amazon-web-services nosql amazon-dynamodb

我是AWS DynamoDB和一般nosql的新手,我在创建表时遇到问题。

我正在尝试使用以下属性创建名为User的表:

  • UserId(HASH)
  • OSType(RANGE)
  • MSISDN
  • IMSI
  • 的DeviceID

我不仅要通过UserId查询表格,还要通过以下字段查询表格:

  • MSISDN
  • IMSI
  • 的DeviceID

我的逻辑如下:

  1. UserId字段查询表格。
  2. 如果返回的查询没有结果,请创建一个新结果,但检查是否存在相同MSISDN归档 OR 相同IMSI字段 OR 相同的DeviceID字段。
  3. 阅读manual about LSI/GSI后,我无法理解如何创建表并定义这些索引。

    这是我要使用PHP + AWS SDK执行以创建表的代码:

        $client->createTable(array(
        'TableName' => 'User',
        'AttributeDefinitions' => array(
            array('AttributeName' => 'UserId',      'AttributeType' => 'S'),
            array('AttributeName' => 'OSType',      'AttributeType' => 'S'),
            array('AttributeName' => 'MSISDN',      'AttributeType' => 'S'),
            array('AttributeName' => 'IMSI',        'AttributeType' => 'S'),
            array('AttributeName' => 'DeviceID',    'AttributeType' => 'S'),
        ),
        'KeySchema' => array(
            array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
            array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
        ),
        'GlobalSecondaryIndexes' => array(
            array(
                'IndexName' => 'IMSIIndex',
                'KeySchema' => array(
                    array('AttributeName' => 'IMSI',    'KeyType' => 'HASH')
                ),
                'Projection' => array(
                    'ProjectionType' => 'KEYS_ONLY',
                ),
                'ProvisionedThroughput' => array(
                    'ReadCapacityUnits'  => 10,
                    'WriteCapacityUnits' => 10
                )
            ),
            array(
                'IndexName' => 'MSISDNIndex',
                'KeySchema' => array(
                    array('AttributeName' => 'MSISDN',  'KeyType' => 'HASH')
                ),
                'Projection' => array(
                    'ProjectionType' => 'KEYS_ONLY',
                ),
                'ProvisionedThroughput' => array(
                    'ReadCapacityUnits'  => 10,
                    'WriteCapacityUnits' => 10
                )
            ),
            array(
                'IndexName' => 'DeviceIDIndex',
                'KeySchema' => array(
                    array('AttributeName' => 'DeviceID',    'KeyType' => 'HASH')
                ),
                'Projection' => array(
                    'ProjectionType' => 'KEYS_ONLY',
                ),
                'ProvisionedThroughput' => array(
                    'ReadCapacityUnits'  => 10,
                    'WriteCapacityUnits' => 10
                )
            ),
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 50,
            'WriteCapacityUnits' => 50
        )
    ));
    

    我收到了这个错误:

    PHP Fatal error:  Uncaught Aws\DynamoDb\Exception\ValidationException: AWS Error Code: ValidationException, Status Code: 400, AWS Request ID: 70LGIARTTQF90S8P0HVRUKSJ27VV4KQNSO5AEMVJF66Q9ASUAAJG, AWS Error Type: client, AWS Error Message: One or more parameter values were invalid: Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions, User-Agent: aws-sdk-php2/2.4.11 Guzzle/3.7.4 curl/7.29.0 PHP/5.4.14
    

    请帮助我理解我做错了什么。我想用GSI创建表,但我无法理解DynamoDB中二级索引的本质:(

2 个答案:

答案 0 :(得分:3)

只应在AttributeDefinitions部分中定义包含在本地索引和全局索引中的属性。

答案 1 :(得分:2)

这应该有效:

$client->createTable(array(
'TableName' => 'User',
'AttributeDefinitions' => array(
    array('AttributeName' => 'UserId',      'AttributeType' => 'S'),
    array('AttributeName' => 'OSType',      'AttributeType' => 'S')
),
'KeySchema' => array(
    array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
    array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
),
'GlobalSecondaryIndexes' => array(
    array(
        'IndexName' => 'IMSIIndex',
        'KeySchema' => array(
            array('AttributeName' => 'IMSI',    'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
    array(
        'IndexName' => 'MSISDNIndex',
        'KeySchema' => array(
            array('AttributeName' => 'MSISDN',  'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
    array(
        'IndexName' => 'DeviceIDIndex',
        'KeySchema' => array(
            array('AttributeName' => 'DeviceID',    'KeyType' => 'HASH')
        ),
        'Projection' => array(
            'ProjectionType' => 'KEYS_ONLY',
        ),
        'ProvisionedThroughput' => array(
            'ReadCapacityUnits'  => 10,
            'WriteCapacityUnits' => 10
        )
    ),
),
'ProvisionedThroughput' => array(
    'ReadCapacityUnits'  => 50,
    'WriteCapacityUnits' => 50
)));

希望有所帮助