このトピックでは、AUTOデータベースで、テーブルの主キーがグローバルかローカルか、およびテーブルの一意キーがグローバルかローカルかを判断する方法について説明します。
主キー
PolarDB-Xでは、主キーにはグローバル主キーとローカル主キーが含まれます。
主キーがグローバルに一意である場合、それはグローバル主キーです。
主キーがパーティション内で一意である場合、それはローカル主キーです。
共通テーブルとブロードキャストテーブル
共通テーブルまたはブロードキャストテーブルの主キーは、グローバルに一意であるため、グローバル主キーです。
例1: 共通テーブルとブロードキャストテーブルのグローバル主キー
## 共通テーブル
CREATE TABLE single_tbl (
id bigint NOT NULL AUTO_INCREMENT、
名前varchar(30) 、
主要なキー (id)
) シングル;
## 放送テーブル
テーブルの作成brd_tbl (
id bigint NOT NULL AUTO_INCREMENT、
名前varchar(30) 、
主要なキー (id)
) 放送; パーティション分割されたテーブル
AUTOデータベースでは、テーブルの作成時にパーティションキーまたはパーティションアルゴリズムを指定しないと、自動パーティションテーブルが作成されます。 テーブルの作成時にパーティションキーまたはパーティションアルゴリズムを指定すると、手動パーティションテーブルが作成されます。
自動パーティションテーブル
自動パーティションテーブルのすべてのプライマリキーは、グローバルに一意であるため、グローバルプライマリキーです。
例2: 自動パーティションテーブルのグローバル主キー
## 自動パーティションテーブル
CREATE TABLE auto_tbl (
id bigint NOT NULL AUTO_INCREMENT、
名前varchar(30) 、
主要なキー (id)
); 手動パーティションテーブル
グローバル主キー
手動パーティションテーブルでは、主キー列にすべてのパーティションキー列が含まれている場合、主キーはグローバルに一意であるため、グローバル主キーになります。
例3: 手動パーティションテーブルのグローバル主キー
key_tblテーブルの主キー列は (id, name, addr) で、すべてのパーティションキー列 (id, addr) が含まれます。 したがって、テーブルの主キーはグローバルに一意であるため、グローバル主キーです。
テーブルの作成key_tbl (
id bigint,
名前varchar(10) 、
addr varchar(30) 、
主要なキー (id、name、addr)
) キーによるパーティー (id、addr); ローカル主キー
手動パーティションテーブルでは、主キー列にすべてのパーティションキー列が含まれていない場合、主キーはローカルの主キーになります。
例4: 手動パーティションテーブルのローカル主キー
list_tblテーブルのパーティションキー列cityは、主キー列に含まれません。 したがって、テーブルの主キーは、パーティション内でのみ一意であり、グローバルに一意ではないため、ローカル主キーです。
CREATE TABLE list_tbl (
order_id bigint、
都市varchar(50) 、
テキスト名、
PRIMARYキー (order_id)
) リストによるパーティー (都市)
(
パーティションp1の値 (「北京」) 、
パーティションp2の値 ("上海") 、
パーティーp3の価値 (「広州」) 、
パーティションp4の値 ("深セン") 、
PARTITION p5の値 (デフォルト)
); 例5: ローカル主キーがグローバルに一意ではない
ローカル主キーはパーティション内でのみ一意ですが、グローバルに一意ではありません。 したがって、主キーの重複が発生する可能性があります。 ここでは、例4のlist_tblテーブルを使用します。 都市列は、テーブル内のパーティションキー列です。 したがって、都市列のデータは異なるパーティションに格納されます。
list_tblテーブルに行を挿入します。 ステートメントが実行されると、データはp1パーティションに格納されます。
INSERT INTO list_tbl(order_id, city, name) VALUES (10001, "Beijing", "phone"); クエリOK、1行が影響同じorder_id値と同じcity値を持つ行をlist_tblテーブルに挿入します。 都市値が同じであるため、行はp1パーティションに格納される予定です。 ステートメントが実行されると、行を挿入できず、主キー競合のエラーが報告されます。 同じプライマリキー値の行を同じパーティションに格納することはできません。 これは、ローカル主キーがパーティション内でのみ一意であることを示します。
INSERT INTO list_tbl(order_id、city、name) VALUES (10001、"Beijing" 、"book"); (1062、"ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] GROUP 'TEST_DB_P00000_GROUP 'ATOM 'dskey_test_db_p00000_group#polardbx-storage-0-master#11.167.60.147-1766#test_db_p00000': キー 'PRIMARY 'のエントリ '10001' の重複)同じorder_id値を持つが異なる都市値 (上海) を持つ行をlist_tblテーブルに挿入します。 行はp4パーティションに格納されることが期待されます。 ステートメントが実行されます。 list_tblテーブルには、同じ主キーを持つ2行が存在します。 これは、ローカル主キーがグローバルに一意ではないことを示します。
INSERT INTO list_tbl (order_id、city、name) VALUES (10001、"深セン" 、"カメラ"); クエリOK、影響を受ける1行 SELECT * からlist_tbl; + --------- ------------ ------------ + | order_id | 都市 | 名前 | + --------- ------------ ------------ + | 10001 | 北京 | 電話 | | 10001 | 深セン | カメラ | + --------- ------------ ------------ + 2行のセット
例6: 主キーが重複しているテーブルでDDLステートメントを実行すると、主キーの競合のエラーが報告される場合があります。
テーブル内で重複するローカル主キーが使用される可能性があるため、パーティション分割ポリシーの変更やテーブルを下流のコンポーネントに同期するというDDLステートメントなど、テーブル上でデータの再配布に関連する操作を実行すると、主キーの競合のエラーが報告されることがあります。
ここでは、例5のlist_tblテーブルを使用します。 テーブルには、同じ主キーを持つ2つの行が既にあります。 1つの行は都市値が北京であるパーティションに格納され、もう1つの行は都市値が深センであるパーティションに格納されます。 次のDDLステートメントを実行して、都市値が北京と深センである行が同じパーティションに格納されるようにパーティション分割ポリシーを変更します。 DDLステートメントが失敗し、主キー競合のエラーが報告されます。 これは、このDDLステートメントが、重複する主キーを持つ行を同じパーティションに格納しようとするためです。これは、ローカル主キーがパーティション内で一意である必要があるという規則に違反しています。
ALTER TABLE list_tbl
リストによるパーティー (都市)
(
パーティションp1の値 ("北京" 、"深セン") 、
パーティションp2の値 ("上海") 、
パーティーp3の価値 (「広州」) 、
PARTITION p5の値 (デフォルト)
);
(4700、"ERR-CODE: [TDDL-4700][ERR_SERVER] サーバエラーによるDDLタスクの実行に失敗しました。 原因: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] キー 'PRIMARY' のエントリ '10001' の複製) 次の方法を使用して、テーブルがローカル主キーを使用するときにローカル主キーの競合を回避できます。
AUTO_INCREMENT属性を使用して、PolarDB-Xが主キーを生成できるようにします。
主キーの値を手動で指定することはありません。
重要ローカル主キーを使用するテーブルにすでに重複主キーがある場合は、データをダウンストリームコンポーネントに同期するときに主キーの競合を回避する必要があります。 たとえば、DTSを使用してローカルのプライマリキーを使用するテーブルをAnalyticDB For MySQLに同期し、AnalyticDB for MySQLがPolarDB-Xテーブルのプライマリキーを使用する場合、プライマリキーの競合が発生する可能性があります。 この場合、AnalyticDB for MySQLのプライマリキーを、PolarDB-Xテーブルのプライマリキー列とパーティションキー列のフルセットに設定することを推奨します。
ユニークなキー
主キーと同様に、PolarDB-Xの一意キーには、グローバル一意キーとローカル一意キーが含まれます。
一意キーがグローバルに一意である場合、それはグローバル一意キーです。
一意キーがパーティション内で一意である場合、それはローカル一意キーです。
共通テーブルとブロードキャストテーブル
共通テーブルまたはブロードキャストテーブル内の一意キーは、グローバルに一意であるため、グローバル一意キーです。
例7: 共通テーブルとブロードキャストテーブルのグローバル一意キー
## 共通テーブル
CREATE TABLE single_tbl (
serial_id bigint、
名前varchar(30) 、
UNIQUEキー (serial_id)
) シングル;
## 放送テーブル
テーブルの作成brd_tbl (
serial_id bigint、
名前varchar(30) 、
UNIQUEキー (serial_id)
) 放送; パーティション分割されたテーブル
AUTOデータベースでは、テーブルの作成時にパーティションキーまたはパーティションアルゴリズムを指定しないと、自動パーティションテーブルが作成されます。 テーブルの作成時にパーティションキーまたはパーティションアルゴリズムを指定すると、手動パーティションテーブルが作成されます。
自動パーティションテーブル
自動パーティションテーブル内のすべての一意キーは、グローバルに一意であるため、グローバル一意キーです。
例8: 自動パーティションテーブルのグローバル一意キー
## 自動パーティションテーブル
CREATE TABLE auto_tbl (
serial_id bigint、
名前varchar(30) 、
UNIQUEキー (serial_id)
); 手動パーティションテーブル
グローバル一意キー
手動パーティションテーブルでは、一意キー列にすべてのパーティションキー列が含まれている場合、一意キーはグローバル一意であるため、グローバル一意キーになります。
例9: 手動パーティションテーブルのグローバル一意キー
hash_tblテーブルの一意のキー列は (inner_id, type_id) で、すべてのパーティションキー列 (type_id) が含まれます。 したがって、テーブルの一意キーは、グローバルに一意であるため、グローバル一意キーです。
テーブルの作成hash_tbl (
type_id int,
inner_id int,
UNIQUE KEY(inner_id, type_id)
) HASHによるパーティー (type_id); 例10: 手動パーティションテーブル内の一意のグローバルインデックスで構成されるグローバル一意キー
手動パーティションテーブルでは、グローバルに一意であるため、グローバルセカンダリインデックスもグローバルに一意のキーです。 key_tblテーブルには、seriale_idインデックス列の一意のグローバルインデックスが含まれます。 serial_idインデックス列がグローバルに一意であることを保証するため、グローバルに一意のキーです。
テーブルの作成key_tbl (
type_id int,
serial_id int,
UNIQUEグローバルインデックスu_sid(serial_id) PARTITION BY HASH(serial_id)
) HASHによるパーティー (type_id); ローカル一意キー
例11: 手動パーティションテーブルのローカル一意キー
手動パーティションテーブルでは、一意のキー列にすべてのパーティションキー列が含まれていない場合、一意のキーはローカルの一意のキーです。
range_tblテーブルの一意のキー列はserial_idで、パーティションキー列order_timeは含まれません。 したがって、パーティション内でのみ一意であり、グローバルに一意ではないため、ローカル一意キーです。
テーブルの作成range_tbl (
id int primary key auto_increment,
serial_id int,
order_time datetime NOT NULL,
UNIQUEキー (serial_id)
) レンジによるパーティー (order_time)
(
パートp1はより少ない値 ('2022-12-31 ') 、
パートp2はより少ない値 ('2023-12-31 ') 、
PARTITION p3の値がより少ない (最大値)
); 例12: ローカル一意キーがグローバル一意ではない
ローカル一意キーはパーティション内でのみ一意ですが、グローバルに一意ではありません。 したがって、重複する一意のキーが発生する可能性があります。
ここでは、例11のrange_tblテーブルを使用します。 range_tblテーブルに行を挿入します。 ステートメントが実行されると、データはp1パーティションに格納されます。
INSERT INTO range_tbl(serial_id, order_time) VALUES (20001, '2022-01-01 '); クエリOK、1行が影響serial_id値が前の行と同じで、order_time値が2022-01-02である行をrange_tblテーブルに挿入します。order_time値は、行がまだp1パーティションに格納されることが予想されることを示します。 ステートメントが実行されると、行を挿入できず、一意のキー競合のエラーが報告されます。 同じ一意のキー値の行を同じパーティションに格納することはできません。 これは、ローカル一意キーがパーティション内でのみ一意であることを示します。INSERT INTO info_tbl(serial_id, order_time) VALUES (20001, '2022-01-02 '); (1062、"ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] GROUP 'D25_000001_GROUP 'ATOM 'dskey_d25_000001_group#polardbx-storage-1-master#11.167.60.147-1766#d25_000001': 重複エントリ '20001' for key 'serial_id'")serial_id値が前の行と同じで、order_time値が2023-01-01の行をrange_tblテーブルに挿入します。order_time値は、その行がp3パーティションに格納されることが予想されることを示す。 ステートメントが実行されます。 range_tblテーブルには、同じ一意キーを持つ2行が存在します。 これは、ローカル一意キーがグローバルに一意ではないことを示します。INSERT INTO range_tbl(serial_id, order_time) VALUES (20001, '2024-01-01 '); クエリOK、影響を受ける1行 SELECT * からrange_tbl; + ---- ----------- + --------------------- + | id | serial_id | order_time | + ---- ----------- + --------------------- + | 2 | 20001 | 2024-01-01 00:00:00 | | 1 | 20001 | 2022-01-01 00:00:00 | + ---- ----------- + --------------------- + 2行のセット
例13: 重複する一意のキーを持つテーブルに対してDDLステートメントを実行すると、一意のキー競合のエラーが報告される可能性があります。
テーブルで重複するローカル一意キーが使用される可能性があるため、パーティション分割ポリシーの変更やテーブルの下流コンポーネントへの同期など、テーブルでのデータ再配布に関連する操作を実行すると、一意キーの競合のエラーが報告される可能性があります。
ここでは、例12のrange_tblテーブルを使用します。 テーブルには、同じserial_id値を持つ2つの行が既にあります。 一方の行はp1パーティションに格納され、他方の行はp2パーティションに格納される。 次のDDLステートメントを実行して、range_tblテーブルを手動パーティションテーブルから共通テーブルに変更します。 これにより、range_tblテーブルのデータ再配布がトリガーされます。
ALTER TABLE range_tblシングル;
(4700、"ERR-CODE: [TDDL-4700][ERR_SERVER] サーバエラーによるDDLタスクの実行に失敗しました。 原因: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] キー 'PRIMARY' "のエントリ '200001' の複製) DDLステートメントが失敗し、一意のキー競合のエラーが報告されます。 これは、このDDLステートメントがrange_tblテーブルを、重複する一意のキーを含む共通テーブルに変更しようとするためです。これは、一意のキーが共通テーブル内で一意でなければならないという規則に違反します。
テーブルがローカル一意キーを使用する場合のローカル一意キーの競合を回避するには、ローカル一意キーが重複しないようにする必要があります。
ローカル一意キーを使用するテーブルに既に重複する一意キーがある場合は、データをダウンストリームコンポーネントに同期するときに一意キーの競合を回避するために、ソースデータを手動で変更することをお勧めします。
FAQ
グローバル主キーまたはグローバル一意キーの作成に使用される別のステートメントはですか。
いいえ。 同じMySQLステートメントを使用して、主キーまたは一意のキーを作成できます。 作成する主キーまたは一意キーが、グローバル主キーまたはグローバル一意キーの要件を満たしていることを確認します。
テーブルでは現在、ローカルの主キーが使用されています。 ローカル主キーがグローバルに一意であることを確認するにはどうすればよいですか。
シーケンス機能を使用して、グローバルに一意な主キーを生成できます。 詳細については、「シーケンス」をご参照ください。