Припустимо, у мене є 4 типи послуг, які я пропоную (навряд чи вони часто змінюються):
- Тестування
- Дизайн
- Програмування
- Інший
Припустимо, у мене є 60-80 реальних послуг, які належать до однієї з вищевказаних категорій. Наприклад, "послуга" може бути "Програма тестування з використанням техніки А", і вона має тип "Тестування".
Я хочу закодувати їх у базу даних. Я придумав кілька варіантів:
Варіант 0:
Використовуйте VARCHAR
безпосередньо для кодування типу послуги безпосередньо у вигляді рядка
Варіант 1:
Використовуйте базу даних enum
. Але, перерахування - це зло
Варіант 2:
використовувати дві таблиці:
service_line_item (id, service_type_id INT, description VARCHAR);
service_type (id, service_type VARCHAR);
Я навіть можу насолоджуватися референтною цілісністю:
ALTER service_line_item
ADD FOREIGN KEY (service_type_id) REFERENCES service_type (id);
Звучить добре, так?
Але мені все ж доводиться кодувати речі та мати справу з цілими числами, тобто під час заповнення таблиці. Або я повинен створити складне програмування або конструкції БД під час заселення або роботи з таблицею. А саме, ПРИЄДНАЙТЕСЯ, коли маєш справу з базою даних безпосередньо або створюєш нові об'єктно-орієнтовані об'єкти на стороні програмування, і переконайтесь, що я правильно ними керую.
Варіант 3:
Не використовуйте enum
, не використовуйте дві таблиці, а просто використовуйте цілий стовпець
service_line_item (
id,
service_type INT, -- use 0, 1, 2, 3 (for service types)
description VARCHAR
);
Це як "фальшивий перелік", який вимагає більше накладних витрат на кодову сторону речей, наприклад, тобто знаючи це {2 == 'Programming'}
та погоджуючись з цим.
Питання:
В даний час я реалізував його, використовуючи Варіант 2 , керуючись концепціями
- не використовувати enum (варіант 1)
- уникайте використання бази даних як електронної таблиці (варіант 0)
Але я не можу не відчути, що мені здається марнотратним з точки зору програмування та когнітивних витрат - я маю знати про дві таблиці і мати справу з двома таблицями проти однієї.
На "менш марнотратний спосіб" я дивлюся Option 3
. ІТ легше і вимагає по суті однакових конструкцій коду для роботи (з незначними модифікаціями, але складність і структура в основному однакові, але з єдиною таблицею)
Я думаю, в ідеалі це не завжди марно, і є хороші випадки для будь-якого варіанту, але чи є хороший настанов щодо того, коли слід використовувати Варіант 2 та коли Варіант 3?
Якщо існує лише два типи (двійкові)
Щоб додати ще трохи до цього питання ... у тому ж місці розташування у мене є бінарний варіант служби "Стандарт" або "Виняток", який може застосовуватися до рядка служби обслуговування. Я це закодував, використовуючи Варіант 3 .
Я вирішив не створювати нову таблицю просто для зберігання значень {"Стандарт", "Виняток"}. Отже, мій стовпець просто містить {0, 1}, і назва мого стовпчика називається exception
, і мій код робить переклад з {0, 1} => {STANDARD, EXCEPTION}
(який я кодував як константи в мові програмування)
Поки що це так не подобається ..... (не подобається варіант 2, ні варіант 3). Я знаходжу варіант 2 вище 3, але з більшою накладною витратою, і все ще не можу уникнути кодування речей як цілих чисел, незалежно від того, який варіант я використовую з 2 та 3.
ОРМ
Щоб додати деякий контекст, прочитавши відповіді - я тільки що знову почав використовувати ORM (нещодавно), в моєму випадку Доктрина 2. Після визначення схеми БД через Анотації я хотів заповнити базу даних. Оскільки весь мій набір даних порівняно малий, я хотів спробувати використовувати конструктивні програми, щоб побачити, як це працює.
Я спочатку заповнював service_type
s, а потім service_line_item
s, оскільки існував список із фактичної електронної таблиці. Таким чином, такі як "стандарт / виняток" та "Тестування" - це всі рядки на електронній таблиці, і їх потрібно закодувати у належні типи, перш ніж зберігати їх у БД.
Я знайшов цю ТАКУ відповідь: Що ви використовуєте замість ENUM у doctrine2? , який запропонував не використовувати конструкцію enum DB, а використовувати INT
поле та кодувати типи, використовуючи конструкцію 'const' мови програмування.
Але, як зазначено у вищезазначеному питанні, я можу уникати прямого використання цілих чисел та використовувати мовні конструкції - константи - після їх визначення ....
Але все ж .... як би ви не повернули, якщо я починаю з string
типу, я повинен спершу перетворити його у належний тип, навіть коли використовую ORM.
Тож якщо скажіть $str = 'Testing';
, мені все одно потрібно десь мати блок, який робить щось на кшталт:
switch($str):
{
case 'Testing': $type = MyEntity::TESTING; break;
case 'Other': $type = MyEntity::OTHER; break;
}
Хороша річ, що ви не маєте справу з цілими чи магічними числами [натомість, маючи справу з кодованими постійними величинами], але погано - ви не можете автоматично магічно витягувати речі з бази даних без цього кроку перетворення на мій знання.
І саме це я мав на увазі частково, кажучи про такі речі, як "все-таки треба кодувати речі та мати справу з цілими числами". (Зрозуміло, зараз, після коментаря Окрамія, мені не доведеться мати справу з цілими числами, а мати справу з названими константами та деяким перетворенням на константи / з необхідності).