Changes between Initial Version and Version 1 of Normalization


Ignore:
Timestamp:
01/07/26 01:01:04 (3 days ago)
Author:
221181
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v1 v1  
     1= Формална анализа и доказ за нормализација на Stock Master =
     2
     3== 1. Дефиниција на универзалната релација ==
     4Нека '''R''' претставува универзалната шема на релацијата. Множеството на атрибути '''U''' во '''R''' е дефинирано како:
     5
     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 }
     15
     16== 2. Функционални зависности (Functional Dependencies - F) ==
     17Врз основа на SQL ограничувањата (CONSTRAINTS) и семантиката на податоците, дефинираме го множеството на функционални зависности '''F''' како канонски покривач:
     18
     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
     28
     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
     33
     34=== Кандидат клучеви (Candidate Keys) ===
     35 1. username -> user_id (поради UNIQUE ограничување)
     36 2. email -> user_id (поради UNIQUE ограничување)
     37 3. sku -> product_id (поради UNIQUE ограничување)
     38
     39== 3. Класификација на атрибути ==
     40Врз основа на '''F''', ги извршуваме следниве класификации:
     41
     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) }
     44
     45'''Лево и десно (Примарни и зависни - Prime and Dependent):'''
     46Во ''product'' табелата, category_id и supplier_id се зависни од product_id, но во нивните сопствени табели се детерминанти.
     47
     48'''Десно (Строго зависни - Strictly Dependent):'''
     49Сите останати атрибути кои се исклучиво на десната страна на зависностите (на пр. password, full_name, quantity, total_amount).
     50
     51== 4. Покривачи на примарни клучеви (Closures of Primary Keys) ==
     52Анализа на адитивното затворање (attribute closure) за секоја релација:
     53
     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 }
     65
     66== 5. Доказ за нормални форми (Детален) ==
     67
     68=== 5.1 1NF (Прва нормална форма) ===
     69'''Услов:''' Релацијата е во 1NF ако и само ако сите вредности на атрибутите се атомски (atomic) и нема повторувачки групи.
     70
     71 * '''Анализа на атомичност:'''
     72   * Сите колони во SQL шемата користат примитивни типови на податоци (INTEGER, VARCHAR, DECIMAL, TIMESTAMP, BOOLEAN).
     73   * Нема дефинирани релации во внатрешноста на атрибутите (nested relations) или полиски типови.
     74   * Иако полето ''address'' има семантички делови, во рамките на релационата тоа е дефинирано како едно поле ''TEXT'', што го задоволува условот за атомичност.
     75   * Нема повторувачки групи (на пр., нема колони ''product1'', ''product2''; наместо тоа, се користат табелите ''sale_item'' и ''purchase_order_item'' за повеќекратни вредности).
     76
     77'''Заклучок:''' Сите табели ги задоволуваат условите за 1NF.
     78
     79=== 5.2 2NF (Втора нормална форма) ===
     80'''Услов:''' Релацијата е во 2NF ако е во 1NF и нема парцијални зависности (не-клучните атрибути мора да зависат од целиот клуч, а не од негов дел).
     81
     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''.
     90
     91'''Заклучок:''' Нема парцијални зависности во композитните клучеви. Сите табели се во 2NF.
     92
     93=== 5.3 3NF (Трета нормална форма) ===
     94'''Услов:''' Релацијата е во 3NF ако е во 2NF и нема транзитивни зависности (не-клучен атрибут не смее да зависи од друг не-клучен атрибут).
     95
     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     * Во сите табели, не-клучните атрибути зависат исклучиво и директно од примарниот клуч, а не преку други не-клучни атрибути.
     104
     105'''Заклучок:''' Нема транзитивни зависности. Сите табели се во 3NF.
     106
     107=== 5.4 BCNF (Boyce-Codd нормална форма) ===
     108'''Услов:''' Релацијата е во BCNF ако за секоја нетривијална функционална зависност X -> A, X е суперклуч на релацијата.
     109
     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).
     119
     120'''Заклучок:''' Нема зависности каде детерминантата не е суперклуч. Шемата е во '''BCNF'''.
     121
     122== 6. Својства на декомпозицијата ==
     123 1. '''Зачувување на зависности:''' Сите функционални зависности од '''F''' се локализирани во соодветните табели (напр. зависноста за sku е во ''product'' табелата).
     124 2. '''Декомпозиција без загуби:''' Foreign Key constraints обезбедуваат дека JOIN на табелите ќе резултира со оригиналната слика на податоците без изгубени или додадени редови.
     125
     126== 7. Специјални случаи и подобрувања ==
     127
     128=== 7.1 ''total_amount'' како изведен атрибут (Денормализација) ===
     129'''Статус:''' Складиран прерасчет (Stored Calculated Value).
     130
     131'''Анализа:''' Атрибутот ''sale.total_amount'' може да се пресмета како SUM(sale_item.quantity * sale_item.unit_price_at_sale). Неговото чување во ''sale'' табелата е денормализација наменета за перформанси.
     132
     133'''Техничко решение за конзистентност (Trigger):'''
     134
     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;
     151
     152CREATE TRIGGER trg_update_sale_total
     153AFTER INSERT OR UPDATE OR DELETE ON sale_item
     154FOR EACH ROW EXECUTE FUNCTION update_sale_total();
     155}}}
     156
     157=== 7.2 Атомичност на ''address'' ===
     158'''Статус:''' Потенцијално кршење на 1NF.
     159
     160'''Анализа:''' Адресата е составена од повеќе семантички делови (улица, град, поштенски код, држава). Држењето на сите овие податоци во едно ''TEXT'' поле ја отежнува агрегацијата (на пр. пребарување на сите корисници во градот "Skopje").
     161
     162'''Предложена декомпозиција:'''
     163
     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';
     171
     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}}}
     178
     179== 8. Краен Заклучок ==
     180Врз основа на извршената формална анализа, вердиктот е следен:
     181
     182'''Базата на податоци е до нормализирана до BCNF.'''
     183
     184Доказот поткрепува дека:
     185 1. '''1NF:''' Сите вредности се атомски.
     186 2. '''2NF:''' Нема делумни зависности во композитните клучеви.
     187 3. '''3NF:''' Нема транзитивни зависности поради правилното користење на Foreign Keys.
     188 4. '''BCNF:''' Сите детерминанти се суперклучеви (вклучувајќи ги UNIQUE ограничувањата).
     189
     190Предложените подобрувања за ''address'' и ''total_amount'' служат за зголемување на атомичноста (теоретска совршеност) и одржување на конзистентноста (практична примена).