Mysql Datatype - Enum или не Enum, Can Enum может быть пустым?

У меня большая БД (много миллионов строк), и я пытаюсь сделать лучший выбор для типов данных для двух полей. Большинство всего, что я сделал varchar или INT. Тем не менее, 2 поля, мне интересно, является ли Enum лучшим способом.

Поле 1 Первое поле - пол. Мои данные в настоящее время являются "мужчинами" или "женщинами", или это может быть пустой. Я изначально настроил его так:

GENDER VARCHAR(6) NOT NULL

Это лучший способ, или было бы лучше настроить его как:

GENDER ENUM ('Male', 'Female') NOT NULL

И мне нужно сделать это NOT NULL, чтобы разрешить пробел, или мне нужно добавить пробел, т.е.

GENDER ENUM ('Male', 'Female', '') NOT NULL

Не говоря уже о том, что я рассматриваю преобразование всего поля только в M или F.

Поле 2: У меня есть почти все те же вещи, которые следует учитывать, за исключением поля состояния, которое может включать 52 значения (50 состояний, DC, плюс пробел).

Я думаю, самый большой вопрос: стоит ли это все Enum? Моя БД имеет много миллионов строк, поэтому все является фактором, но я должен использовать VARCHAR (2) для состояний вместо ENUM.

Ответ 1

Правило большого пальца, которое я обычно применяю к таким случаям, НЕ МОЖЕТ использовать MySQL ENUM. Использование их создает проблемы с обслуживанием, особенно вокруг добавления/удаления/переименования некоторых значений. В InnoDB переименование и удаление значения перечисления тяжело на больших таблицах. Добавление значения не является (если вы не добавляете его посередине).

Как вы, вероятно, хотите сохранить этот столбец в контексте и не допускать какого-либо значения из этого контекста, лучший способ IMHO - использовать INT и подключить его как внешний ключ к таблице значений (идентификаторы столбцов, значение).

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

Чтобы легко прочитать данные, все, что вам нужно, это просто JOIN.

Примечание. Поскольку гендерные группы довольно окончательные, вы можете оставить его как VARCHAR (1) или использовать ENUM, как предлагает Йохан, но кто знает? Возможно, вы захотите поддержать трансгендеров и андрогинию в будущем. Без шуток.

Ответ 2

Если вы хотите иметь значение для no value entered, используйте null, для чего предназначен null!

Если вы хотите указать что-то между мужчиной и женщиной (у нескольких несчастных людей есть это условие), используйте

ENUM('male','female','neither') NULL;

Обратите внимание, что перечисление не хранит буквальное текстовое значение в столбце.
male сохраняется как 1, female как 2 и neither как 3 и т.д.
Это означает, что он намного эффективнее, чем варчар.

Если вы боретесь с null в своих настройках, обратите внимание, что вы можете использовать функции ifnull или coalesce, чтобы заменить null на что-то более полезное.

SELECT IFNULL(gender,'unknown') as gender FROM people;
-- or the identical statement
SELECT COALESCE(gender,'unknown') as gender FROM people;