wiki:Normalization

Version 11 (modified by 215010, 2 days ago) ( diff )

--

Определување функционални зависности

R = {user_id, first_name, last_name, phone, email, password, reservation_id, start_date, end_date, reserv_date, status, building_id, address, city, floors, num_rooms, room_number, room_type, number_of_beds, price_per_night, available, service_id, service_type, service_date, service_status, p_id, p_method, amount, p_date}

Функционални зависности

  • user_id → first_name, last_name, phone, email, password. (FD1)
  • customer_id → first_name, last_name, phone, email, password. (FD1a; исто како user_id)
  • staff_id → first_name, last_name, phone, email, password. (FD1b)
  • manager_id → first_name, last_name, phone, email, password. (FD1c)
  • building_id → address, city, floors, num_rooms, manager_id. (FD2)
  • (building_id, room_number) → room_type, number_of_beds, price_per_night, available. (FD3)
  • reservation_id → start_date, end_date, reserv_date, status, room_number, building_id, customer_id, manager_id. (FD4)
  • p_id → p_method, amount, p_date, reservation_id, customer_id. (FD5)
  • service_id → service_type, service_date, service_status, room_number, building_id, staff_id. (FD6)
  • staff_id → staff_building_id. (FD7) (секој ред на персоналот ја чува зградата каде што работи тој персонал)

(За јасност, атрибутите customer_id, manager_id, staff_id се сите user_id само поделени според класификацијата на различните видови на корисници на апликацијата (нивната улога е определена според user_id - бројот)

Класификација на атрибути

Лево – атрибути кои одредуваат други
user_id, building_id, (building_id, room_number), reservation_id, service_id, p_id

Лево и десно – атрибути кои се и детерминанти и зависни
room_number (во комбинација со building_id)

Десно – атрибути кои се само зависни
first_name, last_name, phone, email, password, address, city, floors, num_rooms, room_type, number_of_beds, price_per_night, available, start_date, end_date, reserv_date, status, p_method, amount, p_date, service_type, service_date, service_status

Покривачи на примарни клучеви

User user_id+ = {user_id, first_name, last_name, phone, email, password}

Hotel Building building_id+ = {building_id, address, city, floors, num_rooms}

Room (building_id, room_number)+ = {room_number, building_id, room_type, number_of_beds, price_per_night, available, address, city, floors, num_rooms}

Reservation reservation_id+ = {reservation_id, start_date, end_date, reserv_date, status, user_id (customer), manager_id, room_number, building_id}

Payment p_id+ = {p_id, p_method, amount, p_date, reservation_id, customer_id}

Service service_id+ = {service_id, service_type, service_date, service_status, staff_id, room_number, building_id}

Анализа според покривачи

Гледајќи ги функционалните зависности и врски, кандидатскиот примарен клуч за целата релација R може да се заклучи како:

{user_id, building_id, room_number, reservation_id, p_id, service_id}

  • user_id е потребен за да се утврдат атрибутите на корисникот.
  • building_id + room_number е потребен за да се утврдат атрибутите на собата.
  • reservation_id е потребен за да се утврдат атрибутите на резервацијата (и преку резервација → соба може да се утврди соба/зграда, но атрибутите на собата постојат и надвор од резервациите).
  • p_id е потребен за атрибути на плаќање (ниту еден друг FD не го одредува p_id).
  • service_id е потребен за атрибути на услугата.

Дали некои атрибути може да се отстранат поради транзитивност? На пример, reservation_id → (room_number, building_id), па во принцип ако reservation_id постои за сите соби, тогаш reservation_id може да го замени (building_id, room_number). Но, собите постојат независно од резервациите, па затоа не можете да се потпрете на reservation_id за уникатно да ги одредите атрибутите на собата за сите соби. Бидејќи глобалната релација вклучува редови за соби кои не се поврзани со ниедна резервација, клучот-кандидат мора да го вклучува композитниот дел од собата. Затоа е потребен целиот сет на ПК-ви на ентитетите.

Анализа на нормални форми

1 НФ

Услов за 1NF: вредности на атомски атрибути (без низи / вгнездени релации).

Нема повторувачки групи или низи, значи R е во 1NF.

2NF (отстранување на делумни зависности)

2NF тест: ако релацијата има композитен кандидатски клуч, секој не-примарен атрибут мора да зависи од целиот клуч, а не од дел.

Бидејќи започнавме од голем композитен суперклуч K, многу FD како user_id -> first_name се делумни зависности во однос на тој суперклуч. Стандардниот пристап е да се извлечат детерминантите и нивните зависни во нивните сопствени релации. Овој чекор обично ги дава табелите со природни ентитети.

Декомпозиции (за отстранување на делумни зависности):

Ги извлекуваме детерминантите и нивните зависни во посебни релации:

Users

R1: Users(user_id, first_name, last_name, phone, email, password)

FDs во R1: user_id -> first_name, last_name, phone, email, password

PK: user_id

R1 е во BCNF.

Hotel_Building

R2: Hotel_Building(building_id, address, city, floors, num_rooms, manager_id)

FDs во R2: building_id -> address, city, floors, num_rooms, manager_id

PK: building_id

R2 е во BCNF.

Room

R3: Room(room_number, building_id, room_type, number_of_beds, price_per_night, available)

PK: (room_number, building_id)

FDs: (room_number, building_id) -> room_type, number_of_beds, price_per_night, available

R3 е во BCNF.

Staff

R4: Staff(user_id /*staff_id*/, building_id)

FDs: staff_id -> building_id

PK: user_id (staff_id)

R4 е во BCNF.

Reservation

R5: Reservation(reservation_id, start_date, end_date, reserv_date, status, room_number, building_id, customer_id, manager_id)

FDs: reservation_id -> start_date, end_date, reserv_date, status, room_number, building_id, customer_id, manager_id

PK: reservation_id

R5 е во BCNF.

Service

R6: Service(service_id, service_type, service_date, service_status, room_number, building_id, staff_id)

FDs: service_id -> service_type, service_date, service_status, room_number, building_id, staff_id

PK: service_id

R6 е во BCNF.

Payment

R7: Payment(reservation_id PK, p_id UNIQUE, p_method, amount, p_date, customer_id)

FD: reservation_id -> p_id, p_method, amount, p_date, customer_id (1:1 means reservation determines payment)

PK: reservation_id

R7 е во BCNF.

По извлекувањето на овие релации, сите делумни зависности во однос на големиот суперклуч се отстрануваат - атрибутите што не се клуч на секоја релација сега целосно зависат од клучот на таа релација. Значи, сме во 2NF.

3NF (отстранување на транзитивни зависности) преку 3NF Синтеза

Цел на 3NF: елиминирање на транзитивни зависности (не клучен атрибут кој зависи од друг не клучен атрибут). Канонскиот алгоритам за синтеза на 3NF е најдобар бидејќи ги зачувува зависностите.

Имплементирана постапка:

Пресметај канонична покриеност Fc на FDs. За секоја лева страна X соберете ги сите атрибути A т.е. X -> A во една релација R_X.

Креирај релации за секоја детерминанта:

Users(user_id, first_name, last_name, phone, email, password) — oд user_id FDs.

Hotel_Building(building_id, address, city, floors, num_rooms, manager_id) — oд building_id.

Room(room_number, building_id, room_type, number_of_beds, price_per_night, available) — од (room_number, building_id).

Staff(user_id, building_id) — од staff_id.

Reservation(reservation_id, start_date, end_date, reserv_date, status, room_number, building_id, customer_id, manager_id) — од reservation_id.

Service(service_id, service_type, service_date, service_status, room_number, building_id, staff_id) — од service_id.

Payment(reservation_id, p_id, p_method, amount, p_date, customer_id) — од reservation_id (1:1).

Се осигуруваме дека релацијата содржи клуч за оригиналниот R (имаме многу клучеви, но унијата на креирани релации ги вклучува сите детерминанти и со тоа ги зачувува клучевите).

3NF статус: секоја FD X -> A во Fc е локален на една од креираните релации (зачувување на зависноста). Бидејќи ги отстранивме атрибутите што предизвикуваа транзитивни ФЗ од нивните релации што содржат (на пр., не го задржавме price_per_night во Reservation), нема преостанати транзитивни зависности во релациите. Значи, сите релации се во 3NF.

BCNF правило: за секој FD X -> A во релацијата Ri, X мора да биде суперклуч на Ri.

Ја проверуваме секоја релација произведена во 3NF:

Users(user_id, ...) — FD лево од user_id е PK ⇒ BCNF.

Hotel_Building(building_id, ...) — building_id е PK ⇒ BCNF.

Room(room_number, building_id, ...) — (room_number, building_id) е сложен PK ⇒ BCNF.

Staff(user_id, building_id) — user_id е PK ⇒ BCNF.

Reservation(reservation_id, ...) — reservation_id е PK ⇒ BCNF.

Service(service_id, ...) — service_id е PK ⇒ BCNF.

Payment(reservation_id PK, ...) — reservation_id е PK ⇒ BCNF.

Бидејќи секоја детерминанта во секоја релација е примарен клуч на релацијата (или суперклуч), секоја релација е во BCNF под овие избори на клучеви.

Забелешка (компромис): BCNF декомпозицијата понекогаш може да ве принуди да изберете клуч кој не е најзгоден (на пр., ако Payment го воспостави p_id како PK, но reservation_id -> p_id постои, Payment би го прекршил BCNF — решивме со тоа што reservation_id го направивме PK за да го задоволиме BCNF без понатамошно декомпозиција). Ако претпочитате p_id како PK за да дозволите повеќекратни плаќања по резервација (1:N), тогаш p_id би бил детерминанта во Payment, а BCNF исто така важи.

Note: See TracWiki for help on using the wiki.