Changes between Initial Version and Version 1 of Normalization


Ignore:
Timestamp:
09/15/25 12:11:31 (5 days ago)
Author:
223075
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v1 v1  
     1= Нормализација =
     2
     3Цел:
     4Да се прикаже процесот на нормализација на базата BlissCore (јога часови, настани, пакети, мерч опрема) со проверка на 1NF, 2NF, фокус на 3NF и BCNF. На крај се наведени финалните релации и применетите ограничувања (UNIQUE, CHECK) и индекси за перформанси.
     5
     6== Поддомени и почетни (денормализирани) релации ==
     7За потребите на нормализација се издвоени најбитните поддомени:
     8
     9Евиденција за часови и резервации
     10R₁ = {class_id, date, start_time, end_time, location, capacity, seats_available, instructor_id, instructor_email, training_id, training_name, user_id, username, email}
     11Интуитивни зависности:
     12
     13class_id → date, start_time, end_time, location, capacity, seats_available, instructor_id
     14
     15instructor_id → instructor_email
     16
     17training_id → training_name
     18
     19user_id → username, email
     20
     21Евиденција за настани и пријави
     22R₂ = {event_id, event_name, date, time, location, user_id, email}
     23
     24event_id → event_name, date, time, location
     25
     26user_id → email
     27
     28Евиденција за пакети и купувања
     29R₃ = {package_id, package_name, price, num_classes, user_id, email}
     30
     31package_id → package_name, price, num_classes
     32
     33user_id → email
     34
     35Евиденција за мерч и купувања
     36R₄ = {merch_id, item_name, price, user_id, email}
     37
     38merch_id → item_name, price
     39
     40user_id → email
     41
     42Сите атрибути се атомски → 1НФ е задоволена.
     43
     44== 2NF и 3NF / BCNF (декомпозиција) ==
     45
     46Проблемите во R₁…R₄ се транзитивни зависности (пример: instructor_id → instructor_email, training_id → training_name, user_id → email) и мешање на фактите од различни ентитети во иста релација. Заради тоа се врши декомпозиција до 3НФ/BCNF.
     47
     48=== R₁ (Часови и резервации) ===
     49
     50Клучеви по домен: class_id (за клас), instructor_id (за инструктор), training_id (за тренинг), user_id (за корисник).
     51
     52Транзитивни зависности:
     53
     54class_id → instructor_id и instructor_id → instructor_email
     55
     56class_id → … и training_id → training_name
     57
     58user_id → email
     59
     60Декомпозиција (BCNF):
     61
     62Class(class_id, date, start_time, end_time, location, capacity, seats_available, instructor_id)
     63
     64Instructor(instructor_id, instructor_email, …)
     65
     66Training(training_id, training_name, …)
     67
     68User(user_id, username, email, …)
     69
     70Class_Has_Training(class_id, training_id) (M:N ако клас има повеќе тренинзи)
     71
     72User_Booked_Class(user_id, class_id) (резервации)
     73
     74Сите транзитивни зависности се извадени во посебни релации → 3НФ / BCNF.
     75
     76=== R₂ (Настани и пријави) ===
     77
     78event_id → event_name, date, time, location
     79
     80user_id → email
     81
     82Декомпозиција (BCNF):
     83
     84Event(event_id, event_name, date, time, location)
     85
     86User_Event(user_id, event_id) (пријави на корисник на настан)
     87
     88=== R₃ (Пакети и купувања) ===
     89
     90package_id → package_name, price, num_classes
     91
     92user_id → email
     93
     94Декомпозиција (BCNF):
     95
     96Package(package_id, package_name, price, num_classes)
     97
     98User_Purchased_Package(user_id, package_id)
     99
     100=== R₄ (Мерч и купувања) ===
     101
     102merch_id → item_name, price
     103
     104user_id → email
     105
     106Декомпозиција (BCNF):
     107
     108Merch_Items(merch_id, item_name, price, …)
     109
     110User_Purchased_Merch(user_id, merch_id)
     111
     112=== Дополнително (пакети што вклучуваат часови) ===
     113
     114Package_Includes_Class(package_id, class_id) (M:N врска)
     115
     116== Финални релации (сите во 3НФ / BCNF) ==
     117
     118User(user_id, username, email, password_hash, …)
     119
     120Instructor(instructor_id, instructor_email, …)
     121
     122Training(training_id, training_name, …)
     123
     124Class(class_id, date, start_time, end_time, location, capacity, seats_available, instructor_id)
     125
     126Event(event_id, event_name, date, time, location)
     127
     128Package(package_id, package_name, price, num_classes)
     129
     130Merch_Items(merch_id, item_name, price, …)
     131
     132Мостови (M:N):
     133
     134Class_Has_Training(class_id, training_id)
     135
     136User_Booked_Class(user_id, class_id)
     137
     138User_Event(user_id, event_id)
     139
     140User_Purchased_Package(user_id, package_id)
     141
     142User_Purchased_Merch(user_id, merch_id)
     143
     144Package_Includes_Class(package_id, class_id)
     145
     146Секоја релација има примарен клуч; странските клучеви ги поврзуваат ентитетите и мостовите.
     147
     148== Интегритетни ограничувања (UNIQUE, CHECK) ==
     149За да спречиме аномалии и дупликати, додадовме:
     150
     151{{{
     152#!sql
     153-- UNIQUE: деловни правила
     154ALTER TABLE "User" ADD CONSTRAINT uq_user_email UNIQUE (email);
     155ALTER TABLE "User" ADD CONSTRAINT uq_user_username UNIQUE (username);
     156ALTER TABLE "Instructor" ADD CONSTRAINT uq_instr_email UNIQUE (instructor_email);
     157ALTER TABLE "Training" ADD CONSTRAINT uq_training_name UNIQUE (training_name);
     158ALTER TABLE "Package" ADD CONSTRAINT uq_package_name UNIQUE (package_name);
     159ALTER TABLE "Merch_Items" ADD CONSTRAINT uq_merch_item UNIQUE (item_name);
     160
     161-- "Slot" уникатност: спречува дупликат термини/локации
     162ALTER TABLE "Class"
     163ADD CONSTRAINT uq_class_slot UNIQUE (date, start_time, location, instructor_id);
     164ALTER TABLE "Event"
     165ADD CONSTRAINT uq_event_slot UNIQUE (event_name, date, time, location);
     166
     167-- CHECK: едноставни бизнис правила
     168ALTER TABLE "Class"
     169ADD CONSTRAINT ck_class_time_order CHECK (end_time > start_time),
     170ADD CONSTRAINT ck_class_capacity_nonneg CHECK (capacity IS NULL OR capacity >= 0),
     171ADD CONSTRAINT ck_seats_not_overflow CHECK (seats_available IS NULL OR capacity IS NULL OR seats_available <= capacity),
     172ADD CONSTRAINT ck_seats_nonneg CHECK (seats_available IS NULL OR seats_available >= 0);
     173
     174ALTER TABLE "Package"
     175ADD CONSTRAINT ck_package_price_pos CHECK (price > 0),
     176ADD CONSTRAINT ck_package_num_pos CHECK (num_classes > 0);
     177
     178ALTER TABLE "Merch_Items"
     179ADD CONSTRAINT ck_merch_price_pos CHECK (price > 0);
     180}}}
     181
     182Забелешка: при обид за дупликат UNIQUE, PostgreSQL враќа грешка 23505 (unique violation) – тоа во апликацијата го прикажуваме како “Email already taken”, итн.
     183
     184== Индекси за перформанси ==
     185
     186Индекси на мостови (по „другата“ страна од PK, за побрзи филтри):
     187{{{
     188#!sql
     189CREATE INDEX IF NOT EXISTS idx_ubc_class ON "User_Booked_Class"(class_id);
     190CREATE INDEX IF NOT EXISTS idx_cht_training ON "Class_Has_Training"(training_id);
     191CREATE INDEX IF NOT EXISTS idx_ue_event ON "User_Event"(event_id);
     192CREATE INDEX IF NOT EXISTS idx_upp_package ON "User_Purchased_Package"(package_id);
     193CREATE INDEX IF NOT EXISTS idx_upm_merch ON "User_Purchased_Merch"(merch_id);
     194CREATE INDEX IF NOT EXISTS idx_pic_class ON "Package_Includes_Class"(class_id);
     195}}}
     196
     197Индекси за честите листања:
     198{{{
     199#!sql
     200CREATE INDEX IF NOT EXISTS idx_event_date_time ON "Event"(date, time);
     201CREATE INDEX IF NOT EXISTS idx_class_date_time ON "Class"(date, start_time);
     202}}}
     203
     204== Заклучок ==
     205Со декомпозиција по ентитети и мостови ги елиминиравме транзитивните зависности и постигнавме 3NФ/BCNF. UNIQUE/CHECK ограничувањата ги зацврстуваат бизнис правилата, а индексирањето ги забрзува најчестите барања (листaње часови/настани и повратни врски преку мостовите).
     206
     207==============================