Нормалізація: Чи вважається вона сумісною для розбиття статичних числових значень, як рік, у власну таблицю?


16

У мене цікава дискусія з іншим дизайнером баз даних щодо нормалізації. У цьому прикладі у нас є таблиця GameTitles, і кожен запис повинен містити рік виходу гри. Він каже, що 2NF передбачає, що все повинно бути нормалізовано, тож, щоб бути сумісним, поле року має бути розділене на таблицю ReleaseYears з власним первинним ключем, на який посилається таблиця GameTitles. Я кажу, що він повинен залишатися як поле у ​​самій таблиці GameTitles.

Мій аргумент для цього полягає в тому, що рік - це просто не примітивне числове значення, яке є статичним за своєю суттю (тобто 2011 завжди буде 2011). Завдяки цьому він служить власним ідентифікатором і не потребує нічого для його посилання, оскільки він є таким, яким він є. Це також вводить додаткове обслуговування, оскільки тепер вам доведеться додати новий рік до таблиці лише для посилання на нього. Якщо ви препулюєте таблицю з великим діапазоном років, то у вас є додаткові записи, які потенційно взагалі не матимуть посилань на них. Це також збільшує розмір бази даних, оскільки тепер у вас є додаткова таблиця, накладні витрати та додатковий первинний ключ для самого року. Якщо ви збережете рік як поле в таблиці GameTitles, ви усунете все це додаткове обслуговування та накладні витрати.

Думки про це?

редагувати: мав на увазі розмістити це в StackOverflow. Чи може хтось проголосувати, щоб видалити це чи позначити це увагою?


6
Чому так? мабуть, тут добре підійде.
Лей Ріффелл

Питання, яке я хочу задати - це ви ставите питанням про нормалізацію чи фактичні потреби виробництва? Для виробництва я б запитав, чи дійсно це робити?
jcolebrand

Відповіді:


14

Інший дизайнер баз даних просто помиляється, але і ваші міркування неправильні. Припустимо, ви починаєте з цієї таблиці, в якій є єдиний кандидатський ключ, "game_title".

Table: game_titles

game_title                      year_first_released
--
The first game                  1998
The second game                 1999
Best game: the third one        2001
The fourth game                 2003
Forty-two, the end of games     2011

Ви оцінюєте, чи є вона в 2NF, задаючи собі ці питання.

Q: Перш за все, це в 1NF?

Відповідь: Так.

Питання: Які основні атрибути (атрибути, що входять до складу ключа-кандидата)?

A: "game_title" - єдиний головний атрибут.

З: Що таке непрості атрибути?

A: "year_first_released" - єдиний.

З: Чи функціонально "year_first_released" функціонально залежить від усього "game_title" чи лише від його частини?

A: Єдиний ключ-кандидат, "game_title", - це один стовпець; він навіть не має частин. Тож "year_first_released" функціонально залежить від усієї "game_title".

Voilà. Ви знайшли 2NF.

Ви можете вирізати деякі формальні терміни, запитавши спочатку, чи є це в 1NF, а потім відповівши на це питання.

З: Чи є складені ключі-кандидати?

A: Ні.

Voilà. Ви знову знайшли 2NF.

За визначенням, щоб таблиця порушувала 2NF, вона повинна мати принаймні один ключ-кандидат, який містить більше одного стовпця.

Ось ваші причини відхилення думки вашого друга.

  • Рік - це просто непомітивне числове значення.
  • Рік статичний за своєю суттю.
  • Рік виступає як власний ідентифікатор.
  • Таблиця років вводить додаткове обслуговування.
  • У таблиці років можуть бути додаткові рядки, на які не посилаються.
  • Таблиця років збільшує розмір бази даних.

Жодна з цих причин взагалі не має нічого спільного з тим, чи є таблиця в 2NF.

Розробляючи базу даних, помилково враховувати проблеми обслуговування, розмір бази даних, нерозділені рядки, обмеження діапазону тощо. Це неправильно називати нормалізацією речей.

О, і та таблиця з двома стовпцями, яку я наводила вище - це в 5NF.


2
Чудово зроблено. Мене спокусило опублікувати відповідь, яка не сказала нічого, крім вашого першого пропозиції ... "Інший дизайнер баз даних просто не так", ви дуже добре висвітлили причину.
Марк Сторі-Сміт

5

Створення окремої таблиці для будь-якого атрибута не має нічого спільного з нормалізацією. 2NF, 3NF, BCNF, 4NF, 5NF стосуються усунення не ключових залежностей. Якщо ви видалите будь-який єдиний атрибут до нової таблиці та заміните її на атрибут іноземного ключа, то залежності в таблиці логічно будуть такими ж, як і раніше - тому переглянута версія таблиці не буде більш-менш нормалізованою, ніж вона був раніше.


Я хочу до цього щось додати , але не впевнений, що. Ви говорите, що переміщення чогось до таблиці, яка має співвідношення 1: 1 (або 1 ключ до точно 1 значення, як у цьому випадку, або один рядок до одного рядка), не дає користі, якщо пошук не потрібен, правда? Але є потенційна користь пошуку, якщо вам рідко потрібен рік, і ви дивитесь лише на діапазон 255 років або менше. Тут ви могли б піти з кількома збереженими байтами, але, як правило, вони виділяються в 4 байти все одно, це не є розумним припущенням.
jcolebrand

1
@jcolebrand: Погоджуйся з тим, що ти кажеш. Але відповідь на питання однакова: чи ти це робиш, чи ні, не має нічого спільного з нормалізацією як такої.
nvogel

Я згоден. Як я вже говорив, мій був напівсерйозним: "Я відчуваю, що в ОП тут щось не вистачає" ... тому що я не впевнений, куди йти з цією концепцією.
jcolebrand

5

З моєї точки зору, окрема таблиця року матиме сенс лише в тому випадку, якщо "рік випуску" не є календарним роком, а, наприклад, фінансовим роком, який може тривати кілька календарних років (наприклад, з жовтня по жовтень).

Тоді ця таблиця міститиме визначення (реальної дати початку та закінчення) фінансового року


1
+1 вам потрібна таблиця, лише якщо у неї будуть атрибути :)
Джек каже спробувати topanswers.xyz

2

З http://en.wikipedia.org/wiki/Second_normal_form :

Таблиця 1NF знаходиться в 2NF, якщо і лише тоді, якщо, враховуючи будь-який кандидатський ключ K та будь-який атрибут A, який не є складовою ключового ключа, A залежить від усього K, а не лише від його частини.

Ви не вказали, рік є частиною ключового кандидата чи ні, але я не впевнений, що це має значення, оскільки в будь-якому випадку 2NF буде задоволений, що стосується року.

На практичному рівні це погана ідея розділити рік з усіх перерахованих вами причин.


2

Мені не подобається аргумент проти окремої таблиці через її розмір або через те, що у неї будуть невикористані рядки. Навіть якщо ви помістите 1000 років у цю таблицю, розмір буде незначним.

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

Аргумент може бути різним для календарної таблиці, де кожен рядок являє собою день і може мати інші атрибути (день тижня, зміщення UTC, чи це свято тощо).

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

WHERE othertable.year = 2011

Замість

WHERE dt >= 20110101 AND dt < 20120101

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


1

Я повністю погоджуюся з відповіддю Catcall, за винятком одного пункту: "рік" може бути не завжди примітивним значенням, але я думаю, що це більше концепція ділової логіки, ніж одна конструкція бази даних.

Дотримуючись тієї ж конструкції, припустимо, що роки повинні бути лише тими роками, які дозволені до випуску. Таким чином, ви не маєте справу з примітивними числовими значеннями, а скоріше з їх підмножиною, і оскільки така підмножина не має примітивної реалізації, ви повинні зробити свою власну (окрему таблицю?) Та посилатися на неї (з ФК). Таким чином, ми ще говоримо про роки, але нам потрібно керувати ними по-іншому, оскільки вони концептуально змінили своє значення. Однак вони все ще "рік випуску", але концептуально відрізняються з точки зору того, що вони означають для когось із знань про домен.

У цьому конкретному випадку я знову кажу, що відповідь Catcall правильна, але просто хотіла це вказати. (Вибачте, поки не вистачає респ. Для коментарів.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.