Mam tabelę transakcji, w której można przechowywać kilka wierszy w odniesieniu do trzech atrybutów (foo_id, bar_id), a ostatni atrybut jest usunięty, myślę tutaj, aby upewnić się, że mam tylko jeden aktywny wiersz naraz (deleted_at = '0000-00-00 00:00:00').MySQL - unikalny klucz złożony z datetime
Ale ja otrzymuję następujący błąd:
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'
Oto schemat:
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
Jedyną rzeczą, która natychmiast wyróżnia to, że MySQL nie może być brane pod uwagę część porze wartość datetime, a zatem narzekanie na inny wiersz z 18-1-2015-08-08
.
Jakieś pomysły, w jaki sposób mogę utrzymać elastyczność w wielu wierszach, jednocześnie będąc w stanie wyegzekwować, że tylko jeden wiersz jest "aktywny" w danym momencie?
Does '(foo_id = '1' AND bar_id IN ('18'))' dopasować dokładnie _one_ wiersz? Jeśli faktycznie pasuje do więcej niż jednego, nowa wartość 'NOW()' spowoduje naruszenie ograniczenia klucza. Jeśli jest więcej niż jeden, ale chcesz wybrać tylko jeden z 'LIMIT' (który uniknie naruszenia unikalności), na jakie inne kryteria byś je posortował? –
Nie, może być X liczba wierszy z foo_id = 1, bar_id = 18, jedyną różnicą między nimi byłaby wartość deleted_at, przy czym tylko jeden z wielu miałby usunięty_at = '0000-00-00 00:00:00 " –
@MikePurcell, jeśli masz wiele wierszy z foo_id = 1 i bar_id = 18, instrukcja aktualizacji prosi wszystkie wiersze, aby zostały zaktualizowane za pomocą metody deleted_at = NOW(), a tym samym powodując nieunikalność. Czy mógłbyś zmienić klauzulę where, aby użyć 'and deleted_at = '0000-00-00 00: 00: 00''? – zedfoxus