我有一个事务表,其中可以存储多个行对三个属性(foo_id,bar_id),最后一个属性是deleted_at,这里的想法是确保我一次只有一个活动行(deleted_at ='0000-00 -00 00:00:00').
但是我收到以下错误:
mysql> UPDATE epic_table SET deleted_at = NOW() WHERE (foo_id = '1' AND bar_id IN ('18'));
ERROR 1062 (23000): Duplicate entry '18-1-2015-08-08 16:35:46' for key 'epic_table_ibuk_1'
Run Code Online (Sandbox Code Playgroud)
这是架构:
CREATE TABLE `epic_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`foo_id` bigint(20) unsigned NOT NULL,
`bar_id` bigint(20) unsigned NOT NULL,
`created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `epic_table_ibuk_1` (`foo_id`,`bar_id`,`deleted_at`),
KEY `epic_table_ibfk_1` (`foo_id`),
KEY `epic_table_ibfk_2` (`bar_id`),
CONSTRAINT `epic_table_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`),
CONSTRAINT `epic_table_ibfk_2` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
唯一突出的是MySQL可能没有考虑日期时间值的时间部分,因此抱怨另一行18-1-2015-08-08.
任何想法如何保持多行灵活性,同时能够强制执行任何给定时间只有一行'活动'?
从评论改为答案......
该声明:
UPDATE epic_table SET deleted_at = NOW()
WHERE (foo_id = '1' AND bar_id IN ('18'));
Run Code Online (Sandbox Code Playgroud)
尝试deleted_at使用foo_id = 1和设置所有行bar_id = 18.由于foo_id,bar_id和deleted_at组合被标记为唯一,因此这种更改最终会违反唯一约束.
只知道只有一条记录可能有这样的声明,因此只需对声明进行微小的改动deleted_at = '0000-00-00 00:00:00':
UPDATE epic_table SET deleted_at = NOW()
WHERE (foo_id = '1' AND bar_id IN ('18') and deleted_at = '0000-00-00 00:00:00');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
641 次 |
| 最近记录: |