enum или char (1) в MySQL - PullRequest
       2

enum или char (1) в MySQL

6 голосов
/ 07 ноября 2011

Иногда я не уверен, используете ли enum или char (1) в MysQL.Например, я храню статусы сообщений.Обычно мне нужны только значения Active или Passive в поле status.У меня есть два варианта:

// CHAR
status char(1);

// ENUM (but too limited)
status enum('A', 'P');

А что, если я хочу добавить еще один тип статуса (т.е. Hidden) в будущем?Если у меня есть небольшие данные, это не будет проблемой.Но если у меня слишком большие данные, так что редактирование типа ENUM будет проблемой, я думаю.

Так что вы посоветуете, если мы тоже подумаем о производительности MySQL?В какую сторону я пойду?

Ответы [ 4 ]

6 голосов
/ 07 ноября 2011

Ни. Вы обычно используете tinyint с таблицей поиска

  • char (1) будет немного медленнее, потому что сравнение использует сопоставление

  • путаница: при расширении на более чем A и P

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

  • каждая система, которую я видел, имеет более одного клиента, например, отчет. A и P должны быть преобразованы в Active и Passive для каждого клиентского кода

  • расширяемость: добавьте еще один тип («S» для «Приостановлено»), вы можете добавить одну строку в таблицу поиска или изменить много кода и ограничений. И ваш код клиента тоже

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

  • Enum не является переносимым

С положительной стороны от использования одной буквы или Enum

Примечание: существует связанный вопрос DBA.SE MySQL о Enums . Там также рекомендуется использовать справочную таблицу.

1 голос
/ 07 ноября 2011

Я бы использовал для этого двоичное поле SET, но без обозначения опций специально в базе данных.Вся «маркировка» будет выполняться внутри вашего кода, но она предоставляет некоторые очень гибкие параметры.

Например, вы можете создать SET, содержащий восемь «параметров», таких как;

`column_name` SET('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') NOT NULL DEFAULT ''

В вашем приложении вы можете определить «a» как «активный» или «пассивный», «b» может обозначать «скрытый», а остальные можно оставить неопределенными, пока они вам не понадобятся.

Затем вы можете использовать всевозможные полезные двоичные операции с полем, например, вы можете извлечь все те, которые «скрыты», запустив;

WHERE `column_name` & 'b'

И все те, которые являются «активными» И«Скрыто» при выполнении;

WHERE `column_name` & 'a' AND `column_name` & 'b'

Вы даже можете использовать операторы LIKE и FIND_IN_SET для выполнения еще более полезных запросов.

Прочтите документацию MySQL для получения дополнительной информации;

http://dev.mysql.com/doc/refman/5.1/en/set.html

Надеюсь, это поможет!

Дейв

1 голос
/ 07 ноября 2011

Вы можете использовать

status enum('Active', 'Passive');

Он не будет сохранять строку в строке, он будет сохранять только число, которое является ссылкой на член enum в структуре таблицы, поэтому размер такой же, но он более читабелен, чем char(1) или enum.
Редактирование enum не проблема, независимо от того, насколько велики ваши данные

0 голосов
/ 07 ноября 2011

Трудно сказать, не зная семантику ваших статусов, но мне «скрытый» не кажется альтернативой «активному» или «пассивному», то есть вы можете захотеть иметь и «активный скрытый» и «пассивный»скрытый ";это будет ухудшаться с каждым новым неисключительным «состоянием», было бы лучше реализовать вашу схему с логическими флагами: один для активного / пассивного различия и один для скрытого / видимого различия.Запросы становятся более читабельными, когда ваше условие «ГДЕ НЕ скрыто» или «ГДЕ активно» вместо «ГДЕ состояние =« А »».

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