我有这张桌子:
CREATE TABLE `executed_tests` (
`id` INTEGER AUTO_INCREMENT NOT NULL,
`user_id` INTEGER NOT NULL,
`test_id` INTEGER NOT NULL,
`start_date` DATE NOT NULL,
`completed_date` DATE,
PRIMARY KEY (`id`)
);
我想对字段user_id
和test_id
设置唯一约束,但仅当conclusion_date
为空时。如果conclusion_date
不为null,则约束不适用。
因此,每个用户和测试只会存在一个不完整的执行。
类似这样的东西:
UNIQUE(`user_id`, `test_id`) WHEN (`completed_date` IS NULL)
如何在MySQL 5.6上完成此操作?
答案 0 :(得分:1)
MySQL从 8.0.13 开始支持functional key parts。
如果您的版本足够新,则可以将索引定义为:
UNIQUE(`user_id`, `test_id`, (IFNULL(`completed_date`, -1)))
请注意,以上索引还将防止重复执行完成的日期。如果这些参数有效,那么略微修改的索引将起作用:
UNIQUE(`user_id`, `test_id`, (
CASE WHEN `completed_date` IS NOT NULL
THEN NULL
ELSE 0
END))
尽管那样会开始有点脏;)
如果您的版本至少为 5.7 ,则可以使用(虚拟)generated column作为解决方法:
CREATE TABLE `executed_tests` (
`id` INTEGER AUTO_INCREMENT NOT NULL,
`user_id` INTEGER NOT NULL,
`test_id` INTEGER NOT NULL,
`start_date` DATE NOT NULL,
`completed_date` DATE,
`_helper` CHAR(11) AS (IFNULL(`completed_date`, -1)),
PRIMARY KEY (`id`),
UNIQUE(`user_id`, `test_id`, `_helper`)
);
如果您被困在 5.6 上,则可以使用常规(非虚拟)列和稍作修改的INSERT
语句的组合:
CREATE TABLE `executed_tests` (
`id` INTEGER AUTO_INCREMENT NOT NULL,
`user_id` INTEGER NOT NULL,
`test_id` INTEGER NOT NULL,
`start_date` DATE NOT NULL,
`completed_date` DATE,
`is_open` BOOLEAN,
PRIMARY KEY (`id`),
UNIQUE(`user_id`, `test_id`, `is_open`)
);
在这种情况下,您可以将is_open
设置为true
来执行不完整的操作,将完成后的NULL
设置为NULL
,这是因为将两个li $v0, 4
la $a0, msg1
syscall
li $v0, 6
syscall
s.s $f0, $f1
li $v0, 4
la $a0, msg2
syscall
li $v0, 6
syscall
s.s $f0, $f2
li $v0, 2
div.s $f12, num1, num2
syscall
视为不执行相等。