MySQL-如何在通过RANGE(时间戳)进行分区时保持唯一约束?

时间:2019-07-03 12:14:16

标签: mysql partitioning database-partitioning

我有一张表,想要按RANGE(在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)
);

此表仅具有两种用法:按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在此表中唯一?

我曾考虑过按order_id进行分区,但是很难以这种方式删除旧数据。

任何建议都值得欢迎。 (例如,您可能对此表有更好的设计)。

1 个答案:

答案 0 :(得分:2)

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。这样可以使所有陈述的操作稍微快一些。