Тип для использования для столбцов «Состояние» в таблице SQL - PullRequest
26 голосов
/ 26 августа 2011

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

ticket
  <b>id</b>: int(11) PK
  <b>name</b>: varchar(255)
  <b>status</b>: ?????????

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

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

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

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

OPEN => "Открыть"

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

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

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

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

Ответы [ 7 ]

6 голосов
/ 26 августа 2011

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

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

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

5 голосов
/ 26 августа 2011

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

5 голосов
/ 26 августа 2011

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

3 голосов
/ 26 августа 2011

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

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

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

Перейти с вариантом 3.

3 голосов
/ 26 августа 2011

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

РЕДАКТИРОВАТЬ: Я думаю, это именно то, что вы изложили в пункте 3. Я думаю, что это лучший вариант.

0 голосов
/ 04 декабря 2018

Я недавно работал со многими базами данных, которым требуется много статусов, и у меня есть несколько заметок, которые, возможно, стоит добавить к беседе.

INT : Одна вещь, которую я обнаружил, состоит в том, что, если в приложении много отслеживания, число справочных таблиц может быстро стать громоздким и, как вы упомянули, проверять базу данных на взгляд непрактичный. (Что для некоторых моих клиентов имело значение гораздо больше, чем скудные миллисекунды, которые он экономил во время обработки.)

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

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

Единственное, что вы не могли бы сделать, что я пропустил, - это математические операции (например, «<» и «>»).

Диапазон INT : гибридная стратегия, которую я опробовал, заключается в использовании INT, но с добавлением степени семантики к числам. Так, например,

1-10 being for initial stages, 
11-20 being in progress, and 
21-30 being the final stages. 
60-69 for errors, rejections

Проблема здесь в том, что если вы обнаружите, что вам нужно больше чисел, вы СОЛ, так как следующий диапазон уже занят. Итак, в итоге я (вроде) имитировал HTTP-ответы:

100-199 being for initial stages, 
200-299 being in progress, and 
300-399 being the final stages. 
500-599 for errors, rejections

Я предпочитаю это простому INT, и хотя оно может быть менее наглядным, чем CHAR, оно также может быть менее двусмысленным. В то время как «PROG» может означать множество вещей, хороших, плохих или доброкачественных, если я увижу, что что-то находится в диапазоне 500, я, возможно, не знаю, в чем проблема, я смогу сказать вам, что is проблема.

0 голосов
/ 19 сентября 2015

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

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

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

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

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

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