6
我有一個事務表,其中幾行可以存儲三個屬性(foo_id,bar_id),最後一個屬性是deleted_at,這裏的想法是確保我只有一個活動行一次(deleted_at ='0000-00-00 00:00:00')。MySQL - 具有日期時間的複合唯一鍵
但我收到以下錯誤:
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'
這裏是架構:
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
立即站出來的唯一的事情是MySQL可能沒有考慮的時間部分日期時間值,因此抱怨18-1-2015-08-08
的另一行。
任何想法如何保持多行靈活性,同時能夠強制在任何給定時間只有一行是「活動的」?
不'(foo_id = '1' AND IN bar_id( '18'))'完全匹配_一行?如果它實際上匹配多個,則新值NOW()會導致違反密鑰約束。如果有多於一個,但是你想選擇一個具有LIMIT(這將避免違反唯一性)的條件,那麼你會根據什麼標準對它們進行排序? –
不,可能有X行的foo_id = 1,bar_id = 18,它們之間的唯一差異將是deleted_at值,只有其中一個具有deleted_at ='0000-00-00 00:00:00 ' –
@MikePurcell如果你有很多行,foo_id = 1和bar_id = 18,你的update語句要求所有這些行都用deleted_at = NOW()更新,因此導致非唯一性。你能改變你的where子句來使用'和deleted_at ='0000-00-00 00:00:00''嗎? – zedfoxus