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

AnalyticDB:テーブルスキーマ設計

最終更新日:Aug 21, 2026

このトピックでは、パフォーマンスを最適化するための AnalyticDB for MySQL テーブルのスキーマ設計方法について説明します。スキーマには、テーブルタイプ、分散キー、パーティションキー、プライマリキー、クラスター化インデックスキーが含まれます。

テーブルタイプの選択

AnalyticDB for MySQL は、レプリケートテーブルと標準テーブルをサポートしています。テーブルタイプを選択する際は、以下の点を考慮してください。

  • レプリケートテーブルは、クラスターの各ノードにデータのレプリカを保存します。各レプリケートテーブルのデータ量は、最大 20,000 行に制限することを推奨します。

  • 標準テーブル (パーティションテーブルとも呼ばれます) は、分散システムのクエリ機能を使用してクエリパフォーマンスを向上させることができます。標準テーブルは、数千万行から数千億行まで、大量のデータを保存できます。

分散キーの選択

増分データをインポートするには、標準テーブルを作成する際に分散キーとパーティションキーを指定します。これにより、増分データの同期が可能になります。テーブルを作成する際は、DISTRIBUTED BY HASH(column_name,...) 句を使用して分散キーを指定します。その後、テーブルは column_name フィールドのハッシュ値に基づいてシャーディングされます。詳細については、「CREATE TABLE」をご参照ください。

  • 構文

    DISTRIBUTED BY HASH(column_name,...)
  • 使用上の注意

    • トランザクション ID、デバイス ID、ユーザー ID、自動インクリメント列など、値が均等に分散されるフィールドを分散キーとして選択してください。

      説明

      DATE、TIME、TIMESTAMP 型のフィールドは分散キーとして選択しないでください。これらのフィールドは、データ書き込み時にデータスキューを引き起こし、書き込みパフォーマンスを低下させる可能性があります。ほとんどのクエリは、過去 1 日や 1 か月といった時間範囲に限定されます。この場合、クエリ対象のデータは単一のノードにのみ存在する可能性があります。これにより、分散データベースのすべてのノードの処理能力を活用できなくなります。DATE または TIME 型のフィールドは、サブパーティションキーとして使用することを推奨します。詳細については、「パーティションキーの選択」をご参照ください。

    • データシャッフルを削減するために、テーブルの結合に使用されるフィールドを分散キーとして選択してください。たとえば、顧客別に過去の注文を照会する場合は、customer_id フィールドを分散キーとして選択できます。

    • クエリ条件に頻繁に出現するフィールドを分散キーとして選択してください。これにより、分散キーに基づいたパーティションプルーニングが可能になります。

    • 各テーブルは 1 つの分散キーのみを持つことができます。分散キーは 1 つ以上のフィールドを含めることができます。さまざまな複雑なクエリに対応できるよう、分散キーのフィールド数はできるだけ少なくすることを推奨します。

    • テーブル作成時に分散キーを指定しない場合、システムは以下のように処理します。

      • テーブルにプライマリキーがある場合、AnalyticDB for MySQL はプライマリキーをデフォルトの分散キーとして使用します。

      • テーブルにプライマリキーがない場合、AnalyticDB for MySQL__adb_auto_id__ フィールドを追加し、それをプライマリキーおよび分散キーとして使用します。

パーティションキーの選択

分散キーを指定した後、単一のシャードに大量のデータが含まれる場合は、パーティションキーを使用してシャードをさらにパーティション化できます。また、クエリステートメントの WHERE 句にサブパーティションフィールドのフィルター条件を含めることで、パーティションプルーニングをトリガーし、スキャンするデータ量を大幅に削減してデータアクセスパフォーマンスを向上させることができます。テーブルを作成する際は、PARTITION BY 句を使用してサブパーティションを定義します。その後、データは指定されたとおりに分割されます。詳細については、「CREATE TABLE」をご参照ください。

  • 構文

    • column_name フィールドの値を使用してテーブルをパーティション化します。構文は次のとおりです。

      PARTITION BY VALUE(column_name)
    • column_name フィールドの値を %Y%m%d 日付形式 (20210101 など) に変換してテーブルをパーティション化します。構文は次のとおりです。

      PARTITION BY VALUE{(DATE_FORMAT(column_name, '%Y%m%d'))|(FROM_UNIXTIME(column_name, '%Y%m%d'))}
    • column_name フィールドの値を %Y%m 日付形式 (202101 など) に変換してテーブルをパーティション化します。構文は次のとおりです。

      PARTITION BY VALUE{(DATE_FORMAT(column_name, '%Y%m'))|(FROM_UNIXTIME(column_name, '%Y%m'))}
    • column_name フィールドの値を %Y 日付形式 (2021 など) に変換してテーブルをパーティション化します。構文は次のとおりです。

      PARTITION BY VALUE{(DATE_FORMAT(column_name, '%Y'))|(FROM_UNIXTIME(column_name, '%Y'))}
  • 使用上の注意

    • テーブルに大量のデータが含まれる場合、サブパーティションの選択は非常に重要です。テーブルにサブパーティションがない場合、またはサブパーティションが適切に分割されていない場合、AnalyticDB for MySQL クラスターのパフォーマンスに深刻な影響を与える可能性があります。パーティションフィールドの適合性を診断する方法については、「分散フィールドの妥当性診断」をご参照ください。

    • 現在、パーティション分割は年、月、日、または元の値によってのみサポートされています。パーティション分割の粒度が大きすぎたり小さすぎたりすると、クエリおよび書き込みパフォーマンスに影響し、AnalyticDB for MySQL クラスターの安定性にも影響を与える可能性があります。

    • サブパーティションは可能な限り静的な状態に保つことを推奨します。サブパーティションを頻繁に更新することは推奨しません。たとえば、複数の履歴サブパーティションが毎日頻繁に更新されるシナリオがある場合は、使用されているサブパーティションフィールドが適切かどうかを検討してください。

    • LIFECYCLE N キーワードを使用してテーブルのライフサイクルを管理できます。パーティションはソートされ、N を超えるパーティションはフィルタリングされます。

      重要

      各テーブルでサポートされるパーティションの最大数には制限があります。したがって、パーティションテーブル内のデータを永続的に保持することはできません。パーティション制限の詳細については、「制限事項」をご参照ください。

      パーティション数が上限を超えているというエラーが発生し、構成によって制限を調整できない場合は、サブパーティションの粒度を大きくする (たとえば、日単位から月単位のパーティション分割に変更する) か、パーティションキーの設計を最適化してパーティションの総数を削減してください。

プライマリキーの選択

プライマリキーは、各レコードの一意の識別子として機能します。テーブルを作成する際は、PRIMARY KEY 句を使用してプライマリキーを定義できます。詳細については、「CREATE TABLE」をご参照ください。

  • 構文

    PRIMARY KEY (column_name,...)
  • 使用上の注意

    • プライマリキーを持つテーブルのみが、DELETE や UPDATE などのデータ更新操作をサポートします。

    • AnalyticDB for MySQL テーブルのプライマリキーは、単一のフィールドまたは複数のフィールドの組み合わせにすることができます。より優れたテーブルパフォーマンスを実現するために、数値フィールドをプライマリキーとして使用し、できるだけ少ないフィールドを使用することを推奨します。

    • プライマリキーには、分散キーとパーティションキーを含める必要があります。複合プライマリキーの先頭に分散キーとパーティションキーを配置することを推奨します。分散キーはシャード間でのデータの分散方法を決定し、パーティションキーはシャード内で値の範囲によってデータを分割します。プライマリキーに両方が含まれている場合、クエリオプティマイザーはプライマリキーインデックスを使用して、対応するシャードとパーティション内のデータを特定できるため、クエリパフォーマンスが保証されます。

クラスター化インデックスキーの選択

クラスター化インデックスのキー値の論理的な順序により、テーブル内の対応する行の物理的な順序が決まります。クラスター化インデックスキーを選択する際は、以下の点を考慮してください。

  • 各テーブルは 1 つのクラスター化インデックスのみをサポートします。作成方法については、「CREATE TABLE」をご参照ください。

  • クエリに常に含まれるフィールドをクラスター化インデックスキーとして使用してください。たとえば、学校の学生情報システムでは、各学生は自分の最終成績のみを表示する必要があります。この場合、学生 ID をクラスター化インデックスとして定義することで、データの局所性を確保し、クエリパフォーマンスを向上させることができます。

  • クラスター化インデックスはテーブル全体をソートするため、CPU リソースなどのリソースを消費します。クラスター化インデックスは慎重に使用してください。

  • クエリに DESC ソートが含まれる場合、CREATE TABLE ステートメントで CLUSTERED KEY (col1 DESC, col2 DESC) 構文を使用することで、対応するフィールドの DESC ソートを効率的にサポートし、クエリ実行時の追加のソートオーバーヘッドを削減できます。

以下の要件を満たす customer という名前のテーブルを作成します。

  • 顧客のログイン時刻 (login_time 列) に基づいてテーブルデータをパーティション化し、ログイン時刻を %Y%m%d 日付形式に変換します。

  • 最後の 30 パーティションのデータのみを保持します (ライフサイクルは 30) 。

  • 顧客 ID (customer_id 列) に基づいてデータを分散します。

  • login_time, customer_id, phone_num を複合プライマリキーとして設定します。

CREATE TABLE ステートメントは次のとおりです:

CREATE TABLE customer (
customer_id bigint NOT NULL COMMENT '顧客 ID',
customer_name varchar NOT NULL COMMENT '顧客名',
phone_num bigint NOT NULL COMMENT '電話番号',
city_name varchar NOT NULL COMMENT '都市',
sex int NOT NULL COMMENT '性別',
id_number varchar NOT NULL COMMENT 'ID カード番号',
home_address varchar NOT NULL COMMENT '自宅住所',
office_address varchar NOT NULL COMMENT 'オフィス住所',
age int NOT NULL COMMENT '年齢',
login_time timestamp NOT NULL COMMENT 'ログイン時刻',
PRIMARY KEY (login_time, customer_id, phone_num)
 )
DISTRIBUTED BY HASH(customer_id)
PARTITION BY VALUE(DATE_FORMAT(login_time, '%Y%m%d')) LIFECYCLE 30
COMMENT '顧客情報テーブル';

よくある質問

  • Q: サブパーティションを作成した後、テーブルのすべてのサブパーティションとその統計情報を表示するにはどうすればよいですか?

    A: 次の SQL ステートメントを実行して、テーブルのすべてのサブパーティションとその統計情報を表示できます:

    SELECT partition_id, -- パーティション名
              row_count, -- パーティション内の総行数
              local_data_size, -- パーティションのローカルストレージサイズ
              index_size, -- パーティションのインデックスサイズ
              pk_size, -- パーティションのプライマリキーインデックスサイズ
              remote_data_size -- パーティションのリモートストレージサイズ
    FROM information_schema.kepler_partitions
    WHERE schema_name = '$DB'
     AND table_name ='$TABLE' 
     AND partition_id > 0;
    重要

    コンパクションがトリガーされていない増分データのパーティションは表示されません。すべてのサブパーティションのリアルタイムリストを表示するには、select distinct $partition_column from $db.$table; ステートメントを実行してください。

  • Q: シャード数に影響する要因は何ですか? シャード数を自分で変更できますか?

    A: シャード数は、クラスターの作成時に初期仕様に基づいて自動的に計算されます。シャード数を変更することはできません。

  • Q: クラスター仕様の変更はシャード数に影響しますか?

    A: クラスターのアップグレードまたはダウングレードは、シャード数に影響しません。

  • Q: AnalyticDB for MySQL は分散キーまたはパーティションキーの変更をサポートしていますか?

    A: いいえ、サポートしていません。これらのキーを変更するには、テーブルの再作成などが必要になります。詳細については、「ALTER TABLE」をご参照ください。

  • Q: 同じテーブルグループ内のテーブルが満たす必要がある一貫性要件は何ですか?

    A: AnalyticDB for MySQL では、同じテーブルグループ内のすべてのテーブルは、同じ数のプライマリハッシュパーティション、セカンダリリストパーティション、レプリカを持つ必要があります。そうでない場合、テーブルを同じテーブルグループに追加することはできません。