Как ограничить значение столбца в SQLite/MySQL

Я хотел бы ограничить значение столбца в таблице SQL. Например, значениями столбца могут быть только «автомобиль», «велосипед» или «фургон». Мой вопрос заключается в том, как вы достигаете этого в SQL, и стоит ли делать это на стороне БД, или я должен позволить приложению ограничивать ввод.

У меня также есть намерение добавить или удалить другие значения в будущем, например, «грузовик».

Я использую такие базы данных, как SQLite и MySQL.


person Maro    schedule 16.06.2011    source источник


Ответы (5)


Добавьте новую таблицу, содержащую эти транспортные средства, и сделайте свой столбец внешним ключом для этой таблицы. В будущем в таблицу могут быть добавлены новые виды транспорта, а определение вашего столбца останется прежним.

С этой конструкцией я бы определенно решил регулировать это на уровне БД, а не на уровне приложения.

person NGLN    schedule 16.06.2011
comment
Мне это нравится больше всего - это единственный ответ, который соответствует требованию добавления большего количества типов в будущем без внесения изменений в базу данных (просто вставьте новую строку) - person Bohemian♦; 16.06.2011
comment
Согласен, тот факт, что данные не являются статическими, подтверждает, что это должна быть таблица поиска, а не ограничение CHECK или его эквивалент. И да, это ограничение данных должно быть смоделировано в базе данных. - person onedaywhen; 16.06.2011

Для MySQL вы можете использовать тип данных ENUM.

имя_столбца ENUM('маленький', 'средний', 'большой')

См. Справочник по MySQL: тип ENUM.

В дополнение к этому я считаю, что всегда лучше ограничивать на стороне БД И на стороне приложения. Enum плюс поле Select, и все готово.

person nageeb    schedule 16.06.2011
comment
Это вряд ли удовлетворяет требованию легкого добавления большего количества типов в будущем - вам нужно внести изменения в БД. Спросите администратора базы данных, как он будет рад этому. - person Bohemian♦; 16.06.2011
comment
Вы не упомянули, что не хотите беспокоить бедного администратора базы данных добавлением дополнительных элементов. Возможно, вам следовало указать это в вопросе. - person nageeb; 16.06.2011
comment
Я не задавал вопрос. Я просто прокомментировал ваш ответ. Хотя я не минусовал :) - person Bohemian♦; 16.06.2011
comment
Виноват. Прошу прощения, если комментарий прозвучал немного язвительно, но я предполагаю, что разные люди принимают разные определения. Я на 100% согласен с принятым ответом (и проголосовал за него) и считаю, что программно разрешить добавление значений было бы лучшим решением, но, будучи лично кодером, я бы просто изменил БД, если бы это не было концом -Функция взаимодействия с пользователем. - person nageeb; 17.06.2011
comment
При реализации этого с помощью уровня ORM это можно легко изменить с помощью миграции. Правильно отслеживаемый через git, я считаю, что это хорошее решение для реализации и отслеживания ограничений значений, реализованных в самой базе данных. - person Daniel Böttner; 21.01.2019

Да, рекомендуется добавить контрольные ограничения. Проверочные ограничения используются для обеспечения достоверности данных в базе данных и обеспечения целостности данных. Если они используются на уровне базы данных, приложения, использующие базу данных, не смогут добавлять недопустимые данные или изменять действительные данные, поэтому данные становятся недействительными, даже если само приложение принимает недопустимые данные.

В SQLite:

create table MyTable
(
    name string check(name = "car" or name = "bike" or name = "van")
);

В MySQL:

create table MyTable
(
    name ENUM('car', 'bike', 'van')
);
person Alex Aza    schedule 16.06.2011
comment
В SQLite вы можете сказать check("name" in ('car', 'bike', 'van')). Также: -кавычки для идентификаторов и '-кавычки для литеральных значений. - person equaeghe; 23.03.2016

Вы бы использовали контрольное ограничение. В SQL Server это работает так

ALTER TABLE Vehicles
ADD CONSTRAINT chkVehicleType CHECK (VehicleType in ('car','bike','van'));

Я не уверен, что это стандарт ANSI, но я уверен, что MySQL имеет аналогичную конструкцию.

person Bob Probst    schedule 16.06.2011
comment
не хватает закрывающей скобки? - person faizal; 23.08.2014

Если вы хотите использовать проверку на стороне БД, вы можете использовать триггеры. См. это для SQLite и это подробное руководство для MySQL.

Таким образом, вопрос действительно заключается в том, следует ли вам использовать проверку базы данных или нет. Если у вас есть несколько клиентов — будь то разные программы или несколько пользователей (возможно, с разными версиями программы) — то, безусловно, лучше всего использовать маршрут базы данных. База данных (надеюсь) централизована, поэтому вы можете отделить некоторые детали проверки. В вашем конкретном случае вы можете убедиться, что значение, вставляемое в столбец, содержится в отдельной таблице, в которой просто перечислены допустимые значения.

С другой стороны, если у вас мало опыта работы с базами данных, вы планируете работать с несколькими разными базами данных и у вас нет времени на приобретение опыта, возможно, наиболее целесообразным выбором будет простая проверка на уровне приложения.

person Dilum Ranatunga    schedule 16.06.2011