SQL: преимущества ENUM по сравнению с отношением «один ко многим»? - PullRequest
14 голосов
/ 27 ноября 2010

Я очень редко вижу типы данных ENUM, используемые в дикой природе; разработчик почти всегда просто использует дополнительную таблицу, которая выглядит следующим образом:

CREATE TABLE officer_ranks (
id int PRIMARY KEY
,title varchar NOT NULL UNIQUE);
INSERT INTO ranks VALUES (1,'2LT'),(2,'1LT'),(3,'CPT'),(4,'MAJ'),(5,'LTC'),(6,'COL'),(7,'BG'),(8,'MG'),(9,'LTG'),(10,'GEN');

CREATE TABLE officers (
solider_name varchar NOT NULL
,rank int NOT NULL REFERENCES officer_ranks(id) ON DELETE RESTRICT
,serial_num varchar PRIMARY KEY);

Но то же самое можно показать и с помощью пользовательского типа / ENUM:

CREATE TYPE officer_rank AS ENUM ('2LT', '1LT','CPT','MAJ','LTC','COL','BG','MG','LTG','GEN');

CREATE TABLE officers (
solider_name varchar NOT NULL
,rank officer_rank NOT NULL
,serial_num varchar PRIMARY KEY);

(Пример показан с использованием PostgreSQL, но другие СУБД имеют аналогичный синтаксис)

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

Если предположить, что информация в основном статическая (названия дней недели, названия месяцев, звания армии США и т. Д.), Есть ли какое-либо преимущество в использовании ENUM?

Ответы [ 7 ]

13 голосов
/ 28 ноября 2010

Пример показан с использованием PostgreSQL, но другие РСУБД имеют аналогичный синтаксис

Это неправильно. Это не требование SQL ISO / IEC / ANSI, поэтому коммерческие базы данных не предоставляют его (вы должны предоставить таблицы поиска). В маленьком конце города реализуются различные «дополнения», но не реализуются более строгие требования или ворчание большого конца города.

У нас также нет ENUM как части DataType, что абсурдно.

Первый недостаток ENUM заключается в том, что он нестандартный и поэтому не переносимый.

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

Третье, когда вы меняете значения, вы должны изменить DDL. В базе данных Normal Standard SQL вы просто вставляете / обновляете / удаляете строку в таблице поиска.

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

7 голосов
/ 27 ноября 2010

Я не вижу никаких преимуществ в использовании ENUMS.

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

6 голосов
/ 27 ноября 2010

Небольшое преимущество может заключаться в том, что у вас есть своего рода UDT при создании ENUM. Определенный пользователем тип может быть повторно использован формально во многих других объектах базы данных, например, в представлениях, других таблицах, других типах, хранимых процедурах (в других СУБД) и т. д.

Еще одним преимуществом является документирование допустимых значений поля. Примеры:

  • Поле да / нет
  • Мужское / женское поле
  • Поле mr / mrs / ms / dr

Вероятно, дело вкуса. Я предпочитаю ENUM для таких полей, а не внешние ключи для поиска таблиц для таких простых концепций.

Еще одним преимуществом может быть то, что когда вы используете генерацию кода или ORM, такие как jOOQ в Java, вы можете использовать этот ENUM для генерирования из него класса enum Java вместо присоединения к таблице поиска или работы с идентификатором литерала ENUM

Это факт, однако, что лишь немногие РСУБД поддерживают формальный тип ENUM. Я знаю только о Postgres и MySQL. У Oracle или DB2 его нет.

5 голосов
/ 28 ноября 2010

Недостатком использования чего-то вроде ENUM является то, что вы не можете получить список всех доступных значений, если они не существуют в вашей таблице данных, если только вы не жестко закодировали список доступных значений где-либо. Например, если в вашей таблице OFFICERS у вас нет MG на посту, нет способа узнать, существует ли ранг. Таким образом, когда BG Blowhard получает облегчение от MG Marjorie-Banks, у вас не будет возможности ввести звание нового офицера - это позор, так как он является самой моделью современного генерал-майора. :-) А что происходит, когда появляется генерал армии (пятизвездочный генерал)?

Для простых типов, которые не изменятся, я успешно использовал домены. Например, в одной из моих баз данных у меня есть yes_no_domain, определенный следующим образом:

CREATE DOMAIN yes_no_dom
  AS character(1)
  DEFAULT 'N'::bpchar
  NOT NULL
   CONSTRAINT yes_no_dom_check
     CHECK ((VALUE = ANY (ARRAY['Y'::bpchar, 'N'::bpchar])));

Делись и наслаждайся.

2 голосов
/ 29 ноября 2010

Преимущества:

  • Безопасность типов для хранимых процедур: вызовет ошибку типа, если аргумент не может быть приведен к типу. Например: select court_martial('3LT') автоматически вызовет ошибку типа.

  • Пользовательский порядок коалиции: в вашем примере офицеры могут быть отсортированы без идентификатора рейтинга.

2 голосов
/ 28 ноября 2010

Вообще говоря, enum лучше подходит для вещей, которые не сильно меняются, и использует немного меньше ресурсов, поскольку нет никаких проверок FK или чего-либо подобного выполнению при вставке и т. Д.

Использование справочной таблицы более элегантно и / или традиционно, а добавлять и удалять параметры гораздо проще, чем перечисление. Также проще массово изменить значения, чем перечисление.

0 голосов
/ 21 декабря 2010

Ну, вы не видите, потому что обычно разработчики используют перечисления в таких языках программирования, как Java, и не имеют своих аналогов в дизайне базы данных.

В базе данных такие перечисления обычно представляют собой текстовые или целочисленные поля без ограничений. Перечисления базы данных не будут переведены в Java / C # / etc. перечисления, поэтому разработчики не видят в этом никакой выгоды.

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

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