Changes between Version 8 and Version 9 of Normalization
- Timestamp:
- 01/14/26 11:04:33 (13 days ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Normalization
v8 v9 1 = Нормализација=1 = Формална анализа и доказ за нормализација на Stock Master = 2 2 3 == Вовед == 3 == 1. Дефиниција на универзалната релација == 4 Нека '''R''' претставува универзалната шема на релацијата. Множеството на атрибути '''U''' во '''R''' е дефинирано како: 4 5 5 Целта на оваа анализа е да се прикаже процесот на нормализација за предложениот модел на базата на податоци Stock Master, од идентификација на функционалните зависиности до постигнување на BCNF (Boyce-Codd нормална форма). Анализата е изведена врз основа на ентитетите и релациите од ER моделот разработен во Фаза P2. 6 U = { user_id, username, password, full_name, email, role, is_active, created_at, 7 customer_id, c_name, c_email, c_phone, c_address, 8 category_id, cat_name, description, 9 supplier_id, s_name, contact_person, s_phone, s_email, s_address, 10 product_id, prod_name, prod_desc, sku, unit_price, reorder_level, is_active, 11 warehouse_id, w_name, location, capacity, 12 sale_id, date_time, total_amount, 13 po_id, order_date, expected_date, actual_date, status, 14 quantity, unit_cost, unit_price_at_sale, received_quantity, quantity_on_hand, last_updated } 6 15 7 == Дел 1: Нормализација == 16 == 2. Функционални зависности (Functional Dependencies - F) == 17 Врз основа на SQL ограничувањата (CONSTRAINTS) и семантиката на податоците, дефинираме го множеството на функционални зависности '''F''' како канонски покривач: 8 18 9 === Ентитет 1: USER === 19 === Примарни детерминанти (Simple Determinants) === 20 1. user_id -> username, password, full_name, email, role, is_active, created_at 21 2. customer_id -> c_name, c_email, c_phone, c_address, created_at 22 3. category_id -> cat_name, description, created_at 23 4. supplier_id -> s_name, contact_person, s_phone, s_email, s_address, created_at 24 5. product_id -> prod_name, prod_desc, sku, unit_price, reorder_level, category_id, supplier_id, is_active, created_at 25 6. warehouse_id -> w_name, location, capacity, created_at 26 7. sale_id -> date_time, total_amount, user_id, customer_id, warehouse_id 27 8. po_id -> order_date, expected_delivery_date, actual_delivery_date, status, supplier_id, warehouse_id, created_at 10 28 11 ==== Почетна релациска шема ==== 29 === Композитни детерминанти (Composite Determinants) === 30 1. {sale_id, product_id} -> quantity, unit_price_at_sale 31 2. {po_id, product_id} -> quantity, unit_cost, received_quantity 32 3. {warehouse_id, product_id} -> quantity_on_hand, last_updated 12 33 13 '''User'''(userId, username, password, full_name, email, role, is_active) 34 === Кандидат клучеви (Candidate Keys) === 35 1. username -> user_id (поради UNIQUE ограничување) 36 2. email -> user_id (поради UNIQUE ограничување) 37 3. sku -> product_id (поради UNIQUE ограничување) 14 38 15 ==== Функционални зависиности ==== 39 == 3. Класификација на атрибути == 40 Врз основа на '''F''', ги извршуваме следниве класификации: 16 41 17 '''FD1:''' userId → username, password, full_name, email, role, is_active 42 '''Лево (Детерминанти - Determinants):''' 43 { user_id, username, email, customer_id, category_id, supplier_id, product_id, sku, warehouse_id, sale_id, po_id, (sale_id, product_id), (po_id, product_id), (warehouse_id, product_id) } 18 44 19 '''Образложение:''' userId уникатно идентификува корисник, и сите други атрибути опишуваат својства на тој конкретен корисник. 45 '''Лево и десно (Примарни и зависни - Prime and Dependent):''' 46 Во ''product'' табелата, category_id и supplier_id се зависни од product_id, но во нивните сопствени табели се детерминанти. 20 47 21 ==== Анализа на кандидатски клучеви ==== 48 '''Десно (Строго зависни - Strictly Dependent):''' 49 Сите останати атрибути кои се исклучиво на десната страна на зависностите (на пр. password, full_name, quantity, total_amount). 22 50 23 '''Чекор 1: Идентификуваме атрибути што никогаш не се на десната страна на FDs''' 24 - userId: се појавува само на левата страна 51 == 4. Покривачи на примарни клучеви (Closures of Primary Keys) == 52 Анализа на адитивното затворање (attribute closure) за секоја релација: 25 53 26 '''Чекор 2: Пресметуваме затвореност''' 27 {userId}⁺ = {userId, username, password, full_name, email, role, is_active} 54 1. '''Users:''' user_id+ = { user_id, username, password, full_name, email, role, is_active, created_at } 55 2. '''Customer:''' customer_id+ = { customer_id, name, email, phone, address, created_at } 56 3. '''Category:''' category_id+ = { category_id, name, description, created_at } 57 4. '''Supplier:''' supplier_id+ = { supplier_id, name, contact_person, phone, email, address, created_at } 58 5. '''Product:''' product_id+ = { product_id, name, description, sku, unit_price, reorder_level, category_id, supplier_id, is_active, created_at } 59 6. '''Warehouse:''' warehouse_id+ = { warehouse_id, name, location, capacity, created_at } 60 7. '''Sale:''' sale_id+ = { sale_id, date_time, total_amount, user_id, customer_id, warehouse_id } 61 8. '''Purchase Order:''' po_id+ = { po_id, order_date, expected_delivery_date, actual_delivery_date, status, supplier_id, warehouse_id, created_at } 62 9. '''Sale Item:''' {sale_id, product_id}+ = { sale_id, product_id, quantity, unit_price_at_sale } 63 10. '''PO Item:''' {po_id, product_id}+ = { po_id, product_id, quantity, unit_cost, received_quantity } 64 11. '''Warehouse Stock:''' {warehouse_id, product_id}+ = { warehouse_id, product_id, quantity_on_hand, last_updated } 28 65 29 Сите атрибути се детерминирани 66 == 5. Доказ за нормални форми (Детален) == 30 67 31 '''Чекор 3: Тестираме минималност''' 32 - Само еден атрибут во клучот, автоматски минимален 68 === 5.1 1NF (Прва нормална форма) === 69 '''Услов:''' Релацијата е во 1NF ако и само ако сите вредности на атрибутите се атомски (atomic) и нема повторувачки групи. 33 70 34 '''Кандидатски клучеви:''' {userId} 71 * '''Анализа на атомичност:''' 72 * Сите колони во SQL шемата користат примитивни типови на податоци (INTEGER, VARCHAR, DECIMAL, TIMESTAMP, BOOLEAN). 73 * Нема дефинирани релации во внатрешноста на атрибутите (nested relations) или полиски типови. 74 * Иако полето ''address'' има семантички делови, во рамките на релационата тоа е дефинирано како едно поле ''TEXT'', што го задоволува условот за атомичност. 75 * Нема повторувачки групи (на пр., нема колони ''product1'', ''product2''; наместо тоа, се користат табелите ''sale_item'' и ''purchase_order_item'' за повеќекратни вредности). 35 76 36 ''' Примарен клуч:''' userId77 '''Заклучок:''' Сите табели ги задоволуваат условите за 1NF. 37 78 38 ==== Чекори на нормализација ==== 79 === 5.2 2NF (Втора нормална форма) === 80 '''Услов:''' Релацијата е во 2NF ако е во 1NF и нема парцијални зависности (не-клучните атрибути мора да зависат од целиот клуч, а не од негов дел). 39 81 40 '''1NF проверка:''' 41 - Сите атрибути атомарни (нема повеќе-вредносни или композитни атрибути) 42 - Примарен клуч дефиниран 43 - Нема повторувачки групи 82 * '''Анализа по табели:''' 83 1. '''Табели со едноставен клуч (Single Key):''' 84 * Табели како ''users'' (PK: ''user_id''), ''customer'', ''product'' и др. тривијално го задоволуваат условот за 2NF. Бидејќи примарниот клуч се состои од еден атрибут, не може да постои "дел" од клучот што ќе детерминира нешто друго. 85 2. '''Табели со композитен клуч (Composite Key):''' 86 * '''Релацијата ''sale_item'' (PK: {sale_id, product_id}):''' 87 * Атрибутите ''quantity'' и ''unit_price_at_sale'' зависат од продажбата И производот. Една продажба има многу ставки, а еден производ може да се продаде во многу продажби. Затоа, не можеме да го утврдиме количеството само со ''sale_id'' или само со ''product_id''. Тие зависат од '''целата''' комбинација на клучот. 88 * Нема атрибут во оваа табела кој зависи само од еден дел од клучот. 89 * Истата логика важи за ''purchase_order_item'', ''warehouse_stock''. 44 90 45 '''Заклучок: User е во 1NF'''91 '''Заклучок:''' Нема парцијални зависности во композитните клучеви. Сите табели се во 2NF. 46 92 47 '''2NF проверка:''' 48 - Примарниот клуч е еден атрибут 49 - Парцијални зависиности невозможни со еден-атрибутски клуч 50 - Автоматски во 2NF 93 === 5.3 3NF (Трета нормална форма) === 94 '''Услов:''' Релацијата е во 3NF ако е во 2NF и нема транзитивни зависности (не-клучен атрибут не смее да зависи од друг не-клучен атрибут). 51 95 52 '''Заклучок: User е во 2NF''' 96 * '''Анализа на транзитивни зависности:''' 97 1. '''Релацијата ''product'':''' 98 * Потенцијална транзитивна зависност би била: product_id -> category_id и category_id -> category_name. Ова би значело product_id -> category_name преку category_id. 99 * Меѓутоа, во дадениот дизајн, category_name не се чува во ''product'' табелата. Тој е преместен во посебна табела ''category''. Оваа '''декомпозиција''' успешно ја отстранува транзитивната зависност. 100 2. '''Релацијата ''sale'':''' 101 * Слично, sale_id -> customer_id и customer_id -> customer_name. Полето ''customer_name'' не е во ''sale'', туку во ''customer''. 102 3. '''Општ преглед:''' 103 * Во сите табели, не-клучните атрибути зависат исклучиво и директно од примарниот клуч, а не преку други не-клучни атрибути. 53 104 54 '''3NF проверка:''' 55 - Тест за транзитивни зависиности (непримарен → непримарен): 56 - username → password? НЕ (корисничките имиња не детерминираат лозинки) 57 - username → full_name? НЕ (корисничките имиња не идентификуваат луѓе уникатно) 58 - username → email? НЕ 59 - email → username? НЕ (email-овите не детерминираат кориснички имиња) 60 - role → (било кој друг атрибут)? НЕ (role е категорија, не детерминант) 61 - Не постојат транзитивни зависиности 105 '''Заклучок:''' Нема транзитивни зависности. Сите табели се во 3NF. 62 106 63 '''Заклучок: User е во 3NF''' 107 === 5.4 BCNF (Boyce-Codd нормална форма) === 108 '''Услов:''' Релацијата е во BCNF ако за секоја нетривијална функционална зависност X -> A, X е суперклуч на релацијата. 64 109 65 '''BCNF проверка:''' 66 - За секоја FD X → Y, дали X е суперклуч? 67 - FD1: userId → {...} 68 - Дали userId е суперклуч? ДА (тој е кандидатскиот клуч) 110 * '''Критичен преглед на детерминантите:''' 111 1. '''Табела ''users'':''' 112 * Детерминанти: user_id (PK), username (UNIQUE), email (UNIQUE). 113 * Сите тие (user_id, username, email) се суперклучеви (еднозначно идентификуваат ред). Дополнителните UNIQUE ограничувања не го кршат BCNF. 114 2. '''Табела ''product'':''' 115 * Детерминанти: product_id (PK), sku (UNIQUE). 116 * sku е кандидат клуч (candidate key), па sku -> ... зависноста има суперклуч како детерминанта. 117 3. '''Останатите табели:''' 118 * Во табелите со композитни клучеви, нема детерминанта што е надвор од клучот или само дел од него (освен самиот PK). 69 119 70 '''Заклучок: User е во BCNF'''120 '''Заклучок:''' Нема зависности каде детерминантата не е суперклуч. Шемата е во '''BCNF'''. 71 121 72 ==== Финална шема ==== 122 == 6. Својства на декомпозицијата == 123 1. '''Зачувување на зависности:''' Сите функционални зависности од '''F''' се локализирани во соодветните табели (напр. зависноста за sku е во ''product'' табелата). 124 2. '''Декомпозиција без загуби:''' Foreign Key constraints обезбедуваат дека JOIN на табелите ќе резултира со оригиналната слика на податоците без изгубени или додадени редови. 73 125 74 '''User'''(userId, username, password, full_name, email, role, is_active) 75 - '''PK:''' userId 76 - '''Нормална форма:''' BCNF 126 == 7. Специјални случаи и подобрувања == 77 127 78 === Ентитет 2: CUSTOMER === 128 === 7.1 ''total_amount'' како изведен атрибут (Денормализација) === 129 '''Статус:''' Складиран прерасчет (Stored Calculated Value). 79 130 80 ==== Почетна релациска шема ==== 131 '''Анализа:''' Атрибутот ''sale.total_amount'' може да се пресмета како SUM(sale_item.quantity * sale_item.unit_price_at_sale). Неговото чување во ''sale'' табелата е денормализација наменета за перформанси. 81 132 82 ''' Customer'''(customerId, name, email, phone, address)133 '''Техничко решение за конзистентност (Trigger):''' 83 134 84 ==== Функционални зависиности ==== 135 {{{ 136 #!sql 137 CREATE OR REPLACE FUNCTION update_sale_total() 138 RETURNS TRIGGER AS $$ 139 BEGIN 140 UPDATE sale s 141 SET total_amount = ( 142 SELECT COALESCE(SUM(si.quantity * si.unit_price_at_sale), 0) 143 FROM sale_item si 144 WHERE si.sale_id = COALESCE(NEW.sale_id, OLD.sale_id) 145 ) 146 WHERE s.sale_id = COALESCE(NEW.sale_id, OLD.sale_id); 147 148 RETURN COALESCE(NEW, OLD); 149 END; 150 $$ LANGUAGE plpgsql; 85 151 86 '''FD2:''' customerId → name, email, phone, address 152 CREATE TRIGGER trg_update_sale_total 153 AFTER INSERT OR UPDATE OR DELETE ON sale_item 154 FOR EACH ROW EXECUTE FUNCTION update_sale_total(); 155 }}} 87 156 88 '''Образложение:''' customerId уникатно идентификува клиент, и сите други атрибути опишуваат својства на тој конкретен клиент. 157 === 7.2 Атомичност на ''address'' === 158 '''Статус:''' Потенцијално кршење на 1NF. 89 159 90 ==== Анализа на кандидатски клучеви ==== 160 '''Анализа:''' Адресата е составена од повеќе семантички делови (улица, град, поштенски код, држава). Држењето на сите овие податоци во едно ''TEXT'' поле ја отежнува агрегацијата (на пр. пребарување на сите корисници во градот "Skopje"). 91 161 92 {customerId}⁺ = {customerId, name, email, phone, address} 162 '''Предложена декомпозиција:''' 93 163 94 '''Кандидатски клучеви:''' {customerId} 164 {{{ 165 #!sql 166 ALTER TABLE customer 167 ADD COLUMN street_address VARCHAR(255), 168 ADD COLUMN city VARCHAR(100), 169 ADD COLUMN zip_code VARCHAR(20), 170 ADD COLUMN country VARCHAR(100) DEFAULT 'Macedonia'; 95 171 96 '''Примарен клуч:''' customerId 172 ALTER TABLE supplier 173 ADD COLUMN street_address VARCHAR(255), 174 ADD COLUMN city VARCHAR(100), 175 ADD COLUMN zip_code VARCHAR(20), 176 ADD COLUMN country VARCHAR(100) DEFAULT 'Macedonia'; 177 }}} 97 178 98 ==== Чекори на нормализација ==== 179 == 8. Краен Заклучок == 180 Врз основа на извршената формална анализа, заклучокот е следниов: 99 181 100 ''' 1NF:''' Атомарни атрибути182 '''Базата на податоци е до нормализирана до BCNF.''' 101 183 102 '''2NF:''' Еден-атрибутски клуч 184 Доказот поткрепува дека: 185 1. '''1NF:''' Сите вредности се атомски. 186 2. '''2NF:''' Нема делумни зависности во композитните клучеви. 187 3. '''3NF:''' Нема транзитивни зависности поради правилното користење на Foreign Keys. 188 4. '''BCNF:''' Сите детерминанти се суперклучеви (вклучувајќи ги UNIQUE ограничувањата). 103 189 104 '''3NF проверка:''' 105 - Не постојат транзитивни зависиности 106 107 '''BCNF проверка:''' 108 - FD2: customerId е суперклуч 109 110 ==== Финална шема ==== 111 112 '''Customer'''(customerId, name, email, phone, address) 113 - '''PK:''' customerId 114 - '''Нормална форма:''' BCNF 115 116 === Ентитет 3: CATEGORY === 117 118 ==== Почетна релациска шема ==== 119 120 '''Category'''(categoryId, name, description) 121 122 ==== Функционални зависиности ==== 123 124 '''FD3:''' categoryId → name, description 125 126 ==== Анализа на кандидатски клучеви ==== 127 128 {categoryId}⁺ = {categoryId, name, description} 129 130 '''Кандидатски клучеви:''' {categoryId} 131 132 '''Примарен клуч:''' categoryId 133 134 ==== Финална шема ==== 135 136 '''Category'''(categoryId, name, description) 137 - '''PK:''' categoryId 138 - '''Нормална форма:''' BCNF 139 140 === Ентитет 4: SUPPLIER === 141 142 ==== Почетна релациска шема ==== 143 144 '''Supplier'''(supplierId, name, contact_person, phone, email, address) 145 146 ==== Функционални зависиности ==== 147 148 '''FD4:''' supplierId → name, contact_person, phone, email, address 149 150 ==== Анализа на кандидатски клучеви ==== 151 152 {supplierId}⁺ = {supplierId, name, contact_person, phone, email, address} 153 154 '''Кандидатски клучеви:''' {supplierId} 155 156 '''Примарен клуч:''' supplierId 157 158 ==== Финална шема ==== 159 160 '''Supplier'''(supplierId, name, contact_person, phone, email, address) 161 - '''PK:''' supplierId 162 - '''Нормална форма:''' BCNF 163 164 === Ентитет 5: WAREHOUSE === 165 166 ==== Почетна релациска шема ==== 167 168 '''Warehouse'''(warehouseId, name, location, capacity) 169 170 ==== Функционални зависиности ==== 171 172 '''FD5:''' warehouseId → name, location, capacity 173 174 ==== Анализа на кандидатски клучеви ==== 175 176 {warehouseId}⁺ = {warehouseId, name, location, capacity} 177 178 '''Кандидатски клучеви:''' {warehouseId} 179 180 '''Примарен клуч:''' warehouseId 181 182 ==== Финална шема ==== 183 184 '''Warehouse'''(warehouseId, name, location, capacity) 185 - '''PK:''' warehouseId 186 - '''Нормална форма:''' BCNF 187 188 === Ентитет 6: PRODUCT === 189 190 ==== Почетна релациска шема ==== 191 192 '''Product'''(productId, name, description, sku, unit_price, reorder_level, categoryId, supplierId) 193 194 ==== Функционални зависиности ==== 195 196 '''FD6:''' productId → name, description, sku, unit_price, reorder_level, categoryId, supplierId 197 198 '''FD7:''' sku → productId, name, description, unit_price, reorder_level, categoryId, supplierId 199 200 '''Образложение:''' ER моделот специфицира дека '''и productId и sku се уникатни идентификатори''' 201 202 ==== Анализа на кандидатски клучеви ==== 203 204 '''Тест productId:''' 205 {productId}⁺ = {productId, name, description, sku, unit_price, reorder_level, categoryId, supplierId} 206 - Сите атрибути детерминирани 207 - Минимален 208 209 '''Тест sku:''' 210 {sku}⁺ = {sku, productId, name, description, unit_price, reorder_level, categoryId, supplierId} 211 - Сите атрибути детерминирани 212 - Минимален 213 214 '''Кандидатски клучеви:''' {productId}, {sku} 215 216 '''Примарен клуч:''' productId 217 218 '''Алтернативен клуч:''' sku 219 220 ==== Чекори на нормализација ==== 221 222 '''3NF проверка:''' 223 224 '''Важно: Надворешни клучеви vs. Транзитивни зависиности''' 225 226 Оваа релација содржи '''categoryId''' и '''supplierId''' кои се надворешни клучеви. 227 228 '''Прашање:''' Дали овие создаваат транзитивни зависиности? 229 230 '''Одговор:''' НЕ 231 232 '''Објаснување:''' Надворешните клучеви се '''индикатори на релации''', не транзитивни зависиности. Вистинските зависни атрибути (category_name, supplier_name) се складирани во нивните соодветни релации (Category, Supplier), одржувајќи ја нормализацијата. 233 234 '''Product е во BCNF''' 235 236 ==== Финална шема ==== 237 238 '''Product'''(productId, name, description, sku, unit_price, reorder_level, categoryId, supplierId) 239 240 - '''PK:''' productId 241 242 - '''AK:''' sku 243 244 - '''FK:''' categoryId → Category(categoryId) 245 246 - '''FK:''' supplierId → Supplier(supplierId) 247 248 - '''Нормална форма:''' BCNF 249 250 === Ентитет 7: SALE === 251 252 ==== Почетна релациска шема ==== 253 254 '''Sale'''(saleId, date_time, total_amount, userId, customerId, warehouseId) 255 256 ==== Функционални зависиности==== 257 258 '''FD8:''' saleId → date_time, total_amount, userId, customerId, warehouseId 259 260 ==== Анализа на кандидатски клучеви ==== 261 262 {saleId}⁺ = {saleId, date_time, total_amount, userId, customerId, warehouseId} 263 264 '''Кандидатски клучеви:''' {saleId} 265 266 '''Примарен клуч:''' saleId 267 268 ==== Финална шема ==== 269 270 '''Sale'''(saleId, date_time, total_amount, userId, customerId, warehouseId) 271 272 - '''PK:''' saleId 273 274 - '''FK:''' userId → User(userId) 275 276 - '''FK:''' customerId → Customer(customerId) 277 278 - '''FK:''' warehouseId → Warehouse(warehouseId) 279 280 - '''Нормална форма:''' BCNF 281 282 === Ентитет 8: PURCHASEORDER === 283 284 ==== Почетна релациска шема ==== 285 286 '''!PurchaseOrder'''(poId, order_date, expected_delivery_date, status, supplierId, warehouseId) 287 288 ==== Функционални зависиности ==== 289 290 '''FD9:''' poId → order_date, expected_delivery_date, status, supplierId, warehouseId 291 292 ==== Анализа на кандидатски клучеви ==== 293 294 {poId}⁺ = {poId, order_date, expected_delivery_date, status, supplierId, warehouseId} 295 296 '''Кандидатски клучеви:''' {poId} 297 298 '''Примарен клуч:''' poId 299 300 ==== Финална шема ==== 301 302 '''!PurchaseOrder'''(poId, order_date, expected_delivery_date, status, supplierId, warehouseId) 303 304 - '''PK:''' poId 305 306 - '''FK:''' supplierId → Supplier(supplierId) 307 308 - '''FK:''' warehouseId → Warehouse(warehouseId) 309 310 - '''Нормална форма:''' BCNF 311 312 === Ентитет 9: SALEITEM (Слаб ентитет) === 313 314 ==== Почетна релациска шема ==== 315 316 '''!SaleItem'''(saleId, productId, quantity, unit_price_at_sale) 317 318 ==== Функционални зависиности ==== 319 320 '''FD10:''' (saleId, productId) → quantity, unit_price_at_sale 321 322 ==== Анализа на кандидатски клучеви ==== 323 324 '''Тест (saleId, productId):''' 325 326 {saleId, productId}⁺ = {saleId, productId, quantity, unit_price_at_sale} 327 328 - Сите атрибути детерминирани 329 330 - Двата компоненти неопходни 331 332 '''Кандидатски клучеви:''' {(saleId, productId)} 333 334 '''Примарен клуч:''' (saleId, productId) 335 336 ==== Чекори на нормализација ==== 337 338 '''2NF проверка:''' 339 340 Нема парцијални зависиности. Двата непримарни атрибути (quantity, unit_price_at_sale) бараат '''ЦЕЛОСЕН композитен клуч''' (saleId, productId) за детерминација. 341 342 '''!SaleItem е во 2NF''' 343 344 '''3NF проверка:''' 345 346 Не постојат транзитивни зависиности 347 348 '''!SaleItem е во 3NF''' 349 350 '''BCNF проверка:''' 351 - FD10: (saleId, productId) е суперклуч 352 353 '''!SaleItem е во BCNF''' 354 355 ==== Карактеристики на слаб ентитет ==== 356 357 1. '''Зависимост од постоење:''' !SaleItem не може да постои без родителска Sale 358 359 2. '''Идентификувачка релација:''' Надворешниот клуч (saleId) е дел од примарниот клуч 360 361 3. '''Парцијален клуч:''' productId ги разликува различните производи во иста продажба 362 363 ==== Финална шема ==== 364 365 '''!SaleItem'''(saleId, productId, quantity, unit_price_at_sale) 366 367 - '''PK:''' (saleId, productId) 368 369 - '''FK:''' saleId → Sale(saleId) - '''идентификувачка''' 370 371 - '''FK:''' productId → Product(productId) 372 373 - '''Тип на ентитет:''' Слаб ентитет (зависен од Sale) 374 375 - '''Нормална форма:''' BCNF 376 377 === Ентитет 10: PURCHASEORDERITEM (Слаб ентитет) === 378 379 ==== Почетна релациска шема ==== 380 381 '''!PurchaseOrderItem'''(poId, productId, quantity, unit_cost) 382 383 ==== Функционални зависиности ==== 384 385 '''FD11:''' (poId, productId) → quantity, unit_cost 386 387 ==== Анализа на кандидатски клучеви ==== 388 389 {poId, productId}⁺ = {poId, productId, quantity, unit_cost} 390 391 '''Кандидатски клучеви:''' {(poId, productId)} 392 393 '''Примарен клуч:''' (poId, productId) 394 395 ==== Финална шема ==== 396 397 '''!PurchaseOrderItem'''(poId, productId, quantity, unit_cost) 398 399 - '''PK:''' (poId, productId) 400 401 - '''FK:''' poId → !PurchaseOrder(poId) - '''идентификувачка''' 402 403 - '''FK:''' productId → Product(productId) 404 405 - '''Тип на ентитет:''' Слаб ентитет (зависен од !PurchaseOrder) 406 407 - '''Нормална форма:''' BCNF 408 409 === Ентитет 11: WAREHOUSESTOCK (Слаб ентитет) === 410 411 ==== Почетна релациска шема ==== 412 413 '''!WarehouseStock'''(warehouseId, productId, quantity_on_hand, last_updated) 414 415 ==== Функционални зависиности ==== 416 417 '''FD12:''' (warehouseId, productId) → quantity_on_hand, last_updated 418 419 ==== Анализа на кандидатски клучеви ==== 420 421 {warehouseId, productId}⁺ = {warehouseId, productId, quantity_on_hand, last_updated} 422 423 '''Кандидатски клучеви:''' {(warehouseId, productId)} 424 425 '''Примарен клуч:''' (warehouseId, productId) 426 427 ==== Финална шема ==== 428 429 '''!WarehouseStock'''(warehouseId, productId, quantity_on_hand, last_updated) 430 431 - '''PK:''' (warehouseId, productId) 432 433 - '''FK:''' warehouseId → Warehouse(warehouseId) - '''идентификувачка''' 434 435 - '''FK:''' productId → Product(productId) 436 437 - '''Тип на ентитет:''' Слаб ентитет (зависен од Warehouse) 438 439 - '''Нормална форма:''' BCNF 440 441 == Дел 2: Сеопфатно резиме == 442 443 === Резиме на функционални зависиности === 444 445 1. '''User:''' userId → username, password, full_name, email, role, is_active 446 447 2. '''Customer:''' customerId → name, email, phone, address 448 449 3. '''Category:''' categoryId → name, description 450 451 4. '''Supplier:''' supplierId → name, contact_person, phone, email, address 452 453 5. '''Warehouse:''' warehouseId → name, location, capacity 454 455 6. '''Product:''' 456 * productId → name, description, sku, unit_price, reorder_level, categoryId, supplierId 457 * sku → productId, name, description, unit_price, reorder_level, categoryId, supplierId 458 459 7. '''Sale:''' saleId → date_time, total_amount, userId, customerId, warehouseId 460 461 8. '''PurchaseOrder:''' poId → order_date, expected_delivery_date, status, supplierId, warehouseId 462 463 9. '''SaleItem:''' (saleId, productId) → quantity, unit_price_at_sale 464 465 10. '''PurchaseOrderItem:''' (poId, productId) → quantity, unit_cost 466 467 11. '''WarehouseStock:''' (warehouseId, productId) → quantity_on_hand, last_updated 468 469 === Резиме на кандидатски клучеви === 470 471 '''User:''' 472 * Кандидатски клуч: {userId} 473 * Примарен клуч: userId 474 475 '''Customer:''' 476 * Кандидатски клуч: {customerId} 477 * Примарен клуч: customerId 478 479 '''Category:''' 480 * Кандидатски клуч: {categoryId} 481 * Примарен клуч: categoryId 482 483 '''Supplier:''' 484 * Кандидатски клуч: {supplierId} 485 * Примарен клуч: supplierId 486 487 '''Warehouse:''' 488 * Кандидатски клуч: {warehouseId} 489 * Примарен клуч: warehouseId 490 491 '''Product:''' 492 * Кандидатски клучеви: {productId}, {sku} 493 * Примарен клуч: productId 494 * Алтернативен клуч: sku 495 496 '''Sale:''' 497 * Кандидатски клуч: {saleId} 498 * Примарен клуч: saleId 499 500 '''PurchaseOrder:''' 501 * Кандидатски клуч: {poId} 502 * Примарен клуч: poId 503 504 '''SaleItem:''' 505 * Кандидатски клуч: {(saleId, productId)} 506 * Примарен клуч: (saleId, productId) 507 508 '''PurchaseOrderItem:''' 509 * Кандидатски клуч: {(poId, productId)} 510 * Примарен клуч: (poId, productId) 511 512 '''WarehouseStock:''' 513 * Кандидатски клуч: {(warehouseId, productId)} 514 * Примарен клуч: (warehouseId, productId) 515 516 == Заклучок == 517 518 Анализата покажа дека релациската шема од Фаза P2 веќе е во BCNF без потреба од дополнителни измени. 519 520 '''Резултати од анализата:''' 521 * Сите 11 релации се во BCNF 522 * Не е потребна декомпозиција 523 * Не е потребна реорганизација 524 * Релациската шема од Фаза P2 може директно да се имплементира. 190 Предложените подобрувања за ''address'' и ''total_amount'' служат за зголемување на атомичноста (теоретска совршеност) и одржување на конзистентноста (практична примена).
