ограничение значения, которое должно повторяться до 3 раз в одном и том же столбце в MySQL

#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 . . . Да, это последний вариант, который я предпочитаю, потому что фактическая проверка не выполняется в триггере. Триггер предназначен только для поддержания количества. (Я не поклонник скрытой логики.)