« AWS Black Belt Online Seminar「AWS re:Invent 2016 アップデート速報」資料およびQA公開 | メイン | Amazon Redshift テーブル設計詳細ガイド:Part 1 序文、事前準備、優先順位付け »

【AWS Database Blog】DynamoDBのテーブルを正規化または非正規化する必要性

Gowri BalasubramanianはAmazon Web Servicesのソリューションアーキテクトです。

データベースという文脈において、正規化という用語はデータの冗長性を最小限に抑えるためにリレーショナルデータベースのカラム(属性)とテーブル(関係)を構成するプロセスを意味します。リレーショナルデータベースでの一般的な推奨案は、正規化されたスキーマを使用することです。このブログ記事では、Amazon DynamoDBでテーブル設計するための正しいアプローチについて説明します。

DynamoDBのようなNoSQLデータベースの場合、スキーマを正規化するかどうかはユースケースによって異なります。ただし、ガイドラインとしては、DynamoDBテーブルは次の2つの理由から非正規化スキーマを使用して設計すべきです。

  • DynamoDBはスキーマレスです。DynamoDBでテーブルを作成する場合、ユーザーはプライマリキー属性のみ(たとえばパーティションキー、またはパーティションキーとソートキー)を指定します。ユーザーはその他の属性を事前に定義しません。
  • DynamoDBはテーブル同士の結合をサポートしていません。

あくまでこれはガイドラインです。 反対に、正規化されたスキーマを使用する必要がある状況がいくつかあります。

正規化スキーマを検討すべき状況

  • 400KBを超える項目を格納する必要がある場合。DynamoDBの最大項目サイズは400KBです。大規模な属性(テキストブロックなど)は、分割された別のテーブルまたはAmazon S3に保存できます。
  • さまざまなアクセスパターンが想定される場合。たとえば、顧客が製品を注文するたびにアクセスされるPRODUCT_ORDER表を考えてみてください。このようなテーブルに対しては、読み書き量が異なる複数の要件があります。
  • アプリケーションが大量の更新を実行する場合。DynamoDBでは、書き込み容量ユニット(WCU)とは最大1KBサイズの項目に対する1秒に1回の書き込みと定義されます。1KBを超える項目の頻繁な書き込みは、1回の書き込みで消費されるWCU数に影響します。たとえ単一の属性を更新したとしても、WCUの計算は項目全体のサイズに基づいています。

非正規化スキーマを検討すべき状況

  • 少数の属性しか持たない小さな項目を格納する場合。読み取り時に項目サイズが4KBを超えないようにすべきです。(読み取り容量ユニット(RCU)とは、最大4KBの項目に対する1秒に1回の読み取りと定義されています。)書き込みの場合は、項目サイズが1KB(1WCUのサイズ)を超えないようにすべきです。
  • 複数のテーブル間でのデータの一貫性と同期について考慮する必要がない高トラフィック環境で、アプリケーションがデータを読み書きする場合。
    たとえばANNOTATIONSという名前のテーブルを考えてみましょう。このテーブルには、さまざまな端末で読まれた本の注釈に関する情報が含まれています。顧客がある端末から別の端末に切り替えるたびに、自分の注釈をニアリアルタイムで素早く更新できる必要があります。このシナリオでは、すべての注釈を1個のテーブルに格納することが理にかなっています。

    Partition Key (Customer_id:bookid:content_type) Annonation_Type Description
    Cust1:Book1xxx:pdf Lastread {"deviceType":"ipad", page=100, Posstart:1,Posend:50}
    Cust1:Book2xxx:ebook Highlight {"deviceType":"Andriod", page=231, Posstart:1,Posend:50}
    Cust1:Book3xxx:text Mark {"deviceType":"Kindle", page=242, Posstart:1,Posend:50}
  • アプリケーションが、1個の項目内でアトミックに変更しないといけない複数の属性がある場合。この場合、その項目に関連するすべての属性を同じテーブルに格納する必要があります。
  • 論理的に関連していて同時に参照されるデータにアクセスする必要がある場合。リレーショナルデータベース管理システム(RDBMS)では、通常、このようなデータを別々のテーブルに保存し、結合を実行してデータを検索します。たとえばRDBMS内のCUSTOMERテーブルとADDRESSテーブルを考えてみてください。

    CUSTOMERテーブル

    Custid Transaction_Id Price Order_date Delivery_code
    cust1 XXX.. 200 2013-10-01 98001
    cust2 XXX.. 100 2013-09-05 98002
    cust3 XXX.. 500 2013-10-08 98003
    cust1 XXX.. 1000 2013-09-12 98004

    ADDRESSテーブル

    Zipcode City_name Country
    98001 Bellevue USA
    98002 Renton USA
    98003 Redmond USA
    98004 Seattle USA

    ある顧客の注文時の住所を取得するには、以下のSQLクエリーを使用します。

    SELECT a.custid, a.transaction_id, b.city_name, b.addres
    FROM customer a, address b
    WHERE a.customer=’cust1’ and a.delivery_code=b.zipcode

    DynamoDBでは、このような正規化されたスキーマモデルを使用する理由がありません。DynamoDBは結合をサポートしていませんが、データモデルを非正規化すれば結合する必要がありません。

    Custid Transaction_Id Price Order_date Zipcode City_name Country
    cust1 XXX.. 200 2013-10-01 98001 Bellevue USA
    cust2 XXX.. 100 2013-09-05 98002 Renton USA
    cust3 XXX.. 500 2013-10-08 98003 Redmond USA
    cust1 XXX.. 1000 2013-09-12 98004 Seattle USA

    このようなシンプルな設計では、結合済みの顧客データと住所データは1行あたり数百バイトしか消費しません。このような小さな項目は、DyanamoDBを使用した高速な読み書きに適しています。

まとめ

正規化方針を決定するための万能なガイドラインはありません。これはアプリケーションをリレーショナルデータベースから移行する場合に特に当てはまります。リレーショナルスキーマ設計が前提のシステムの多くは、そのままではNoSQLデータベースにうまく適用できません。

最終的には、選択されるスキーマはアプリケーションのアクセスパターンとデータ項目のサイズによって主に決まります。

参考文献

より詳しく知りたい場合はAmazon DyanmoDB開発者ガイドをご覧ください。

※日本語訳はデータベースSA柴田<@rewse>が担当しました。原文はShould Your DynamoDB Table Be Normalized or Denormalized?

コメント

Twitter, Facebook

このブログの最新情報はTwitterFacebookでもお知らせしています。お気軽にフォローください。

2017年4 月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30