如何使用dynamodb将两个表与主键连接起来

时间:2016-05-06 14:03:12

标签: amazon-dynamodb

我是DynamoDB的新手。我有两张桌子:

  • 国家
  • 城市

我希望通过country_id主键和外键加入两个表。我可以在DynamoDB中执行此操作吗?

3 个答案:

答案 0 :(得分:3)

Amazon DynamoDB是NoSQL数据库。这意味着传统的关系数据库概念(如JOIN和外键)不可用

您的申请将负责"加入"表。也就是说,您需要从两个表中读取值,并确定应用程序中它们之间的关系。 DynamoDB无法为您执行此操作。

或者,您可以使用提供Hadoop的 Amazon EMR 等系统。您可以使用Hadoop和Hive通过使用HiveQL(类似于SQL)访问DynamoDB表。但是,这是一个非常慢的操作,可能太复杂,无法满足您的特定要求。

答案 1 :(得分:0)

正如@John所说,Amazon DynamoDB是NoSQL数据库。因此,不可能在一个查询中执行此操作。但是,当然,您可以根据需要通过多个查询获取数据。下面是dynamoDB表方案。(这也是表创建代码)

import { CreateTableInput } from 'aws-sdk/clients/dynamodb';
import AWS from 'aws-sdk'

const paramCountryTable: CreateTableInput = {
  BillingMode: 'PAY_PER_REQUEST',       // for just example
  TableName: 'Country',
  AttributeDefinitions: [
    { AttributeName: 'country_id', AttributeType: 'S' },
  ],
  KeySchema: [
    { AttributeName: 'country_id', KeyType: 'HASH' },
  ],
}

const paramCityTable: CreateTableInput = {
  BillingMode: 'PAY_PER_REQUEST',       // for just example
  TableName: 'City',
  AttributeDefinitions: [
    { AttributeName: 'city_id', AttributeType: 'S' },
    { AttributeName: 'country_id', AttributeType: 'S' },
  ],
  KeySchema: [
    { AttributeName: 'city_id', KeyType: 'HASH' },
  ],
  GlobalSecondaryIndexes: [{
    Projection: { ProjectionType: 'ALL' },
    IndexName: 'IndexCountryId',
    KeySchema: [
      { AttributeName: 'country_id', KeyType: 'HASH' },
    ],
  }],
}

const run = async () => {
  const dd = new AWS.DynamoDB({ apiVersion: '2012-08-10' })
  await dd.createTable(paramCountryTable).promise()
  await dd.createTable(paramCityTable).promise()
}

if (require.main === module) run()

然后,您可以通过以下几个查询来实现所需的内容。

const ddc = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' })

const getCountryByCityId = async (city_id: string) => {
    const resultCity = await ddc.get({ TableName: 'City', Key: {city_id}}).promise()
    if (!resultCity.Item) return null

    const { country_id } = resultCity.Item
    const resultCountry = await ddc.get({ TableName: 'Country', Key: {country_id}}).promise()
    return resultCountry.Item
}

const getCityArrByCountryId = async (country_id: string) => {
    const result = await ddc.query({ 
        TableName: 'City',
        IndexName: 'IndexCountryId',
        ExpressionAttributeValues: { ":country_id": country_id },
        KeyConditionExpression: "country_id = :country_id",
    }).promise()

    return result.Items
}
  

请注意,这不是NoSQL的推荐用例。

答案 2 :(得分:-1)

不幸的是,DynamoDB不支持联接。 DynamoDB的查询能力非常有限。您可以为表指定分区键和可选的排序键以查询表,就是这样。

名为Rockset的服务可以拖尾DynamoDB表并在其上提供功能齐全的SQL。它支持具有联接和子查询的任意复杂的查询。

此博客讨论如何使用Rockset通过SQL查询DynamoDB表中的数据: https://rockset.com/blog/running-fast-sql-on-dynamodb-tables

全面披露:我在Rockset的工程团队工作。