Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

Хлоп! Там есть куча двусмысленностей с использованием чисел в поле 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. a UNSIGNED TINYINT имеет диапазон от 0 до 255 и берет 1 байт для хранения. INT занимает 4 байта для хранения. Если вы хотите ограничить значения, попадающие в таблицу, вы можете добавить триггеры ON INSERT и ON UPDATE, которые проверяют значения.

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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