Changes between Version 8 and Version 9 of Normalization


Ignore:
Timestamp:
01/14/26 11:04:33 (13 days ago)
Author:
221181
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v8 v9  
    1 = Нормализација =
     1= Формална анализа и доказ за нормализација на Stock Master =
    22
    3 == Вовед ==
     3== 1. Дефиниција на универзалната релација ==
     4Нека '''R''' претставува универзалната шема на релацијата. Множеството на атрибути '''U''' во '''R''' е дефинирано како:
    45
    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 }
    615
    7 == Дел 1: Нормализација ==
     16== 2. Функционални зависности (Functional Dependencies - F) ==
     17Врз основа на SQL ограничувањата (CONSTRAINTS) и семантиката на податоците, дефинираме го множеството на функционални зависности '''F''' како канонски покривач:
    818
    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
    1028
    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
    1233
    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 ограничување)
    1438
    15 ==== Функционални зависиности ====
     39== 3. Класификација на атрибути ==
     40Врз основа на '''F''', ги извршуваме следниве класификации:
    1641
    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) }
    1844
    19 '''Образложение:''' userId уникатно идентификува корисник, и сите други атрибути опишуваат својства на тој конкретен корисник.
     45'''Лево и десно (Примарни и зависни - Prime and Dependent):'''
     46Во ''product'' табелата, category_id и supplier_id се зависни од product_id, но во нивните сопствени табели се детерминанти.
    2047
    21 ==== Анализа на кандидатски клучеви ====
     48'''Десно (Строго зависни - Strictly Dependent):'''
     49Сите останати атрибути кои се исклучиво на десната страна на зависностите (на пр. password, full_name, quantity, total_amount).
    2250
    23 '''Чекор 1: Идентификуваме атрибути што никогаш не се на десната страна на FDs'''
    24 - userId: се појавува само на левата страна
     51== 4. Покривачи на примарни клучеви (Closures of Primary Keys) ==
     52Анализа на адитивното затворање (attribute closure) за секоја релација:
    2553
    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 }
    2865
    29 Сите атрибути се детерминирани
     66== 5. Доказ за нормални форми (Детален) ==
    3067
    31 '''Чекор 3: Тестираме минималност'''
    32 - Само еден атрибут во клучот, автоматски минимален
     68=== 5.1 1NF (Прва нормална форма) ===
     69'''Услов:''' Релацијата е во 1NF ако и само ако сите вредности на атрибутите се атомски (atomic) и нема повторувачки групи.
    3370
    34 '''Кандидатски клучеви:''' {userId}
     71 * '''Анализа на атомичност:'''
     72   * Сите колони во SQL шемата користат примитивни типови на податоци (INTEGER, VARCHAR, DECIMAL, TIMESTAMP, BOOLEAN).
     73   * Нема дефинирани релации во внатрешноста на атрибутите (nested relations) или полиски типови.
     74   * Иако полето ''address'' има семантички делови, во рамките на релационата тоа е дефинирано како едно поле ''TEXT'', што го задоволува условот за атомичност.
     75   * Нема повторувачки групи (на пр., нема колони ''product1'', ''product2''; наместо тоа, се користат табелите ''sale_item'' и ''purchase_order_item'' за повеќекратни вредности).
    3576
    36 '''Примарен клуч:''' userId
     77'''Заклучок:''' Сите табели ги задоволуваат условите за 1NF.
    3778
    38 ==== Чекори на нормализација ====
     79=== 5.2 2NF (Втора нормална форма) ===
     80'''Услов:''' Релацијата е во 2NF ако е во 1NF и нема парцијални зависности (не-клучните атрибути мора да зависат од целиот клуч, а не од негов дел).
    3981
    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''.
    4490
    45 '''Заклучок: User е во 1NF'''
     91'''Заклучок:''' Нема парцијални зависности во композитните клучеви. Сите табели се во 2NF.
    4692
    47 '''2NF проверка:'''
    48 - Примарниот клуч е еден атрибут
    49 - Парцијални зависиности невозможни со еден-атрибутски клуч
    50 - Автоматски во 2NF
     93=== 5.3 3NF (Трета нормална форма) ===
     94'''Услов:''' Релацијата е во 3NF ако е во 2NF и нема транзитивни зависности (не-клучен атрибут не смее да зависи од друг не-клучен атрибут).
    5195
    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     * Во сите табели, не-клучните атрибути зависат исклучиво и директно од примарниот клуч, а не преку други не-клучни атрибути.
    53104
    54 '''3NF проверка:'''
    55 - Тест за транзитивни зависиности (непримарен → непримарен):
    56   - username → password? НЕ (корисничките имиња не детерминираат лозинки)
    57   - username → full_name? НЕ (корисничките имиња не идентификуваат луѓе уникатно)
    58   - username → email? НЕ
    59   - email → username? НЕ (email-овите не детерминираат кориснички имиња)
    60   - role → (било кој друг атрибут)? НЕ (role е категорија, не детерминант)
    61   - Не постојат транзитивни зависиности
     105'''Заклучок:''' Нема транзитивни зависности. Сите табели се во 3NF.
    62106
    63 '''Заклучок: User е во 3NF'''
     107=== 5.4 BCNF (Boyce-Codd нормална форма) ===
     108'''Услов:''' Релацијата е во BCNF ако за секоја нетривијална функционална зависност X -> A, X е суперклуч на релацијата.
    64109
    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).
    69119
    70 '''Заклучок: User е во BCNF'''
     120'''Заклучок:''' Нема зависности каде детерминантата не е суперклуч. Шемата е во '''BCNF'''.
    71121
    72 ==== Финална шема ====
     122== 6. Својства на декомпозицијата ==
     123 1. '''Зачувување на зависности:''' Сите функционални зависности од '''F''' се локализирани во соодветните табели (напр. зависноста за sku е во ''product'' табелата).
     124 2. '''Декомпозиција без загуби:''' Foreign Key constraints обезбедуваат дека JOIN на табелите ќе резултира со оригиналната слика на податоците без изгубени или додадени редови.
    73125
    74 '''User'''(userId, username, password, full_name, email, role, is_active)
    75 - '''PK:''' userId
    76 - '''Нормална форма:''' BCNF
     126== 7. Специјални случаи и подобрувања ==
    77127
    78 === Ентитет 2: CUSTOMER ===
     128=== 7.1 ''total_amount'' како изведен атрибут (Денормализација) ===
     129'''Статус:''' Складиран прерасчет (Stored Calculated Value).
    79130
    80 ==== Почетна релациска шема ====
     131'''Анализа:''' Атрибутот ''sale.total_amount'' може да се пресмета како SUM(sale_item.quantity * sale_item.unit_price_at_sale). Неговото чување во ''sale'' табелата е денормализација наменета за перформанси.
    81132
    82 '''Customer'''(customerId, name, email, phone, address)
     133'''Техничко решение за конзистентност (Trigger):'''
    83134
    84 ==== Функционални зависиности ====
     135{{{
     136#!sql
     137CREATE OR REPLACE FUNCTION update_sale_total()
     138RETURNS TRIGGER AS $$
     139BEGIN
     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);
     149END;
     150$$ LANGUAGE plpgsql;
    85151
    86 '''FD2:''' customerId → name, email, phone, address
     152CREATE TRIGGER trg_update_sale_total
     153AFTER INSERT OR UPDATE OR DELETE ON sale_item
     154FOR EACH ROW EXECUTE FUNCTION update_sale_total();
     155}}}
    87156
    88 '''Образложение:''' customerId уникатно идентификува клиент, и сите други атрибути опишуваат својства на тој конкретен клиент.
     157=== 7.2 Атомичност на ''address'' ===
     158'''Статус:''' Потенцијално кршење на 1NF.
    89159
    90 ==== Анализа на кандидатски клучеви ====
     160'''Анализа:''' Адресата е составена од повеќе семантички делови (улица, град, поштенски код, држава). Држењето на сите овие податоци во едно ''TEXT'' поле ја отежнува агрегацијата (на пр. пребарување на сите корисници во градот "Skopje").
    91161
    92 {customerId}⁺ = {customerId, name, email, phone, address}
     162'''Предложена декомпозиција:'''
    93163
    94 '''Кандидатски клучеви:''' {customerId}
     164{{{
     165#!sql
     166ALTER TABLE customer
     167ADD COLUMN street_address VARCHAR(255),
     168ADD COLUMN city VARCHAR(100),
     169ADD COLUMN zip_code VARCHAR(20),
     170ADD COLUMN country VARCHAR(100) DEFAULT 'Macedonia';
    95171
    96 '''Примарен клуч:''' customerId
     172ALTER TABLE supplier
     173ADD COLUMN street_address VARCHAR(255),
     174ADD COLUMN city VARCHAR(100),
     175ADD COLUMN zip_code VARCHAR(20),
     176ADD COLUMN country VARCHAR(100) DEFAULT 'Macedonia';
     177}}}
    97178
    98 ==== Чекори на нормализација ====
     179== 8. Краен Заклучок ==
     180Врз основа на извршената формална анализа, заклучокот е следниов:
    99181
    100 '''1NF:'''  Атомарни атрибути
     182'''Базата на податоци е до нормализирана до BCNF.'''
    101183
    102 '''2NF:'''  Еден-атрибутски клуч
     184Доказот поткрепува дека:
     185 1. '''1NF:''' Сите вредности се атомски.
     186 2. '''2NF:''' Нема делумни зависности во композитните клучеви.
     187 3. '''3NF:''' Нема транзитивни зависности поради правилното користење на Foreign Keys.
     188 4. '''BCNF:''' Сите детерминанти се суперклучеви (вклучувајќи ги UNIQUE ограничувањата).
    103189
    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'' служат за зголемување на атомичноста (теоретска совршеност) и одржување на конзистентноста (практична примена).