#mysql #sql
#mysql #sql
Вопрос:
Когда я создаю таблицу (A), я хочу добавить ограничение, которое не позволит добавлять более 3 раз одно и то же значение в один и тот же столбец.
Я думал, что сделаю еще один столбец (КОЛИЧЕСТВО), чтобы пользователь должен был подсчитать, сколько раз они давали значение, и вставить его в новый столбец, а затем использовать это ограничение :
ALTER TABLE A
ADD CONSTRAINT A check(COUNT<=3);
Но это потребует слишком многого от пользователя, и, вероятно, произойдет сбой .
Есть ли самый простой способ сделать это, который не зависит от пользователя?
Комментарии:
1. Для этого вам нужно будет написать триггеры.
Ответ №1:
Вот три варианта:
(1) Используйте триггер для подсчета количества значений в столбце. Это будет триггер insert
/ update
, который будет уверен, что 4-е значение не будет добавлено.
(2) Создайте определяемую пользователем функцию, которая подсчитывает количество значений в столбце, и добавьте check
ограничение, чтобы убедиться, что значение равно 3 или меньше. В настоящее время это не разрешено в MySQL, но однажды это может быть.
(3) Добавьте counter
столбец в родительскую таблицу, а затем добавьте check
ограничение, чтобы гарантировать, что счетчик никогда не будет больше 3. Это также требует insert
/ update
/ delete
триггеров для поддержания актуальности подсчета.
В общем, я думаю, что я предпочитаю (3), потому что часто удобно иметь счетчик в родительской таблице. И хотя он использует триггеры, логика сбоя понятна — она не скрыта в триггере, она находится в контрольном ограничении.
Я должен предложить четвертый вариант. Это означает предварительное заполнение таблицы тремя строками для каждого пользователя. Тогда разрешайте пользователям обновлять строки только вместо insert
/ delete
. Для этого требуется флаг, указывающий, имеет ли строка значение.
Комментарии:
1. В MySQL ни пользовательская функция, ни подзапрос не разрешены в CHECK — so (1) является единственным вариантом.
2. @Akina . . . Ни один из параметров не ссылается на подзапрос в
CHECK
ограничении. Третий вариант поддерживает актуальность данных с помощью триггеров.3. Вы имеете в виду, что триггер находится в дочернем, тогда как ПРОВЕРКА в родительском? Я просто не сразу понял это.
4. @Akina . . . Да, это последний вариант, который я предпочитаю, потому что фактическая проверка не выполняется в триггере. Триггер предназначен только для поддержания количества. (Я не поклонник скрытой логики.)