我在MySQL中有一个表(需要用last_updated_date
进行分区)。但是我希望表的col1
中的值是唯一的(但是由于MySQL要求分区列包含在每个唯一键约束中,因此我不能仅在col1
上创建主键)。现在我有这个查询在表中插入一条记录
INSERT INTO TAB1 (col1, clo2, clo3) SELECT 'val1', 'val2', 'val3'
from dual WHERE NOT EXISTS (SELECT * from TAB1 where col1 = 'val1');
上述查询将确保在非并行插入的情况下col1的唯一性。但是,我想确认它是否也能确保col1
在2个连接并行插入时的唯一性,即上述查询线程是否安全?
注意:我使用的是InnoDB engine
。
答案 0 :(得分:2)
我认为对于你想做的事情有一个非常好的解决方案。将col1
作为第一个分区键,几乎会导致您按last_update_date
分区的原因。
一个kludge做范围分区有一些荒谬的宽范围,所以一切都在一个分区。您可以使用range columns
执行此操作。
partition by range columns (id, last_updated_date)
partition p0 values less than (9999999999, '2015-01-01'),
. . .
);
然后,您可以包含unique
约束。缺点是您需要与所有id
子句where
中的where id < 9999999999
进行比较。
另一种方法是使id
成为自动递增的ID。在这种情况下,您不必担心重复。
或者,在每个分区中使id
唯一,并在您的问题中使用查询。这不是100%肯定,但碰撞的条件是:
第二个需要分区切换,这是非常罕见的,因此碰撞的可能性非常低。
答案 1 :(得分:0)
设置:索引以col1
开头。 (制作UNIQUE
是没用的,因为您必须向其添加last_updated_date
。)
BEGIN;
SELECT 1 from TAB1 where col1 = 'val1' FOR UPDATE;
If you got 1, ROLLBACK and exit.
INSERT INTO TAB1 (col1, clo2, clo3) VALUES ('val1', 'val2', 'val3')
COMMIT;
另一方面说明......使用PARTITION会带来什么好处?