Тип, используемый для столбцов "статус" в таблице sql

У меня есть (фиктивная) структура таблицы следующим образом:

ticket
  id: int(11) PK
  name: varchar(255)
  status: ?????????

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

  1. varchar, представляющий статус-плохо, потому что нет целостности
  2. перечисление, представляющее статус-плохо, потому что для изменения значения мне придется изменить таблицу, а затем любой код с выпадающими значениями и т. д. и т. д.
  3. int FK в таблицу состояния-хорошо, потому что это динамично, плохо, потому что это сложнее проверить на глаз (что может быть полезно)
  4. varchar FK в таблицу состояния-хорошо, потому что она динамическая и видимая при осмотре. Плохо, потому что ключи имеют смысл, что обычно не одобряется. Интересно, что в этом случае вполне возможно, что таблица состояния имеет только 1 столбец, что делает ее прославленным перечислением

есть ли у меня точное чтение ситуации? Неужели иметь значимый ключ так плохо? Потому что хотя от этого у меня мурашки по коже, у меня нет никаких причин для этого...

обновление: Для варианта 4, предлагаемая структура будет статус: char (4) FK в таблице состояния. Итак,

открыть => "открыть"

CLOS = > "закрыто"

"PEND" = > "ожидание авторизации"

"PROG" = > " выполняется

в чем недостаток в этом случае ? Единственное преимущество, которое я вижу в использовании int над char в этом случае небольшая производительность.

6 ответов


перейти с номером 3. Создайте представление, которое соединяется в значении состояния, если вы хотите что-то проверить.


Я бы пошел с номером 4, но я бы использовал . Если вы беспокоитесь о производительности, char (4) занимает столько же места (и, или так можно подумать, дисковый ввод-вывод, пропускная способность и время обработки), как int, который также занимает 4 байта для хранения. Если вы действительно беспокоитесь о производительности, сделайте ее char(2) или даже char (1).

Не думайте об этом как о" значимых данных", думайте об этом как об аббревиатуре естественного ключа. Да, данные имеют смысл, но, как вы заметили, это может это означает, что вам не всегда нужно присоединяться (даже если это тривиально маленькая таблица), чтобы извлечь смысл из базы данных. И, конечно же, ограничение внешнего ключа гарантирует, что данные действительны, поскольку они должны быть в таблице подстановки. (Это можно сделать и с ограничениями проверки, но таблицы поиска, как правило, легче управлять и поддерживать с течением времени.)

недостатком является то, что вы можете попасть в ловушку, пытаясь найти смысл. char (1) имеет сильное обращение, но если вы получите десять или более значений, это может получить трудно придумать хороший осмысленные значения. Меньше проблем с char (4), но все же возможная проблема. Еще один недостаток: если данные могут измениться, то да, ваши значимые данные ("PEND" = "ожидающая авторизации") могут потерять свое значение ("PEND" = "переслать в home office для первоначального утверждения"). Это плохой пример; если такие коды меняются, вам, вероятно, намного лучше рефакторинг вашей системы отразить изменение бизнес-правил. Я думаю, что моя точка зрения должна быть, если это введенное пользователем значение поиска, суррогатные ключи (целые числа) будут вашим другом, но если они внутренне определены и поддерживаются, вы должны определенно рассмотреть более удобные для человека значения. Это, или вам понадобятся заметки post-em на вашем мониторе, чтобы напомнить вам, что должен означать статус heck = 31. (У меня их три, а липучка изнашивается каждые несколько месяцев. Поговорим о стоимости обслуживания...)


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


могу ли я рекомендовать вам пойти с полем statusID вместо этого и иметь отдельную таблицу, сопоставляющую ID с varchar?

EDIT: я думаю, это именно то, что вы изложили в пункте 3. Я думаю, что это лучший вариант.


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

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

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

перейти к варианту 3.


создание отдельной таблицы со статусом-хорошая идея, когда вы хотите показать список статуса в форме HTML. Вы можете показать подробное описание из таблицы подстановки, и это поможет пользователю выбрать статус, если требования такие.

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

Если вы используете аббревиатуру как внешний ключ тогда вы должны думать каждый раз, чтобы сделать его уникальным все время, как @Philip Kelley упомянул его в качестве обратной стороны.

наконец, вы можете объявить тип таблицы MYISAM, если хотите.

обновление: Отражая мнение @Philip Kelley, если слишком много статуса, то лучше использовать integer в качестве внешнего ключа. Если есть только пара статуса, то можно использовать abbr в качестве внешнего ключа.