Тип MySQL ENUM против таблиц соединения - PullRequest
55 голосов
/ 12 декабря 2008

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

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

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


Первоначальный проект

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

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

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

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

Ответы [ 5 ]

94 голосов
/ 12 декабря 2008
  • Для изменения набора значений в ENUM требуется ALTER TABLE, что может привести к реструктуризации таблицы - невероятно дорогая операция (реструктуризация таблицы не произойдет, если вы просто добавите одно новое значение в конец определение ENUM, но если вы удалите его или измените порядок, он выполнит реструктуризацию таблицы). Принимая во внимание, что изменение набора значений в справочной таблице так же просто, как INSERT или DELETE.

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

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

Как вы можете сказать, я не большой поклонник ENUM. : -)

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

Обновление: MySQL 8.0.16 теперь реализует ограничения CHECK .

11 голосов
/ 12 декабря 2008

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

7 голосов
/ 12 декабря 2008

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

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

3 голосов
/ 18 ноября 2010

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

0 голосов
/ 12 декабря 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...