C, PHP, VB, .NET

Дневникът на Филип Петров


* Нормализация на бази от данни – докъде?

Публикувано на 20 май 2009 в раздел Бази от Данни.

Нормализацията на бази от данни е една изключително важна тема, която обаче е по-теоретично насочена и поради тази причина не наблягахме досега на нея. Текстът по-долу е реферат на студента Никола Костадинов Симеонов, който смятам, че много добре описва темата „нормализация на бази от данни“…

тема:

До къде може да стигнем с номализацията?

Никола Костадинов Симеонов, ТУ-София, ФКСУ, гр. 57

Нормализацията е един от основновните процеси при проектиране на бази данни. Най общо казано нормализацията премахва повтаряемостта и минимизира излишъка от данни. Резултатът е по добра организация,по добра използваемост на паммета и премахване на аномалиите в базата данни. Нормализацията не винаги е най-доброто решение за дадена база данни, например при data Warehouse бази данни се прилага съвсем различен подход(използват се силно денормализирани бази данни). Или иначе казано сляпото прилагане на всички нормални форми може да доведе до катастрофални последици-изключително голям брой таблици,сложни заявки за сливане и най-важното много лоша производителност. Това в крайна сметка може да направи базата данни неизползваема. Така стигаме до въпроса как да намерим баланса?Да избегнем аномалиите и да и във същото време да запазим високата производителност и време за отговор на базата данни.

В този реферат ще се опитам да дам отгоровор на тези въпроси, също така ще разгледам какво точно се прави след 3-та нормална форма ,защо се прави и в кои случаи не е препоръчително да се прави. Най-накрая ще се опитам да обобщя личната ми позиция по тази много важна тема защото тя има важно място в цялостния процес на разробтка на софтуер. Отделянето на достатъчно време за доброто проектиране на базата данни още от началото ще спести много проблеми и усилия по нататък.

Първо нека накратко разгледаме нормалите форми и как се прилагат.

1НФ: Една таблица е в първа нормална форма, тогава и само тогава, когато не съдържа повтарящи се атрибути или групи от атрибути.

2НФ: Таблицата трябва да е в 1НФ и всички неключови стойности трябва да са напълно функционално зависими от първичния ключ. Не са позволени частични зависимости.

3НФ: Премахват се непреките зависимости. Това са полетата които са непряко зависими от първични ключ. Например поле е фунцкционално зависимо на друго поле, а то от своя страна е зависимо от първичния ключ.

Boyce-codd Normal Form (BCNF): Всяка детерминанта трябва да бъде кандидат ключ. Детерминант е произволно поле от което са напълно функционално зависими други полета. Ако съществува един единствен кандидат ключ 3НФ и BCNF са едно и също.

4НФ: Трябва да се премахнат многостойностните зависимости.

5НФ: Трябва да се премахнат цикличните зависимости

Domain key Normal Form (DKNF): Тази форма е по скоро определение на това как трябва да излегжда нормализирана до съвършенство база данни.

  • Не трябва да съществуват аномалии при записване, обновяване или триене на данни. Иначе казано всеки запис трябва да бъде директно достъпен по всякакъв начин така че да не възникват грешки;
  • Всеки запис във всяка таблица трябва да бъде уникално идентифициран и свързан с първичния ключ в своята таблица. Това означава че всяко поле трябва да е пряко определено от пърчвичния ключ;
  • Всички проверки за типа на данните се извършват в самата база данни(Като се има предвид производителноста това е крайно нежелателно в комерсиална работна среда. По-добър подход би бил  да се раздели функционалността между базата данни и приложението).

Несъмнено прилагането на първите две форми, като създаване на разширяващи(master-detail връзки) в 1НФ и Отделяне на статичните данни в 2НФ е необходимо. Не само че помага за избягване на аномалите те са необходими за да съществува релационния модел. Прилагането на 3НФ също е доста срещано но с всяка следваща форма модела на базата става все по раздробен и броя на таблиците нараства. От там нарастват и SQL заявките за сливане и намалява производителноста.

Защо да отиваме след 3-та нормална форма?

Прилагането на първите 3 нормални форми може да се каже че елиминира 90% от аномалиите при изтриване , обновяване или въвеждане. Използването на останалите 3 се нормални форми се прилагат в някои по специфични случаи за да се „доизглади” модела.

Тук искам да дам няколко нагледни примера как се прилагат формите след 3-та и да покажа защо по мое мнение в много случаи това е излишно и е признак на следване на математическо съвършенство а не проектиране на работна база данни.

Премахване на едно към едно NULL полета

Това е често срещан подход за нормализация след 3-та НФ при който се премахват потенциално нулевите полета. Тук съм дал следния пример съществува база данни за библиотека като една от таблиците и се казва EDITION. Полетата rank и ingram_units са потенциално с нулеви стойности. Може да нормализираме модела като отделим тези полета в отделна таблица и по този начин спестим място. Създаваме новата таблица RANK с първичен ключ ISBN номера и двете потенциално нулеви полета. Връзката която се получава в този случай между RANK и EDITION таблиците е нула или едно към едно. Това означава че ако съществува RANK задължително трябва да съществува EDITION запис, обаче обратното не е задължително може да съществува издание което не е оценено и не е получило RANK.

fig11

В случая с таблицата RANK при от фиг 1.1 полетата rank и ingram_units не са зависими едно от друго и са напълно независими. Много е възможно едното от полетата да бъде нула а другото не. Ако продължим с нормализацията до крайности може да разделим таблицата на две нови както е показано на фиг 1.2. Това ниво на нормализация е доста абсурдно и отчасти безмислено. В днешно време паметта е евтина а процесорното време скъпо така че се обезсмиля разделянето на таблицата RANK.

fig1-2

Boyce-Codd Normal Form (BCNF)

Нека сега разгледаме прилагането на тази форма. При нея базата данни трябва да е вече в 3-та НФ и всяка таблица да има само по един кандидат-ключ. Кандидат ключ е поле което е възможно да се използва за първичен ключ.

От лявата страна на Фиг.2 е дадена таблица която съдържа естествени (основни) ключови полета като customer_name и address и изкуствен(допълнителн) customer_id. Допълнителния ключ customer_id е добавен защото е по ефиктивен при търсене и по лесно се обработва като цяло. От дясната страна на Фиг.2 е показана таблицата Customer разбита на отделни таблици според точното прилагане на Boyce-Codd Normal Form. Както се вижда раздробяването на таблицата customer на толкова много таблици е меко казано нецелесъобразно!

fig21

4-та Нормална Форма

При нея таблицата трябва да е в 3-та нормална форма или 3-та нормална форма с BCNF. При прилагането на 4-та нормална форма трябва да се премахнат многостойностните зависимости. Това означава че единични стойности а не съставни трябва да са зависими от първичния ключ.

Многостойностно поле е такова поле което съдържа колекция масив от стойности от някакъв тип разделени със запетаи.
Фигура 3 показва таблицата Employee с различните умения които притежават служителите и техните сертификати. Трябва да се отбележи че уменията и сертификатите не само че не са зависими едно от друго но са добавени в списък разделен със запетаи.

fig31

За да приложим 4-та нормална форма премахваме многостойностните зависимости като разделяме таблицата Employee на три таблици Employee_Skill, Employee и Employee_Certification:

fig41

Във същността си 4-та нормална форма пренася колекцията от многостойностните елементи във различни таблици и записи и така прави всеки запис по лесен за директен достъп.

5-та Нормална Форма

За да приложим 5-та нормална форма таб таблиците трябва да са вече в 4-та. При 5-та нормална форма се премахват цикличните зависимости. Циклична зависимост се получава когато едно поле зависи от друго поле а то от своя страна зависи директно или индиректно от първото поле. 5-та нормално форма се нарича още „Проекционна нормална форма”. Думата проекционна идва от това че метода създава нови таблици съдържащи подмножества от данните на оригиналната таблица. Циклична зависимост се получава когато например в съставен първичен ключ с три полета всяко от полетата е зависимо от всички други освен от себе си. В конкретния пример името на проекта е зависимо от неговия мениджър и от служителите които работят по него,същото се отнася и за останалите две полета името на служителя е зависимо от мениджъра и от проекта по който работи,за третото поле се отнася същото името на мениджъра е зависимо от проекта който ръководи и от сложителите които управлявава. Таблицата от фигура 5 с съставния ключ може да се раздели на 3 таблици кадето полета са разделени по двойки и така вече не съществува циклична зависимост в отделните таблици.

fig51

И така това са нормалните форми. В повечето случаи прилагането на формите води до определени подобрения в структурата и до избягване на аномалии но както вече няколко пъти споменах важно е да се има предвид фактора производителност и то още от самото начало на проектирането на базите данни.

Нужно да се нормализира модела след 3-та нормална форма?

В някои случаи може и да е но в голямата си част работните комерсиални бази данни не стигат дотам. Моето лично мнение е, че проектантите на бази данни не трябва да се страхуват да не използват висококо ниво на нормализация а по скоро обратното. От първостепенна важност е проектанта да може да „види” модела на базата през погледа на софтуерния разработчик и крайния потребител и точно да се определят изискванията.

За да определите нивото на нормализация е добре да си зададете следните въпроси:

1. Какъв тип е базата данни? Дали е OLTP, OLAP или warehouse?

2. Какви са по същество заявките към базата? Дали са повече за добавяне или са за извеждане?

При бази данни при които заявките са добавяне са повече от заявките за извеждане на информация е в общия случай е по добре да се използва по дълбоко ниво на нормализация и обратното ако заявките за извеждане са повече от тези да добавяне тогава може да си позволим по слаба нормализация.

Фактори които влиаят на нивото на нормализация:

Тук съм подбрал основните фактори които трябва да вземем предвид при прилагането на нормализацията.

1. Коефицентът на добавени/изведени стойности.

2. За какво се използва базата за тразнакционно записване/обработване или е система за подпомагане на избора.

3. Какво е времето за отговор от което се нуждаем при добавяне изтриване и обновяване.

4. Колко е като обем пика на зареждане на данни в базата данни за определен период от време.

5. Дали базата данни е съставена като централизирана система или е разпростряна на няколко места.

6. Как ще контролираме транзакционните процеси дали ще използваме еднофазно или многофазно потрвърждаване.

7. Дали ще се използва временно кеш съхранение на даден тип данни.
След отговора на тези въпроси ще имаме обща представа каква ще точно нашата система и много по лесно ще определим нивото на нормализация.

Каде трябва да теглим чертата?

В случая няма еднозначен отговор но в 90% от случаите това е 3НФ или 3НФ с BCNF. Един добър подход би бил да се остави до някаква степен приложението да проверява данните които се въвеждат и извежда с цел в крайна сметка да се покрият изискванията за скорост и производителност. В случаите когато ситуацията налага да се използват по дълбоки нива на нормализация тогава могат да се използват и 4-та и 5-та нормална форма само, че тогава проблема със нормализацията става много по-сложен и в повечето случаи не си заслужава да се стига до там.

Използвана литетература :

1. Beginning Database Design – Gavin Powel (Wrox, 2006),
2. Database Design Know It All – Stephen Buxton, Thomas P. Nadeau (Morgan Kaufmann Publishers,2009).
3. Beginning.Database.Design.From.Novice.to.Professional –Clare Churcher (Apress, 2007).

 



11 коментара


  1. dzver каза:

    Само да отбележа, че посочената дефиниция за 1нф е абсолютно погрешна. Това ме отказа да продължа да чета надолу.

  2. Опитал се е да го формулира, но не е успял. Една таблица е в първа нормална форма, тогава и само тогава, когато не съдържа повтарящи се атрибути или групи от атрибути. Ще го поправя, за да е честно спрямо други читатели. Мен такива неща не ме отказват да чета по-надолу.

  3. TU каза:

    В крайна сметка какъв тип нормализация трябва да се използва за изпита, защото според мен всеки я разбира по различен начин – т.е. е доста субективна?

  4. Специално за втори курс втори семестър изпитът е строго технически насочен и изисква умения за реализиране на проекти по задание. Примерни задачи има дадени колкото искате в Moodle. До теоретичната част, нейната интерпретация и приложение в практиката ще достигнете малко по-късно „като му дойде времето“. Засега просто се „трупа материал“.

  5. TU каза:

    Аз говорех за ликвидационния изпит след 2ри курс. Нормализация през семестъра на упражнения не беше предадена, а при изпита на Гоцева изигра решаващо значение. Затова питам какъв тип нормализация е предпочитан за използване? И също така искам да попитам дали и сега вариантът на изпита ще бъде непосилен за час и 30 мин. както миналите 2-а пъти?

  6. На самия изпит от теоретичната част се изискват съвсем минимално количество знания. От гледна точка на „нормализацията“ трябва просто да изнесете няколко полета в отделна таблица (или в „най-лошия“ случай в две отделни таблици). Освен това са ясно указани точно кои. Остава да се определи каква е връзката в ER диаграмата и това е всичко. За привеждане на база данни в конкретна „нормална форма“ въобще не става дума, камо ли пък да има „решаваща роля“. А всъщност дали трябва или не трябва да има – това е друга отделна тема.

    Относно въпроса по същество – очевидно има хора, които са си взели изпита съвсем успешно, следователно е бил напълно „посилен“ за тях. И да, изпитът на ликвидационната сесия ще бъде в абсолютно същия формат, както предишните два.

  7. TU каза:

    Благодаря за информацията!

  8. Radmila Yasenova каза:

    Много ми помогна Реферата.Благодаря за полезната информация.

  9. Ляля каза:

    Хубава статия и в допълнение бих добавил(може би за друга статия) е, че може да се записва на куп или на малки леки заявки което също е много спорно
    Малките заявки са леки, но пък по бавни от MULTI INSERT заявките, а пък MULTI INSERT заявките пък могат да сринат сървъра (буквално)

  10. Sams каза:

    Като че ли в таблица project_manager на фигура 5 нещо не е наред. Може би вместо employee трябва да има manager ?

  11. Като че е така.

Добави коментар

Адресът на електронната поща няма да се публикува


*