INT или CHAR для поля типа

19

Каков наилучший дизайн для стола, Typeполя intили char(1)? Другими словами, учитывая эту схему:

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehType .... not null
)

Это более эффективно (с точки зрения производительности) для того, VehTypeчтобы быть intили char(1)? Скажем, у вас есть пять типов автомобилей, должны ли вы использовать приращения значений 0 -> 4 или символы для типов (скажем, 'v', 's', 'c', 't', 'm')?

Если бы это было больше, я бы использовал отдельную таблицу типов и имел бы связь с внешним ключом, но я не вижу в этом необходимости.

Я заметил, что представление sys.objectsкаталога использует символ для typeполя. Есть ли причина для этого? Я просто хватаюсь за воздух и могу ли я чувствовать себя более комфортно?

Томас Стрингер
источник

Ответы:

20

Вы обычно используете tinyint, который также равен 1 байту

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

  • путаница: что такое S: внедорожник или седан или седан или спорт?

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

  • каждая система, которую я видел, имеет более одного клиента, например, отчет. Логика смены V, S на «Ван», «Внедорожник» и т. Д. Потребуется повторить. Использование таблицы поиска означает, что это просто JOIN

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

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

Плюсом использования одной буквы ... э, не вижу

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

ГБН
источник
2
отличные моменты. Меня удивляет, почему другие используют char (1) (например, sys.objects).
Томас Стрингер
2
У sys.objects есть наследие Sybase и более ранних версий SQL Server. en.wikipedia.org/wiki/Microsoft_SQL_Server#Genesis Если вы посмотрите на системные объекты, вы можете увидеть коды, а не идентификаторы, но в новых DMV это не так. Что касается других людей, кроме MS? Думайте RDBMS, а не OO / Enums, и имеет смысл использовать Lookups.
ГБН
1
Хорошо я согласен. Спасибо за разъяснение. Так что это довольно точное утверждение, что нет реального чрезмерного проектирования с помощью реляционной целостности и таблиц поиска? Я имею в виду, что в этом случае с сохранением нескольких записей в таблице поиска и ссылками на них в таблице потребления будет ли предыдущий оператор точным?
Томас Стрингер
1
@onedaywhen: Если вы смотрите на различные типы как на данные или как на статический набор значений, который никогда не изменится, будет иметь значение. Если вы используете таблицу типов, вы можете просто добавить другой тип таблицы без необходимости изменять бизнес-правила в базе данных и в приложении.
Гуффа
1
@ MichaelKjörling: Правильно, если это был просто ключ. Но OP намеревается обозначить что-то вроде «v» или «s». Обратите внимание, мы не о самоописании и полных натуральных ключах, таких как коды валют (EUR, USD, GBP, CHF и т. Д.).
ГБН
3

Так же, как дополнение к великому ответу ГБН .

Может быть, вы могли бы создать что-то вроде этого:

create table dbo.VehicleType
(
    VehicleTypeId int not null primary key,
    Name varchar(50) not null,
    Code char(3) null
) 
go 

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehTypeId int not null ,
    foreign key FKTypeOfCar(VehTypeId) referenctes dbo.VehicleType (VehicleTypeId) 
)
go 

Таким образом, вы можете делать все что угодно с вашим перечислением, сохраняя целостность отношений (используя внешний ключ). С помощью codeстолбца вы можете использовать свои коды символов по своему усмотрению, чтобы они документировались в базе данных (и вы можете извлекать информацию о коде непосредственно из БД, без сложного преобразования кода приложения для системной интеграции).

Фабрицио Араужо
источник
Вы хотите разрешить nullкод?
Джек Дуглас
Да, код является необязательным, чтобы разрешить представлять тип транспортного средства, который еще не кодифицирован.
Фабрицио Араужо
Почему людям нравится удалять комментарии? Это довольно раздражает.
Фабрицио Араужо
@FabricioAraujo - Если комментарий устарел (например, «я отредактирую его в своем ответе», а затем вы действительно это сделаете), то хорошо, чтобы убрать комментарии, которые больше не применяются.
Ник Чаммас
1
Я бы предложил добавить тип Unclassified в таблицу типов и установить значение по умолчанию для вашего поля VehTypeId в качестве неклассифицированного значения вместо того, чтобы разрешать нулевое значение в поле внешнего ключа. Обычно плохая практика - делать «ноль» действительным деловым смыслом.
Майкл Блэкберн