すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB for HBase:行キーの設計

最終更新日:Jan 16, 2025

行キーはテーブル行の一意の識別子であり、クエリとパーティション分割に使用されます。このトピックでは、行キーを設計する前に考慮する必要がある注意事項と制限事項について説明します。また、行キーの設計方法の例も示します。

  • 質問 1:行キーは一意ですか?

    HBase では、同じ行キーを持つレコードは、複数バージョンの 1 つのレコードと見なされます。デフォルトでは、特定のクエリに対してレコードの最新バージョンが返されます。複数バージョン同時実行制御(MVCC)機能を使用しない限り、行キーは一意である必要があります。

    ベストプラクティス:データベーステーブルの主キーと同様の方法で行キーを使用します。行キーはレコードを識別します。行キーは、1 つのフィールドにすることも、複数のフィールドの組み合わせにすることもできます。行キーが [userid] の場合、各ユーザーは 1 つのレコードのみを持ちます。行キーが [userid][orderid] の場合、各ユーザーは複数のレコードを持ちます。

  • 質問 2:行キーはどのように使用しますか?HBase では、次の方法で行キーを使用できます。
    • GET メソッドは、完全な行キーを使用してデータをクエリします。たとえば、次のステートメントを実行してデータをクエリできます。SELECT * FROM table WHERE Rowkey = 'abcde' GET メソッドでは、完全な行キーを指定する必要があります。これは、行キーを構成するすべてのフィールドの値が決定されていることを示します。
    • scan メソッドは、行キーの範囲を使用してデータをクエリします。たとえば、次のステートメントを実行してデータをクエリできます。SELECT * FROM table WHERE 'abc' < Rowkey <'abcx' scan メソッドでは、行キーの左側の値を指定する必要があります。たとえば、英語辞書から接頭辞 pre または prefi を含むすべての単語をクエリできますが、接尾辞 prefi を含む単語や、prefi が中央にある単語をクエリすることはできません。
    ベストプラクティス:次の方法を使用して複雑なクエリを実行できます。
    • インデックステーブルとしてテーブルを作成します。
    • フィルターを使用して、サーバー上で不要なデータをフィルター処理します。
    • セカンダリインデックスを使用します。
    • リバーススキャンメソッドを使用して、データを降順にソートします。この方法では、最初のレコードが最新のデータエントリになります。このメソッドを使用する場合は、次の設定を指定します。scan.setReverse(true) リバーススキャンは、通常の scan よりもパフォーマンスが低下します。ほとんどのシナリオでデータを降順にソートする必要がある場合は、行キーを設計してこの問題を解決できます。たとえば、[hostname][log-event][timestamp] は [hostname][log-event][Long.MAX_VALUE - timestamp] に変更されます。
  • 質問 3:完全に分散されたデータに対してスタックホットスポットが発生しますか?

    いいえ、完全に分散されたデータに対してはホットスポットは発生しません。ハッシュメソッドを使用して、データを異なるパーティションに分散します。これにより、サーバーがホットスポットによって終了したり、他のサーバーがアイドル状態になったりするのを防ぎます。このようにして、分散アーキテクチャと同時処理が効率的に利用されます。

    ベストプラクティス:
    • メッセージダイジェストアルゴリズム 5(MD5)ハッシュアルゴリズムが行キーで指定されています。たとえば、行キー [userId][orderid] は [md5(userid).subStr(0,4)][userId][orderid] に変更されます。
    • リバーススキャンが行キーで指定されています。たとえば、行キー [userId][orderid] は [reverse(userid)][orderid] に変更されます。
    • 剰余演算が行キーで指定されています。たとえば、行キー [timestamp][hostname][log-event] は [bucket][timestamp][hostname][log-event]; long bucket = timestamp % numBuckets に変更されます。
    • 乱数が行キーに追加されます。たとえば、行キー [userId][orderid] は [userId][orderid][random( 100)] に変更されます。
  • 質問 4:行キーの長さの制限は何ですか?

    行キーはできるだけ短くしてください。行キーが短いほど、データ量を削減し、データのクエリと書き込みをより効率的に行うことができます。

    ベストプラクティス:
    • STRING データ型は LONG または INT データ型に置き換えられます。たとえば、'2015122410' は Long(2015122410) に置き換えることができます。
    • 名前はコードに置き換えられます。たとえば、「Taobao」は tb に置き換えられます。
  • 質問 5:scan メソッドを使用して未使用のデータをクエリできますか?

    はい、使用していないデータは scan メソッドを使用してクエリできます。たとえば、table1 の行キーは、column1、column2、および column3 の組み合わせです。column1 の値が host1 であるすべてのレコードをクエリする場合は、scan 'table1',{startkey=> 'host1',endkey=> 'host2'} ステートメントを実行します。column1 の値が host12 であるレコードが使用可能な場合、そのレコードも返されます。

    ベストプラクティス:
    • フィールドの長さが行キーで指定されています。たとえば、行キー [column1][column2] は [rpad(column1,'x',20)][column2] に変更されます。
    • 区切り文字が行キーに追加されます。たとえば、行キー [column1][column2] は [column1][_][column2] に変更されます。

一般的な設計例

  • 行キーは、次のシナリオのログデータと時系列データ用に設計されています。
    • 一定期間に測定されたメトリックのデータをホストからクエリする必要があります。行キーは、この要件を満たすために [hostname][log-event][timestamp] として設計されています。
    • メトリックの最新レコードをホストからクエリする必要があります。行キーは、この要件を満たすために timestamp = Long.MAX_VALUE - timestamp; [hostname][log-event][timestamp] として設計されています。
    • クエリするデータに時間ディメンションしかない場合、またはディメンション内の大量のデータをクエリする必要がある場合。行キーは、この要件を満たすために long bucket = timestamp % numBuckets; [bucket][timestamp][hostname][log-event] として設計されています。
  • 行キーは、次のシナリオのトランザクションデータ用に設計されています。
    • 特定の期間に生成されたトランザクションレコードを販売者についてクエリする必要があります。行キーは、この要件を満たすために [seller id][timestamp][order number] として設計されています。
    • 一定期間に生成されたトランザクションレコードを購入者についてクエリする必要があります。行キーは、この要件を満たすために [buyer id][timestamp][order number] として設計されています。
    • 注文番号を使用してデータをクエリする必要があります。行キーは、この要件を満たすために [order number] として設計されています。
    • 3 つのテーブルからデータをクエリする必要があります。購入者テーブルの行キーは [buyer id][timestamp][order number] として設計されています。販売者テーブルの行キーは [seller id][timestamp][order number] として設計されています。インデックステーブルの行キーは [order number] として設計されています。