Changes between Version 5 and Version 6 of Normalization


Ignore:
Timestamp:
09/19/25 12:06:32 (17 hours ago)
Author:
215010
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v5 v6  
    6565=== Анализа според покривачи
    6666
    67 Од анализата се забележуваат:
    68 
    69 room_number е уникатен само во комбинација со building_id → слаб ентитет.
    70 
    71 Во Reservation нема експлицитно модел на врска со Customer, Manager и Room → треба релации за интегритет.
    72 
    73 Во Payment, amount е транзитивно зависно од Reservation (amount = цена * број на ноќи).
    74 
    75 Во Service, моментално нема детална историја (само статус).
     67Од функционалните зависности и шемата, можеме да идентификуваме дека релацијата R вклучува различни ентитети кои се поврзани преку надворешни клучеви и делумни зависности. За да го идентификуваме кандидатскиот примарен клуч за целата релација
     68R, мора да се осигураме дека: сите не-примарни атрибути се функционално зависни од кандидатскиот примарен клуч и кандидатскиот клуч мора да биде уникатен низ целата релација.
     69
     70Гледајќи ги функционалните зависности и врски, кандидатскиот примарен клуч за целата релација R може да се заклучи како:
     71
     72**{reservation_id, p_id, service_id, room_number, building_id}**
     73
     74- reservation_id: Уникатно идентификува резервација.
     75
     76- p_id: Уникатно идентификува плаќање.
     77
     78- service_id: Уникатно идентификува услуга.
     79
     80- room_number и building_id: Заедно, тие идентификуваат одредена соба во одредена зграда.
     81
     82Овој сет на атрибути треба да може уникатно да го идентификува секој запис во релацијата R, осигурувајќи дека нема редундантност и нема двосмисленост.
    7683
    7784=== Анализа на нормални форми
    7885==== 1 НФ
    7986
    80 Тековниот дизајн е во 1NF: атомски атрибути, нема повеќевредносни атрибути складирани како едно поле.
     87За да постигнеме 1NF, мора да се осигураме дека сите атрибути во секоја торка се атомски, што значи дека не постојат повеќевредносни атрибути или композитни атрибути.
     88
     89===== Проблем во тековната шема:
     90
     91Композитни атрибути како address (кои може да имаат повеќе компоненти како што се улица, град итн.).
     92
     93===== Решение:
     94
     95Разделување на повеќевредносните атрибути во посебни колони.
     96
     97===== Применето 1NF:
     98
     99Адресата во Hotel_Building треба да се подели на атомски компоненти: улица, град и поштенски код.
     100
     101Табела Hotel_Building:
     102
     103building_id, street, city, zip_code, floors, num_rooms
     104
     105Сите атрибути во секоја табела ќе бидат атомски, што значи дека нема да постојат дополнителни сложени или повеќевредносни атрибути.
    81106
    82107==== 2 НФ
    83108
    84 Нема парцијални зависности (освен кај Room, каде клуч е составен (building_id, room_number)).
     109За да постигнеме 2NF, треба да отстраниме делумни зависности. Атрибутот што не е примарен мора да биде целосно функционално зависен од целиот примарен клуч, а не само од негов дел.
     110
     111===== Проблем во тековната шема:
     112
     113Во Reservation, атрибутите како user_id, manager_id и room_number се делумно зависни само од дел од примарниот клуч (т.е. reservation_id), а не од целиот примарен клуч.
     114
     115===== Решение:
     116
     117Преместување на атрибутите што зависат од дел од примарниот клуч во посебни табели за да ги елиминирате делумните зависности.
     118
     119===== Применето 2NF:
     120
     121Креирање табела Customer со user_id како примарен клуч и атрибути поврзани со клиентот.
     122
     123Креирање табела Manager со user_id како примарен клуч и атрибути поврзани со менаџерот.
     124
     125Изменување на Reservation за да ги чува само атрибутите што зависат од reservation_id и преместување на user_id (клиент) и manager_id во нивните соодветни табели.
     126
     127По 2NF:
     128
     129Customer: user_id, first_name, last_name, phone, email, password
     130
     131Manager: user_id, first_name, last_name, phone, email, password
     132
     133Reservation: reservation_id, start_date, end_date, reserv_date, status, room_number, building_id, customer_id, manager_id
    85134
    86135==== 3 НФ
    87136
    88 Проблеми:
    89 
    90 Reservation – amount (треба да се изведува од Room.price_per_night × број на ноќи → не треба да стои во Payment како атрибут).
    91 
    92 Reservation моментално чува и customer_id, и manager_id → транзитивна зависност преку User.
    93 
    94 Подобрувања за да се задоволи 3 НФ
    95 Reservation – Order Cost
    96 
    97 Да не се чува amount во Payment, туку да се пресметува.
    98 
    99 {{{#!sql
    100 ALTER TABLE Payment DROP COLUMN amount;
    101 }}}
    102 Да се додава VIEW:
    103 {{{#!sql
    104 CREATE VIEW reservation_total AS
    105 SELECT r.reservation_id,
    106        (EXTRACT(DAY FROM r.end_date - r.start_date) * rm.price_per_night) AS total_cost
    107 FROM Reservation r
    108 JOIN Room rm ON r.room_number = rm.room_number AND r.building_id = rm.building_id;
    109 }}}
    110 Service – историја на статуси
    111 {{{#!sql
    112 CREATE TABLE service_history (
    113     history_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    114     service_id BIGINT NOT NULL,
    115     status VARCHAR(70) NOT NULL,
    116     changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    117     FOREIGN KEY (service_id) REFERENCES Service(service_id)
    118 );
    119 }}}
     137За да постигнеме 3NF, мора да ги отстраниме транзитивните зависности. Непримарниот атрибут не смее да зависи од друг непримарен атрибут.
     138
     139===== Проблеми во тековната шема:
     140
     141Во Payment, user_id индиректно одредува атрибути како first_name и last_name, создавајќи транзитивна зависност.
     142
     143===== Решение:
     144
     145Отстранување на транзитивните зависности со креирање посебни табели за User (веќе направено во 2NF) и осигурувајќи се дека секоја табела ги складира само атрибутите што директно зависат од примарниот клуч.
     146
     147===== Применето 3NF:
     148
     149Во табелата Payment, складираме само p_id, p_method, amount, p_date и reservation_id. До user_id може да се пристапи преку reservation_id, па затоа не треба да се чува во табелата Payment.
     150
     151===== По 3NF:
     152
     153Payment: p_id, p_method, amount, p_date, reservation_id
     154
    120155==== BCNF
    121 Прекршоци
    122 
    123 email во Hotel_User треба да е уникатен → веќе има UNIQUE.
    124 
    125 phone исто така треба да е уникатен (еден број = еден корисник).
    126 
    127 Во Room, комбинацијата (building_id, room_number) е единствен идентификатор.
    128 {{{#!sql
    129 ALTER TABLE Hotel_User ADD CONSTRAINT uq_phone UNIQUE(phone);
    130 
    131 ALTER TABLE Room ADD CONSTRAINT uq_room UNIQUE(building_id, room_number);
    132 }}}
     156
     157За да се постигне BCNF, мора да се осигураме дека секоја детерминанта во релацијата е клуч-кандидат, односно За секоја функционална зависност: A→B, A мора да биде клуч-кандидат.
     158
     159===== Проблем во тековната шема:
     160
     161Во табелата Service, функционалната зависност:
     162
     163service_id → service_type, service_date, service_status, staff_id, room_number, building_id
     164
     165Оваа функционална зависност покажува дека service_id ги одредува service_type, service_date и service_status, но room_number и building_id не се дел од клучот-кандидат. Така, room_number и building_id се не-примарни атрибути кои зависат од service_id, создавајќи потенцијално прекршување на BCNF.
     166
     167===== Решение за BCNF:
     168
     169
     170За да го решиме ова прекршување, треба да се осигураме дека секоја детерминанта е клуч-кандидат.
     171
     172room_number и building_id се одредени од композитниот клуч (room_number, building_id) во табелата Room, што е клуч-кандидат.
     173
     174Треба да ја отстраниме зависноста од room_number и building_id од табелата Service бидејќи овие атрибути се веќе одредени од табелата Room.
     175
     176===== По примена на BCNF:
     177
     178Табелата Service ќе ги чува само:
     179
     180service_id, service_type, service_date, service_status и staff_id.
     181
     182Табелата Room ќе продолжи да ги чува деталите поврзани со собата, вклучувајќи го room_number и building_id.
     183
     184Со ова, сите не-примарни атрибути во табелата Service зависат единствено од клучот-кандидат service_id.
     185
     186===== Конечни табели во BCNF:
     187
     188По примената на BCNF и решавањето на сите проблеми, конечната шема за засегнатите табели изгледа вака:
     189
     190Hotel_Bidling: building_id, street, city, zip_code, floors, num_rooms
     191
     192Room: room_number, building_id, room_type, number_of_beds, price_per_night, available
     193
     194Customer: user_id, first_name, last_name, phone, e-mail, password
     195
     196Manager: user_id, first_name, last_name, phone, e-mail, password
     197
     198Reservation: reservation_id, start_date, end_date, reserv_date, status, customer_id, manager_id, room_number, building_id
     199
     200Payment: p_id, p_method, amount, p_date, reservation_id
     201
     202Service: service_id, service_type, service_date, service_status, staff_id