Одним из решений является создание пустого столбца is_active
, который ограничен значением NULL или одним значением, отличным от NULL.Столбцы code
и is_active
вместе должны быть уникальными.
CREATE TABLE `employees` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`code` varchar(4) NOT NULL,
`is_active` enum('yes'),
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`code`, `is_active`)
);
Если is_active
равно NULL, то в столбце code
допускается любое количество дубликатов.Если is_active
не равно NULL, тогда допускается только одно значение «да», и поэтому каждое значение в столбце code
должно быть уникальным.
deleted_at
больше не указывает, является ли данный сотрудник активным в данный момент илинет, только , когда тогда были инактивированы.
Ваш комментарий:
Ограничения, охватывающие несколько таблиц, называются ASSERTIONS
в стандарте SQL, нобуквально не является продуктом СУБД, который реализует эту функцию из стандарта.
Некоторые реализуют ограничения с помощью триггеров, но не всегда очевидно, как спроектировать триггеры, чтобы делать то, что вы хотите эффективно.
Честно говоря, большинстволюди прибегают к логике приложения для такого рода ограничений.Это идет с некоторым риском условий гонки.Как только вы выполните инструкцию SELECT, чтобы проверить, что данные удовлетворяют ограничениям, какой-то другой параллельный сеанс может зафиксировать данные, которые портят ограничение, прежде чем ваш сеанс сможет зафиксировать его изменения.
Единственное решение - использовать пессимистическую блокировку дляубедитесь, что никакая другая сессия не может опередить вас.