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чи a char(1)? Скажімо, у вас п'ять типів автомобілів, чи слід використовувати значення приросту 0 -> 4 або символи для типів (скажімо; 'v', 's', 'c', 't', 'm')?

Якщо це не що інше, я використовував би окрему таблицю Type і мав стосунки із зовнішнім ключем, але я не бачу потреби в цьому.

Зауважую, що у sys.objectsподанні каталогу використовується символ для typeполя. Чи є причина в цьому? Чи я просто хапаюся тут за повітря, і чи не мені це зручніше?

Відповіді:


20

Зазвичай ви використовуєте tinyint, який теж є 1 байт

  • char (1) буде дещо повільнішим, оскільки порівняння використовує порівняння

  • плутанина: що таке S: позашляховик чи салон, седан чи спорт?

  • використання букви обмежує вас, оскільки ви додаєте більше типів. Дивіться останній пункт.

  • кожна система, яку я бачив, має більше одного клієнта, наприклад, звітності. Логіку зміни V, S на "Van", "SUV" тощо потрібно буде повторити. Використання таблиці пошуку означає, що це ПРИЄДНАЙТЕСЬ

  • розширюваність: додайте ще один тип ("F" для " Літаючого автомобіля "), ви можете один рядок до таблиці пошуку або змінити багато коду та обмежень. І ваш клієнтський код теж тому, що він повинен знати, що таке V, S, F тощо

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

З плюсу використання однієї літери ... е, не бачите жодної

Примітка. Існує відповідне питання MySQL щодо Enums . Рекомендація також використовувати там таблицю пошуку.


2
чудові моменти. Мене змушує замислитися, чому інші використовують char (1) (наприклад, sys.objects).
Томас Стрінгер

2
sys.objects має спадщину, що повертається до Sybase та ранніх версій SQL Server en.wikipedia.org/wiki/Microsoft_SQL_Server#Genesis Якщо ви подивитесь на системні об'єкти, ви зможете побачити коди не ідентифікатори в усьому світі: але менше в нових DMV. Що стосується інших людей, крім МС? Подумайте RDBMS, а не OO / Enums, і є сенс використовувати Lookups.
gbn

1
добре, я згоден Дякуємо, що ви зрозуміли це. Тож чи досить точне твердження про те, що не існує справжньої надмірної інженерії з реляційною цілісністю та таблицями пошуку? Я маю на увазі, якщо в цьому випадку попереднє твердження було б точним?
Томас Стрінгер

1
@onedaywhen: Різниця стає тим, що ви дивитесь на різні типи як на дані або як на статичні набори значень, які ніколи не зміняться. Якщо ви використовуєте таблицю типів, ви можете просто додати інший тип до таблиці без необхідності зміни правил бізнесу в базі даних та в додатку.
Гуффа

1
@ MichaelKjörling: Правильно, якби це був лише ключ. Але ОП має намір це означати щось на кшталт "v" або "s". Зауважте, ми не займаємося тим, що описує і заповнює природні ключі, такі як коди валют (EUR, USD, GBP, CHF тощо).
gbn

3

Так само як доповнення до великого відповіді gbn .

Можливо, ви могли б створити щось подібне:

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стовпця ви можете за бажанням використовувати свої char коди, тому він стане документально зафіксованим у базі даних (і ви можете витягти інформацію про код безпосередньо з БД, без згорткового перетворення коду програми для системної інтеграції).


Ви маєте на увазі дозволити nullкод?
Джек Дуглас

Так, код необов’язковий, щоб дозволити представляти тип транспортного засобу, який ще не кодифікований.
Fabricio Araujo

Чому люди люблять залишати коментарі? Це досить дратує
Fabricio Araujo

@FabricioAraujo - Якщо коментар застарілий (наприклад, "Я відредагую це у своїй відповіді", а потім ви це зробите), тоді добре очистити коментарі, які більше не застосовуються.
Нік Чаммас

1
Я б запропонував додати в таблицю типів тип "Некласифікований" і внести значення за замовчуванням для вашого поля VehTypeId, яке некласифіковане, а не допустити нульове значення в полі іноземного ключа. Взагалі погана практика робити так, щоб "null" мав дійсне ділове значення.
Майкл Блекберн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.