如何使用auto_increment主键对MySQL表进行分区

6ojccjat  于 2022-11-28  发布在  Mysql
关注(0)|答案(3)|浏览(207)

这是我的table
| A列|B栏|C列|D栏|
| - -|- -|- -|- -|
| 单元格1|单元2|单元格1|单元2|
| 单元3|单元4|单元3|单元4|
其中,列A是主键,列D是TINYINT列。列D仅包含0到3之间的值。(0,1,2,3)我要根据列D对此表进行分区。
我尝试用这段代码对表进行分区。
ALTER TABLE to_be_partitioned PARTITION BY HASH(Column D) PARTITIONS 4;
它指出PRIMARY KEY必须包括表的分区函数中的所有列
请问如何根据D列的值对此表进行分区???
我尝试使用KEY分区类型,它也给出了一个错误。
我就知道会发生这样的事。
P0包含列D值为0的所有记录
P1包含列D值为1的所有记录
P2包含列D值为2的所有记录
P3包含列D值为3的所有记录

ymdaylpp

ymdaylpp1#

演示
使用附加表和触发器提供的PK进行分区。
必须分区的表-无PK。

CREATE TABLE main (
  colA INT NOT NULL,  -- should be AI PK
  colB INT,
  colC TINYINT CHECK (colC BETWEEN 0 AND 3)
)
  PARTITION BY LIST (colC) (
  PARTITION zero VALUES IN (0),
  PARTITION one VALUES IN (1),
  PARTITION two VALUES IN (2),
  PARTITION three VALUES IN (3)
);

将用于AI PK生成的附加表格。

CREATE TABLE main_ai_pk (
  colA INT AUTO_INCREMENT PRIMARY KEY
);

将生成AI PK的触发器。如果为colA提供了显式值,则将覆盖该值。

CREATE TRIGGER tr_bi_main_set_pk
BEFORE INSERT ON main
FOR EACH ROW
BEGIN
  INSERT INTO main_ai_pk VALUES (DEFAULT);        -- generate new AI value
  SET NEW.colA = LAST_INSERT_ID();                -- assign it to "PK" in main table
  DELETE FROM main_ai_pk WHERE colA < NEW.colA;   -- clear excess rows
END

某些插入。在第二次INSERT中,显式提供的colA的值被覆盖。

INSERT INTO main (colB, colC) VALUES (11,1), (22,2), (111,1);
INSERT INTO main VALUES (NULL,33,3), (3333,333,3);

查看最终数据状态。

SELECT * FROM main ORDER BY colA;
SELECT * FROM main_ai_pk;
SELECT PARTITION_NAME, TABLE_ROWS
  FROM INFORMATION_SCHEMA.PARTITIONS
  WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'main'
  ORDER BY PARTITION_ORDINAL_POSITION;

| 可乐|列B|结肠|
| - -|- -|- -|
| 一个|十一|一个|
| 2个|二十二个|2个|
| 三个|一一一|一个|
| 四个|三十三人|三个|
| 五个|三百三十三|三个|
| 可乐|
| - -|
| 五个|
| 分区名称|表格_行|
| - -|- -|
| 零点|第0页|
| 一个|2个|
| 两个|一个|
| 三个|2个|
fiddle

cs7cruho

cs7cruho2#

1.正如Akina所建议的,按LIST划分对本例是有意义的。
1.主键必须包含表分区函数中的所有列。主键必须是(Column A,Column D)或(Column D,Column A),否则将得到SQL Error [1503] [HY000]

create table to_be_partitioned (
    col_a   int,
    col_b   int,
    col_c   int,
    col_d   int,
    primary key (col_a, col_d))
partition by list (col_d) (
    partition p0 values in (0),
    partition p1 values in (1),
    partition p2 values in (2),
    partition p3 values in (3)
);

create table to_be_partitioned (
    col_a   int,
    col_b   int,
    col_c   int,
    col_d   int,
    primary key (col_d, col_a))
partition by list (col_d) (
    partition p0 values in (0),
    partition p1 values in (1),
    partition p2 values in (2),
    partition p3 values in (3)
);

编辑:
1.如果col_a是一个auto_increment列,则col_a本身已经是唯一的。因此(col_acol_d)也是唯一的。
1.如果分区的目的是均匀分布数据,则下面的DDL可能适用于您:
第一次

dgiusagp

dgiusagp3#

其他答案解释 * 如何 * 进行分区。我将解释 * 为什么您不需要 * 分区。
让我们看看会受益的SELECT

WHERE colc = ...
  AND cola = ...

在这种情况下,具有

INDEX(colc, cola)

很可能和任何PARTITION BY ...(colc)一样快或更快。

相关问题