Почему ENUM лучше чем INT - PullRequest
       35

Почему ENUM лучше чем INT

22 голосов
/ 22 сентября 2008

Я только что запустил «АНАЛИЗ ПРОЦЕДУРЫ ()» на одном из моих столов. И у меня есть этот столбец, который имеет тип INT, и он всегда содержит значения от 0 до 12 (идентификаторы категории). И MySQL сказал, что мне будет лучше с ENUM ('0', '1', '2', ..., '12'). Эта категория в основном статическая и не изменится в будущем, но если они это сделают, я могу просто изменить этот столбец и добавить его в список ENUM ...

Так почему же ENUM лучше в этом случае?

edit: меня больше всего интересует аспект производительности ...

Ответы [ 5 ]

29 голосов
/ 22 сентября 2008

Проще говоря, это потому, что он проиндексирован по-другому.

В этом случае ENUM говорит: «Это одно из этих 13 значений», тогда как INT говорит: «Это может быть любое целое число».

Это означает, что индексация проще, так как она не должна учитывать индексацию для тех целых чисел, которые вы не используете «на всякий случай», когда вы их используете.

Это все связано с алгоритмами.

Мне было бы интересно, хотя, когда дело доходит до точки, где INT будет быстрее, чем ENUM.

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

20 голосов
/ 22 сентября 2008

Хлоп! Существует множество неясностей с использованием чисел в поле ENUM. Быть осторожен. Единственное, что я помню, это то, что вы можете получить доступ к значениям в ENUMS по индексу: если ваше перечисление равно ENUM('A', 'B', 'C', '1', '2, '3'), то эти два запроса очень разные:

INSERT INTO TABLE (example_col) VALUES( '1' ); -- example_col == 1
INSERT INTO TABLE (example_col) VALUES(  1  ); -- example_col == A

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

Лучше было бы использовать TINYINT вместо INT. UNSIGNED TINYINT имеет диапазон от 0 до 255 и занимает 1 байт для хранения . INT занимает 4 байта для хранения. Если вы хотите ограничить значения, попадающие в таблицу, вы можете добавить триггеры ON INSERT и ON UPDATE, которые проверяют значения.

Если вы беспокоитесь о разнице в производительности между ENUM и TINYINT, вы всегда можете сравнить тесты, чтобы увидеть разницу. Эта статья кажется несколько уместной.

4 голосов
/ 22 сентября 2008

Поскольку он вводит ограничение на возможные значения.

2 голосов
/ 22 сентября 2008

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

1 голос
/ 22 сентября 2008

В Oracle у меня был бы индекс BITMAP, который намного быстрее, чем поиск на основе хеш-функции для такого небольшого числа значений. (Таким образом, я предполагаю, что аналогичное преимущество в запросе или индексации доступно для MySQL.)

Интересно, что документы MySQL предполагают, что использование «вещей, похожих на числа» является плохим выбором для типа ENUM из-за возможной путаницы между значением перечисления и индексом перечисления (http://dev.mysql.com/doc/refman/5.0/en/enum.html).

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