日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

主鍵與唯一鍵(DRDS模式)

本節(jié)介紹了在DRDS模式數(shù)據(jù)庫中,判斷表的主鍵是Global主鍵還是Local主鍵,表的唯一鍵是Global唯一鍵還是Local唯一鍵的方法。

主鍵

PolarDB-X中,主鍵分為Global主鍵與Local主鍵。區(qū)別如下:

  • 能保證全局唯一,就稱為Global主鍵;

  • 只保證分表內(nèi)唯一,則稱為Local主鍵。

單表和廣播表

單表和廣播表中的主鍵都是Global主鍵,能保證全局唯一。

示例1:單表和廣播表中的Global主鍵

## 單表
CREATE TABLE single_tbl(
 id bigint NOT NULL AUTO_INCREMENT, 
 name varchar(30), 
 PRIMARY KEY(id)
);

## 廣播表
CREATE TABLE brd_tbl(
 id bigint NOT NULL AUTO_INCREMENT, 
 name varchar(30), 
 PRIMARY KEY(id)
) BROADCAST;

分庫分表

Global主鍵

在分庫分表中,如果主鍵列包含了所有拆分鍵,該主鍵就是Global主鍵,能保證全局唯一。

示例2:分庫分表中的Global主鍵

表user_tbl中,分庫的拆分鍵為id,分表的拆分鍵為name,主鍵列(id, name, addr)包含了所有拆分鍵,所以該表的主鍵是Global主鍵,能保證全局唯一。

CREATE TABLE user_tbl(
 id bigint,
 name varchar(10),
 addr varchar(30),
 PRIMARY KEY(id, name, addr)
) DBPARTITION BY HASH(id) TBPARTITION BY HASH(name) TBPARTITIONS 4;

Local主鍵

在分庫分表中,如果主鍵列未包含全部拆分鍵,該主鍵就是Local主鍵。

示例3:分庫分表中的Local主鍵

表order_tbl的主鍵列是order_id,主鍵列未包含分庫的拆分鍵city,因此該表的主鍵是Local主鍵,只能保證分表內(nèi)唯一,無法保證全局唯一。

CREATE TABLE order_tbl(
 order_id bigint,
 city varchar(50),
 name text,
 PRIMARY KEY(order_id)
) DBPARTITION BY HASH(city);

示例4:Local主鍵無法保證全局唯一

由于Local主鍵只能保證分表內(nèi)部唯一,不保證全局唯一,因此可能出現(xiàn)主鍵重復的情況。沿用示例3中的order_tbl表,該表使用city作為分庫拆分鍵,且只分庫不分表,因此每個分庫都只有1張分表。

  1. 向order_tbl插入一條數(shù)據(jù),執(zhí)行成功。

    INSERT INTO order_tbl(order_id, city, name) VALUES (10001, "Beijing", "phone");
    Query OK, 1 row affected
  2. 向order_tbl表插入一條order_id相同且city相同的數(shù)據(jù)。由于city相同,數(shù)據(jù)仍將被存儲到和第一次插入的數(shù)據(jù)相同的分表。執(zhí)行SQL發(fā)現(xiàn)插入失敗,報主鍵沖突的錯誤??梢钥吹较嗤麈I的值無法插入到相同分表,這說明Local主鍵可以保證在分表內(nèi)部唯一。

    INSERT INTO order_tbl(order_id, city, name) VALUES (10001, "Beijing", "book");
    (1062, "ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'D25_000002_GROUP' ATOM 'dskey_d25_000002_group#polardbx-storage-0-master#11.167.60.147-1766#d25_000002': Duplicate entry '10001' for key 'PRIMARY' ")
  3. 向order_tbl表插入一條order_id相同但city不同的數(shù)據(jù),因為city的值為“Shenzhen”,由于這次city的值不同于第一次插入的數(shù)據(jù),這次的數(shù)據(jù)將被插入到不同的分表。

    執(zhí)行SQL,發(fā)現(xiàn)執(zhí)行成功。此時order_tbl表內(nèi)存在兩行主鍵重復的數(shù)據(jù),這說明Local主鍵無法保證全局唯一。

    INSERT INTO order_tbl (order_id, city, name) VALUES (10001, "Shenzhen", "camera");
    Query OK, 1 row affected
    
    SELECT * FROM order_tbl;
    +----------+----------+--------+
    | order_id | city | name |
    +----------+----------+--------+
    | 10001 | Beijing | phone |
    | 10001 | Shenzhen | camera |
    +----------+----------+--------+
    2 rows in set

示例5:在含有重復主鍵的表上執(zhí)行DDL,可能出現(xiàn)主鍵沖突報錯

使用Local主鍵的表內(nèi)可能存在重復的主鍵值,當在該表上執(zhí)行數(shù)據(jù)重分布相關的操作時(如執(zhí)行變更表類型的DDL、將表同步至下游),可能會出現(xiàn)主鍵沖突的錯誤。

表order_tbl已經(jīng)存在兩行主鍵相同的數(shù)據(jù),它們分別存儲在不同的分表內(nèi)。執(zhí)行變更表類型的DDL,通過把分庫分表變成單表,使得city為“Beijing”和“Shenzhen”的數(shù)據(jù)存儲在一起。

ALTER TABLE order_tbl SINGLE;
(4700, '[17399c0a2fc00000][30.221.117.14:8527][d25]ERR-CODE: [TDDL-4700][ERR_SERVER] server error by The DDL job has been rollback. Please check the ddl stmt. jobId: 1673540305653071872 ')

DDL執(zhí)行失敗。這是因為在將分庫分表轉(zhuǎn)為單表時,主鍵重復的數(shù)據(jù)同時出現(xiàn)在新的單表中,違反了單表中的主鍵唯一性。

對于使用Local主鍵的表,為避免主鍵值重復引發(fā)的主鍵沖突,建議:

  • 使用auto_increment屬性,由PolarDB-X生成主鍵值;

  • 同時,避免業(yè)務側(cè)手動寫入指定的主鍵值。

    重要

    對于使用Local主鍵的表,如果已經(jīng)存在主鍵重復的情況,往下游同步數(shù)據(jù)的時候需避免下游出現(xiàn)主鍵沖突。例如將含Local主鍵的表通過DTS向云原生數(shù)據(jù)倉庫AnalyticDB MySQL版進行同步時,如果云原生數(shù)據(jù)倉庫AnalyticDB MySQL版的主鍵沿用PolarDB-X的主鍵,就可能出現(xiàn)沖突,此時建議將云原生數(shù)據(jù)倉庫AnalyticDB MySQL版的主鍵設為PolarDB-X端表的主鍵列和所有拆分鍵的集合。

唯一鍵

與主鍵類似,在PolarDB-X中,唯一鍵分為Global唯一鍵與Local唯一鍵。當創(chuàng)建出的唯一鍵:

  • 能保證全局唯一,就稱為Global唯一鍵;

  • 只保證分表內(nèi)唯一,則稱為Local唯一鍵。

本節(jié)將介紹在不同場景下,如何判斷表的唯一鍵是Global唯一鍵還是Local唯一鍵。

單表和廣播表

單表和廣播表中的唯一鍵都是Global唯一鍵,能保證全局唯一。

示例6:單表和廣播表中的Global唯一鍵

## 單表
CREATE TABLE single_tbl(
 serial_id bigint,
 name varchar(30), 
 UNIQUE KEY(serial_id)
);

## 廣播表
CREATE TABLE brd_tbl(
 serial_id bigint,
 name varchar(30), 
 	UNIQUE KEY(serial_id)
) BROADCAST;

分庫分表

Global唯一鍵

在分庫分表中,如果唯一鍵列包含了全部拆分鍵,該唯一鍵就是Global唯一鍵,能保證全局唯一。

示例7:分庫分表中的Global唯一鍵

表type_tbl的唯一鍵列是(inner_id, type_id),包含了所有的拆分鍵type_id,所以該表的唯一鍵是Global唯一鍵。

CREATE TABLE type_tbl(
 type_id int,
 inner_id int,
 UNIQUE KEY(inner_id, type_id)
) DBPARTITION BY HASH(type_id);

在分庫分表中,全局二級索引也是一個Global唯一鍵,能保證全局唯一。

示例8:分庫分表表中由UNIQUE GLOBAL INDEX構(gòu)成的全局唯一鍵

表type_tbl2包含一個索引列為serial_id的UNIQUE GLOBAL INDEX,它能保證serial_id的全局唯一性,因此是Global唯一鍵。

CREATE TABLE type_tbl2(
 type_id int,
 serial_id int,
 UNIQUE GLOBAL INDEX u_sid(serial_id) DBPARTITION BY HASH(serial_id)
) DBPARTITION BY HASH(type_id);

Local唯一鍵

在分庫分表中,如果唯一鍵列未包含全部拆分鍵,該唯一鍵就是Local唯一鍵。

示例9:分庫分表中的Local唯一鍵

表info_tbl的唯一鍵列是serial_id,未包含拆分鍵order_time,所以該表的唯一鍵是Local唯一鍵,只能保證分表內(nèi)唯一,無法保證全局唯一。

CREATE TABLE info_tbl(
 id int primary key auto_increment,
 serial_id int,
 	order_time date NOT NULL,
 UNIQUE KEY(serial_id)
) DBPARTITION BY YYYYMM(order_time);

示例10:Local唯一鍵無法保證全局唯一

與Local主鍵類似,由于Local唯一鍵不保證全局唯一,因此可能出現(xiàn)唯一鍵重復的情況。

沿用示例9中的info_tbl表,該表使用order_time作為分庫拆分鍵,且只分庫不分表,因此每個分庫中只有1個分表。

  1. 向info_tbl插入一條數(shù)據(jù),執(zhí)行成功。

    INSERT INTO info_tbl(serial_id, order_time) VALUES (20001, '2022-01-01');
    Query OK, 1 row affected
  2. 向info_tbl表插入一條serial_id相同,且order_time為“2022-01-02”的數(shù)據(jù)。order_time的年月值與第一次插入的相同,因此數(shù)據(jù)將被存儲到與第一次插入的數(shù)據(jù)一樣的分表,執(zhí)行SQL發(fā)現(xiàn)插入失敗,報唯一鍵沖突的錯誤。相同唯一鍵的值無法插入到相同的分表,這說明Local唯一鍵可以保證在分表內(nèi)部唯一。

    INSERT INTO info_tbl(serial_id, order_time) VALUES (20001, '2022-01-02');
    (1062, "ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'D25_000001_GROUP' ATOM 'dskey_d25_000001_group#polardbx-storage-1-master#11.167.60.147-1766#d25_000001': Duplicate entry '20001' for key 'serial_id' ")
  3. 向info_tbl表插入一條serial_id相同,且order_time為“2023-03-01”的數(shù)據(jù)。order_time的值決定了數(shù)據(jù)將被存儲到和第一次插入數(shù)據(jù)不同的分表,執(zhí)行成功。此時serial_id表中存在兩行唯一鍵重復的數(shù)據(jù),這說明Local唯一鍵無法保證全局唯一。

    INSERT INTO info_tbl(serial_id, order_time) VALUES (20001, '2023-03-01');
    Query OK, 1 row affected
    
    SELECT * FROM info_tbl;
    +--------+-----------+------------+
    | id | serial_id | order_time |
    +--------+-----------+------------+
    | 100006 | 20001 | 2023-03-01 |
    | 100001 | 20001 | 2022-01-01 |
    +--------+-----------+------------+

示例11:在含有重復唯一鍵的表上執(zhí)行DDL,可能會出現(xiàn)唯一鍵沖突報錯

與Local主鍵類似,用到Local唯一鍵的表內(nèi)可能存在重復的唯一鍵值,當在該表上執(zhí)行數(shù)據(jù)重分布相關的操作時(如執(zhí)行變更表類型的DDL、將表同步至下游),可能會出現(xiàn)唯一鍵沖突的錯誤。

表info_tbl已經(jīng)存在兩行serial_id相同的數(shù)據(jù),它們分別存儲在不同的分表內(nèi)。嘗試執(zhí)行變更表類型的DDL,使info_tbl表從分庫分表變成單表,這將引發(fā)info_tbl表內(nèi)的數(shù)據(jù)重分布。

ALTER TABLE info_tbl SINGLE;
(4700, "ERR-CODE: [TDDL-4700][ERR_SERVER] server error by Failed to execute the DDL task. Caused by: ERR-CODE: [TDDL-5321][ERR_GLOBAL_SECONDARY_INDEX_BACKFILL_DUPLICATE_ENTRY] Duplicated entry '20001' for key 'PRIMARY' ")

DDL執(zhí)行失敗,報了關于唯一鍵沖突的錯誤。這是因為DDL在把info_tbl轉(zhuǎn)換為單表時,在單表內(nèi)出現(xiàn)了重復的唯一鍵值,違反了單表內(nèi)唯一鍵的唯一性。

對于使用Local唯一鍵的表,為避免唯一鍵值重復引發(fā)的唯一鍵沖突,應該由業(yè)務側(cè)采取措施確保唯一鍵值的唯一性。

重要

對于使用Local唯一鍵的表,如果已經(jīng)存在唯一鍵值重復的情況,當往下游同步數(shù)據(jù)時出現(xiàn)唯一鍵沖突時,建議人工訂正源端數(shù)據(jù)。

常見問題

  • Q:創(chuàng)建Global主鍵、Global唯一鍵有特殊的語法嗎?

    A:沒有,使用與MySQL一樣的語法創(chuàng)建主鍵、唯一鍵即可。請注意創(chuàng)建的主鍵、唯一鍵需要滿足上文中關于Global主鍵、Global唯一鍵的定義。

  • Q:目前使用的主鍵是Local主鍵,但我想保證主鍵全局唯一,該怎么做?

    A:請參見Sequence生成唯一值作為主鍵值,可保證主鍵全局唯一。