Mysql - 如何在按范围(时间戳)分区时保持唯一约束?
Mysql - how to keep unique constraint while partitioning by RANGE (timestamp)?
我有一个 table,想按范围分区(created_at 时间戳),这样可以轻松删除旧数据(通过删除分区)。
CREATE TABLE `orders` (
`order_id` NVARCHAR(64) NOT NULL,
`amount` INTEGER NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`modified_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE dropship.orders
PARTITION BY RANGE (UNIX_TIMESTAMP(created_at)) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-03-01 00:00:00') ),
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-04-01 00:00:00') ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-05-01 00:00:00') ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-06-01 00:00:00') ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-07-01 00:00:00') ),
PARTITION p5 VALUES LESS THAN (MAXVALUE)
);
这个table只有两种用法:通过order_id获取,或者通过order_id更新。
select * from orders where order_id = '123';
update orders set amount = 10 where order_id = '123';
由于 Mysql 分区的限制,我无法为 order_id 添加唯一键,因为将使用 created_at 字段进行分区。
All columns used in the table's partitioning expression must be part of every unique key that the table may have, including any primary key.
问题:
有什么方法可以使 order_id 在 table 中独一无二?
我考虑过按order_id分区,但是这样很难删除旧数据。
欢迎任何建议。 (例如,您可能对此有更好的设计 table)。
BEGIN;
SELECT 1 FROM orders WHERE order_id = 234 FOR UPDATE;
if row exists, you have a dup error.
INSERT INTO orders ... order_id = 234;
COMMIT;
但是,正如 Raymond 指出的那样,您也可以删除 PARTITIONing
并将该列设为 PRIMARY KEY
。这将使所有规定的操作稍微更快。
我有一个 table,想按范围分区(created_at 时间戳),这样可以轻松删除旧数据(通过删除分区)。
CREATE TABLE `orders` (
`order_id` NVARCHAR(64) NOT NULL,
`amount` INTEGER NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`modified_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE dropship.orders
PARTITION BY RANGE (UNIX_TIMESTAMP(created_at)) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-03-01 00:00:00') ),
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-04-01 00:00:00') ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-05-01 00:00:00') ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-06-01 00:00:00') ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-07-01 00:00:00') ),
PARTITION p5 VALUES LESS THAN (MAXVALUE)
);
这个table只有两种用法:通过order_id获取,或者通过order_id更新。
select * from orders where order_id = '123';
update orders set amount = 10 where order_id = '123';
由于 Mysql 分区的限制,我无法为 order_id 添加唯一键,因为将使用 created_at 字段进行分区。
All columns used in the table's partitioning expression must be part of every unique key that the table may have, including any primary key.
问题:
有什么方法可以使 order_id 在 table 中独一无二?
我考虑过按order_id分区,但是这样很难删除旧数据。
欢迎任何建议。 (例如,您可能对此有更好的设计 table)。
BEGIN;
SELECT 1 FROM orders WHERE order_id = 234 FOR UPDATE;
if row exists, you have a dup error.
INSERT INTO orders ... order_id = 234;
COMMIT;
但是,正如 Raymond 指出的那样,您也可以删除 PARTITIONing
并将该列设为 PRIMARY KEY
。这将使所有规定的操作稍微更快。