Changes between Version 6 and Version 7 of Normalization


Ignore:
Timestamp:
09/23/25 09:48:37 (6 hours ago)
Author:
223075
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v6 v7  
    147147Секоја релација има примарен клуч; странските клучеви ги поврзуваат ентитетите и мостовите.
    148148
    149 == Интегритетни ограничувања (UNIQUE, CHECK) ==
    150 За да спречиме аномалии и дупликати, додадовме:
    151 
    152 {{{
    153 #!sql
    154 -- UNIQUE: деловни правила
    155 ALTER TABLE "User" ADD CONSTRAINT uq_user_email UNIQUE (email);
    156 ALTER TABLE "User" ADD CONSTRAINT uq_user_username UNIQUE (username);
    157 ALTER TABLE "Instructor" ADD CONSTRAINT uq_instr_email UNIQUE (instructor_email);
    158 ALTER TABLE "Training" ADD CONSTRAINT uq_training_name UNIQUE (training_name);
    159 ALTER TABLE "Package" ADD CONSTRAINT uq_package_name UNIQUE (package_name);
    160 ALTER TABLE "Merch_Items" ADD CONSTRAINT uq_merch_item UNIQUE (item_name);
    161 
    162 -- "Slot" уникатност: спречува дупликат термини/локации
    163 ALTER TABLE "Class"
    164 ADD CONSTRAINT uq_class_slot UNIQUE (date, start_time, location, instructor_id);
    165 ALTER TABLE "Event"
    166 ADD CONSTRAINT uq_event_slot UNIQUE (event_name, date, time, location);
    167 
    168 -- CHECK: едноставни бизнис правила
    169 ALTER TABLE "Class"
    170 ADD CONSTRAINT ck_class_time_order CHECK (end_time > start_time),
    171 ADD CONSTRAINT ck_class_capacity_nonneg CHECK (capacity IS NULL OR capacity >= 0),
    172 ADD CONSTRAINT ck_seats_not_overflow CHECK (seats_available IS NULL OR capacity IS NULL OR seats_available <= capacity),
    173 ADD CONSTRAINT ck_seats_nonneg CHECK (seats_available IS NULL OR seats_available >= 0);
    174 
    175 ALTER TABLE "Package"
    176 ADD CONSTRAINT ck_package_price_pos CHECK (price > 0),
    177 ADD CONSTRAINT ck_package_num_pos CHECK (num_classes > 0);
    178 
    179 ALTER TABLE "Merch_Items"
    180 ADD CONSTRAINT ck_merch_price_pos CHECK (price > 0);
    181 }}}
    182 
    183 Забелешка: при обид за дупликат UNIQUE, PostgreSQL враќа грешка 23505 (unique violation) – тоа во апликацијата го прикажуваме како “Email already taken”, итн.
    184 
    185 == Индекси за перформанси ==
    186 
    187 Индекси на мостови (по „другата“ страна од PK, за побрзи филтри):
    188 {{{
    189 #!sql
    190 CREATE INDEX IF NOT EXISTS idx_ubc_class ON "User_Booked_Class"(class_id);
    191 CREATE INDEX IF NOT EXISTS idx_cht_training ON "Class_Includes_Training"(training_id);
    192 CREATE INDEX IF NOT EXISTS idx_ue_event ON "User_Event"(event_id);
    193 CREATE INDEX IF NOT EXISTS idx_upp_package ON "User_Purchased_Package"(package_id);
    194 CREATE INDEX IF NOT EXISTS idx_upm_merch ON "User_Purchased_Merch"(merch_id);
    195 CREATE INDEX IF NOT EXISTS idx_pic_class ON "Package_Includes_Class"(class_id);
    196 }}}
    197 
    198 Индекси за честите листања:
    199 {{{
    200 #!sql
    201 CREATE INDEX IF NOT EXISTS idx_event_date_time ON "Event"(date, time);
    202 CREATE INDEX IF NOT EXISTS idx_class_date_time ON "Class"(date, start_time);
    203 }}}
    204149
    205150== Заклучок ==
    206 Со декомпозиција по ентитети и мостови ги елиминиравме транзитивните зависности и постигнавме 3NФ/BCNF. UNIQUE/CHECK ограничувањата ги зацврстуваат бизнис правилата, а индексирањето ги забрзува најчестите барања (листaње часови/настани и повратни врски преку мостовите).
     151Со декомпозиција по ентитети и мостови ги елиминиравме транзитивните зависности и постигнавме 3NФ/BCNF
    207152