I have a transaction table where several rows may be stored against three attributes (foo_id, bar_id), and the last attribute is deleted_at, the thought here is to ensure that I only have one active row at a time (deleted_at = '0000-00-00 00:00:00').
But I am getting the following error:
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'
Here is the schema:
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
The only thing that immediately stands out is that MySQL may not be considering the time portion of the datetime value, and therefore complaining about another row with 18-1-2015-08-08
.
Any ideas how I can maintain the multiple row flexibility while being able to enforce that only one row is 'active' at any given time?
To form a composite key to be unique, you need to use ADD UNIQUE command. Following is the syntax − alter table yourTableName add unique yourUniqueName ( yourColumnName1,yourColumnName2,.......N); Let us first create a table. Following is the query − Now check the description of the table using DESC command. Following is the query −
Every table should have a PRIMARY KEY. In MySQL this implies two things: a UNIQUEness constraint, and an index. Any kind of index can be "composite" ("compound"), that is be composed of more than one column. It is rarely useful to have two UNIQUE keys in a single table. (Remember: PRIMARY counts as UNIQUE.
In MySQL this implies two things: a UNIQUEness constraint, and an index. Any kind of index can be "composite" ("compound"), that is be composed of more than one column. It is rarely useful to have two UNIQUE keys in a single table.
If you already have a unique key (a), it is unreasonable and unnecessary to have also have UNIQUE (a,b) or UNIQUE (b,a). On the other hand, it may be useful to have a non-unique INDEX (a,b) and/or INDEX (b,a).
Changing from a comment to an answer...
The statement:
UPDATE epic_table SET deleted_at = NOW()
WHERE (foo_id = '1' AND bar_id IN ('18'));
attempts to set deleted_at
for all rows with foo_id = 1
and bar_id = 18
. Since foo_id, bar_id and deleted_at combination is marked as unique, such change ends up violating the unique constraint.
Only a slight change may be needed to the statement like so, knowing that only one record may have 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');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With