Тип MySQL ENUM и таблицы соединений

Мое требование

Таблица должна поддерживать столбец статус.

Этот столбец представляет одно из 5 состояний.


первоначальный дизайн

Я решил, что могу просто сделать его целочисленным столбцом и представлять состояния с помощью числового значения.

  • 0 = начало
  • 1 = работает
  • 2 = разбился
  • 3 = приостановлено
  • 4 = остановлен

Поскольку я не хочу, чтобы мое приложение поддерживало сопоставление целых чисел с их строковым описанием, я планирую поместить их в отдельную таблицу описания состояний (полагаясь на отношение FK).

Затем я обнаружил, что MySQL имеет тип ENUM, который точно соответствует моим требованиям. Есть ли какие-либо подводные камни при использовании типа ENUM, кроме прямой зависимости от MySQL?

Тип данных ENUM начинает отсчет с 1, а не с 0, как вы указали.

Tomalak 12.12.2008 09:46

см .: dev.mysql.com/doc/refman/5.0/en/enum.html

Tomalak 12.12.2008 09:47
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
66
2
20 674
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

В качестве оптимизации это, вероятно, очень преждевременно; но OP в основном предлагает это как удобную функцию.

См. Также http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/

Ответ принят как подходящий
  • Для изменения набора значений в ENUM требуется ALTER TABLE, который может вызвать реструктуризацию таблицы - невероятно дорогостоящая операция (реструктуризации таблицы не произойдет, если вы просто добавите одно новое значение в конец определения ENUM, но если вы удалите one, или изменить порядок, выполняется реструктуризация таблицы). В то время как изменить набор значений в таблице поиска так же просто, как INSERT или DELETE.

  • Невозможно связать другие атрибуты со значениями в ENUM, например, какие из них удалены, а какие могут быть помещены в раскрывающийся список в вашем пользовательском интерфейсе. Однако таблица поиска может включать дополнительные столбцы для таких атрибутов.

  • Очень сложно запросить ENUM, чтобы получить список отдельных значений, в основном требуя, чтобы вы запросили определение типа данных из INFORMATION_SCHEMA и проанализировали список из возвращенного BLOB. Вы можете попробовать SELECT DISTINCT status из своей таблицы, но он получит только те значения статуса, которые используются в настоящее время, а это могут быть не все значения в ENUM. Однако, если вы сохраняете значения в таблице поиска, их легко запрашивать, сортировать и т. д.

Как видите, я не большой поклонник ENUM. :-)

То же самое относится к ограничениям CHECK, которые просто сравнивают столбец с фиксированным набором значений. Хотя MySQL все равно не поддерживает ограничения CHECK.

Обновление: MySQL 8.0.16 теперь реализует ПРОВЕРИТЬ ограничения.

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

ashitaka 12.12.2008 10:05

О, я забыл одно: ENUM не является стандартным SQL, и, как ни странно, ни одна другая база данных не поддерживает его. Таким образом, это ограничивает вашу мобильность, если вы его используете.

Bill Karwin 12.12.2008 10:07

Кто-то проголосовал против. Когда вы голосуете против, не могли бы вы объяснить, в чем вы возражаете? Возможно, я смогу улучшить ответ.

Bill Karwin 08.11.2010 23:46

Вам не обязательно использовать INFORMATION_SCHEMA. Используйте DESC table, просматривайте результаты, пока не найдете нужное поле, и используйте регулярное выражение для получения полей. Это не самое лучшее занятие, но и не так уж и плохо.

Ariel 11.07.2012 08:22

Нашел еще одно интересное объяснение: komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil

Zbyszek 06.06.2013 09:59

@Zbyszek, ах, опасно похоже ... кто был первым?

Pacerier 31.01.2015 02:16

@Pacerier, я ответил на этот пост 12 декабря 2008 г. Блог по этой ссылке был написан 2 марта 2011 г.

Bill Karwin 01.02.2015 00:19

Другие БД, которые используют, - это Postgres и MariaDB (на самом деле любая вилка MySQL, о которой я могу думать)

MrMesees 28.03.2016 23:13

Я не думаю, что ответ @BillKarwin больше актуален. MySQL, Maria и Postgresql поддерживают тип ENUM.

Brett McLain 20.03.2018 06:09

Вот статья про сравнение скорости перечисления. Может быть, это дает какие-то подсказки. ИМХО следует ограничиться использованием фиксированного списка строк («Да / Нет», «Ребенок / Взрослый»), который с вероятностью 99% не изменится в будущем.

Перечисления в MySQL плохи по уже объясненным причинам. Могу добавить следующий факт: Enum не обеспечивает никакой проверки на стороне сервера. Если вы вставите строку со значением, которого нет в определении перечисления, вы получите хорошее значение <empty> или NULL в БД, в зависимости от NULL-способности объявления поля перечисления.

Моя точка зрения о крошечных точках:

  • перечисления ограничены 65535 значениями
  • если вам не нужно больше 256 значений, tinyint займет меньше места для каждой строки, и его поведение будет более «предсказуемым».

Подождите, так что перечисления или tinyints - это плохо? Или оба?

Brad Moore 21.01.2014 06:38

Совершенно уверен, что он хотел сказать, что «перечисления» плохи по объясненным причинам.

abenson 07.01.2015 22:53

По крайней мере, в MySQL, если вы установите SQL_MODE в одну из строгих форм, вы не получите null или '', если попытаетесь вставить значение, которого нет в ENUM. Вы получите сообщение об ошибке. См. dev.mysql.com/doc/refman/5.7/en/constraint-enum.html

Bill Karwin 29.03.2016 00:17

Если у вас много данных в вашей БД (больше данных, чем у вас есть ОЗУ), и ваши значения ENUM НИКОГДА не изменятся, я бы выбрал ENUM, а не соединение. Так должно быть быстрее. Подумайте об этом: в случае соединения вам понадобится индекс вашего внешнего ключа и индекс вашего первичного ключа в другой таблице. Как сказал Рихо, посмотрите тесты.

Другие вопросы по теме