Changes between Version 2 and Version 3 of Normalization


Ignore:
Timestamp:
04/20/26 18:39:48 (6 months ago)
Author:
233062
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v2 v3  
    1 Нормализација
    2 == Де-нормализирана база на податоци
     1# **Нормализација**
     2
     3== **Де-нормализирана база на податоци**
    34
    45Се тргнува од една глобална, де-нормализирана релација што ги содржи атрибутите од целиот модел:
    56
    6 R = { user_id, email, username, password, training_user_id, training_gender, training_age, training_weight, training_id, training_date, training_type, training_duration, training_calories, investor_user_id, asset_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_user_id, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_id, daily_intake_date, daily_intake_calories, discipline_user_id, custom_tracking_id, custom_tracking_name, task_id, task_name, task_finished, daily_completion_id, daily_completion_date, daily_completion_percent, finance_user_id, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_id, income_date, income_amount }
     7`R = { user_id, email, username, password, training_user_id, training_gender, training_age, training_weight, training_id, training_date, training_type, training_duration, training_calories, investor_user_id, asset_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_user_id, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_id, daily_intake_date, daily_intake_calories, discipline_user_id, custom_tracking_id, custom_tracking_name, task_id, task_name, task_finished, daily_completion_id, daily_completion_date, daily_completion_percent, finance_user_id, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_id, income_date, income_amount }`
    78
    89Оваа релација е де-нормализирана затоа што содржи повторливи групи, како и зависности од атрибути што не се клуч.
    910
    10 == Функционални зависности
     11== **Функционални зависности**
    1112
    12 FD1: user_id -> email, username, password
    13 FD2: email -> user_id, username, password
    14 FD3: username -> user_id, email, password
    15 FD4: training_user_id -> training_gender, training_age, training_weight
    16 FD5: training_id -> training_user_id, training_date, training_type, training_duration, training_calories
    17 FD6: investor_user_id -> user_id
    18 FD7: asset_id -> investor_user_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity
    19 FD8: weight_user_id -> weight_current, weight_height, weight_goal_weight, weight_goal_calories
    20 FD9: daily_intake_id -> weight_user_id, daily_intake_date, daily_intake_calories
    21 FD10: discipline_user_id -> user_id
    22 FD11: custom_tracking_id -> user_id, custom_tracking_name
    23 FD12: task_id -> discipline_user_id, custom_tracking_id, task_name, task_finished
    24 FD13: daily_completion_id -> user_id, daily_completion_date, daily_completion_percent
    25 FD14: (task_id, daily_completion_id) -> /
    26 FD15: finance_user_id -> finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit
    27 FD16: income_id -> finance_user_id, income_date, income_amount
    28 Леви и десен дел:
     13- **FD1:** `user_id -> email, username, password`
     14- **FD2:** `email -> user_id, username, password`
     15- **FD3:** `username -> user_id, email, password`
     16- **FD4:** `training_user_id -> training_gender, training_age, training_weight`
     17- **FD5:** `training_id -> training_user_id, training_date, training_type, training_duration, training_calories`
     18- **FD6:** `investor_user_id -> user_id`
     19- **FD7:** `asset_id -> investor_user_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity`
     20- **FD8:** `weight_user_id -> weight_current, weight_height, weight_goal_weight, weight_goal_calories`
     21- **FD9:** `daily_intake_id -> weight_user_id, daily_intake_date, daily_intake_calories`
     22- **FD10:** `discipline_user_id -> user_id`
     23- **FD11:** `custom_tracking_id -> user_id, custom_tracking_name`
     24- **FD12:** `task_id -> discipline_user_id, custom_tracking_id, task_name, task_finished`
     25- **FD13:** `daily_completion_id -> user_id, daily_completion_date, daily_completion_percent`
     26- **FD14:** `(task_id, daily_completion_id) -> /`
     27- **FD15:** `finance_user_id -> finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit`
     28- **FD16:** `income_id -> finance_user_id, income_date, income_amount`
    2929
    30 Леви: user_id, email, username, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id
    31 Десен: password, training_gender, training_age, training_weight, training_date, training_type, training_duration, training_calories, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_date, daily_intake_calories, custom_tracking_name, task_name, task_finished, daily_completion_date, daily_completion_percent, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_date, income_amount
    32 Леви и десен дел:
     30**Леви и десен дел:**
    3331
    34 user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id
    35 == Глобална релација
     32- **Леви:** `user_id, email, username, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id`
     33- **Десен:** `password, training_gender, training_age, training_weight, training_date, training_type, training_duration, training_calories, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_date, daily_intake_calories, custom_tracking_name, task_name, task_finished, daily_completion_date, daily_completion_percent, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_date, income_amount`
    3634
    37 R = { user_id, email, username, password, training_user_id, training_gender, training_age, training_weight, training_id, training_date, training_type, training_duration, training_calories, investor_user_id, asset_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_user_id, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_id, daily_intake_date, daily_intake_calories, discipline_user_id, custom_tracking_id, custom_tracking_name, task_id, task_name, task_finished, daily_completion_id, daily_completion_date, daily_completion_percent, finance_user_id, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_id, income_date, income_amount }
     35**Леви и десен дел:**
    3836
    39 == Покривачи
     37- `user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id`
    4038
    41 user_id+ = { user_id, email, username, password } -> не ги содржи сите атрибути
    42 training_user_id+ = { training_user_id, training_gender, training_age, training_weight } -> не ги содржи сите атрибути
    43 training_id+ = { training_id, training_user_id, training_date, training_type, training_duration, training_calories } -> не ги содржи сите атрибути
    44 investor_user_id+ = { investor_user_id, user_id } -> не ги содржи сите атрибути
    45 asset_id+ = { asset_id, investor_user_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity } -> не ги содржи сите атрибути
    46 weight_user_id+ = { weight_user_id, weight_current, weight_height, weight_goal_weight, weight_goal_calories } -> не ги содржи сите атрибути
    47 daily_intake_id+ = { daily_intake_id, weight_user_id, daily_intake_date, daily_intake_calories } -> не ги содржи сите атрибути
    48 discipline_user_id+ = { discipline_user_id, user_id } -> не ги содржи сите атрибути
    49 custom_tracking_id+ = { custom_tracking_id, user_id, custom_tracking_name } -> не ги содржи сите атрибути
    50 task_id+ = { task_id, discipline_user_id, custom_tracking_id, task_name, task_finished } -> не ги содржи сите атрибути
    51 daily_completion_id+ = { daily_completion_id, user_id, daily_completion_date, daily_completion_percent } -> не ги содржи сите атрибути
    52 finance_user_id+ = { finance_user_id, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit } -> не ги содржи сите атрибути
    53 income_id+ = { income_id, finance_user_id, income_date, income_amount } -> не ги содржи сите атрибути
    54 {task_id, daily_completion_id}+ = { task_id, daily_completion_id } -> не ги содржи сите атрибути
    55 == Спојување покривачи
     39== **Глобална релација**
     40
     41`R = { user_id, email, username, password, training_user_id, training_gender, training_age, training_weight, training_id, training_date, training_type, training_duration, training_calories, investor_user_id, asset_id, asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity, weight_user_id, weight_current, weight_height, weight_goal_weight, weight_goal_calories, daily_intake_id, daily_intake_date, daily_intake_calories, discipline_user_id, custom_tracking_id, custom_tracking_name, task_id, task_name, task_finished, daily_completion_id, daily_completion_date, daily_completion_percent, finance_user_id, finance_spending_budget, finance_saving_budget, finance_investing_budget, finance_donation_budget, finance_credit, income_id, income_date, income_amount }`
     42
     43== **Покривачи**
     44
     45- **`user_id+`** = { `user_id`, `email`, `username`, `password` } -> **не ги содржи сите атрибути**
     46- **`training_user_id+`** = { `training_user_id`, `training_gender`, `training_age`, `training_weight` } -> **не ги содржи сите атрибути**
     47- **`training_id+`** = { `training_id`, `training_user_id`, `training_date`, `training_type`, `training_duration`, `training_calories` } -> **не ги содржи сите атрибути**
     48- **`investor_user_id+`** = { `investor_user_id`, `user_id` } -> **не ги содржи сите атрибути**
     49- **`asset_id+`** = { `asset_id`, `investor_user_id`, `asset_ticker_symbol`, `asset_buy_price`, `asset_buy_date`, `asset_quantity` } -> **не ги содржи сите атрибути**
     50- **`weight_user_id+`** = { `weight_user_id`, `weight_current`, `weight_height`, `weight_goal_weight`, `weight_goal_calories` } -> **не ги содржи сите атрибути**
     51- **`daily_intake_id+`** = { `daily_intake_id`, `weight_user_id`, `daily_intake_date`, `daily_intake_calories` } -> **не ги содржи сите атрибути**
     52- **`discipline_user_id+`** = { `discipline_user_id`, `user_id` } -> **не ги содржи сите атрибути**
     53- **`custom_tracking_id+`** = { `custom_tracking_id`, `user_id`, `custom_tracking_name` } -> **не ги содржи сите атрибути**
     54- **`task_id+`** = { `task_id`, `discipline_user_id`, `custom_tracking_id`, `task_name`, `task_finished` } -> **не ги содржи сите атрибути**
     55- **`daily_completion_id+`** = { `daily_completion_id`, `user_id`, `daily_completion_date`, `daily_completion_percent` } -> **не ги содржи сите атрибути**
     56- **`finance_user_id+`** = { `finance_user_id`, `finance_spending_budget`, `finance_saving_budget`, `finance_investing_budget`, `finance_donation_budget`, `finance_credit` } -> **не ги содржи сите атрибути**
     57- **`income_id+`** = { `income_id`, `finance_user_id`, `income_date`, `income_amount` } -> **не ги содржи сите атрибути**
     58- **`{task_id, daily_completion_id}+`** = { `task_id`, `daily_completion_id` } -> **не ги содржи сите атрибути**
     59
     60== **Спојување покривачи**
    5661
    5762Бидејќи атрибутите што се појавуваат само на левата страна не можат да се изведат на друг начин, тие мора да бидат дел од примарниот клуч.
    … …  
    5964Земајќи ги сите леви атрибути заедно, добиваме минимален суперклуч:
    6065
    61 { user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id }
     66`{ user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id }`
    6267
    6368Во нашата нормализирана конструкција, ова е теоретскиот глобален кандидат-ключ на де-нормализираната релација.
    6469
    65 Избран примарен клуч: { user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id }
     70Избран примарен клуч: **`{ user_id, training_user_id, training_id, investor_user_id, asset_id, weight_user_id, daily_intake_id, discipline_user_id, custom_tracking_id, task_id, daily_completion_id, finance_user_id, income_id }`**
    6671
    67 == Проверка за 1НФ
     72== **Проверка за 1НФ**
    6873
    69 Бидејќи релацијата содржи повторливи групи и неатомски листи во де-нормализираниот поглед, не ја задоволува 1НФ.
     74Бидејќи релацијата содржи повторливи групи и неатомски листи во де-нормализираниот поглед, **не ја задоволува 1НФ**.
    7075
    71 == Декомпозиција по 1НФ
     76== **Декомпозиција по 1НФ**
    7277
    73 Релација што се анализира
     78**Релација што се анализира**
    7479
    75 R
     80`R`
    7681
    77 Проблем
     82**Проблем**
    7883
    7984Лист атрибутите и повторливите групи не се атомски.
    8085
    81 Прва декомпозиција
     86**Прва декомпозиција**
    8287
    83 TASKS(task_id, discipline_user_id, custom_tracking_id, task_name, task_finished)
    84 TASK_DAILY_COMPLETION(task_id, daily_completion_id)
    85 Резултат
     88- `TASKS(task_id, discipline_user_id, custom_tracking_id, task_name, task_finished)`
     89- `TASK_DAILY_COMPLETION(task_id, daily_completion_id)`
     90
     91**Резултат**
    8692
    8793Се добиваат атомски вредности и релации со локални клучеви.
    8894
    89 == Проверка за 2НФ
     95== **Проверка за 2НФ**
    9096
    91 R не ја задоволува 2НФ поради парцијални зависности, на пример:
     97`R` **не ја задоволува 2НФ** поради парцијални зависности, на пример:
    9298
    93 user_id -> email, username, password
    94 training_user_id -> training_gender, training_age, training_weight
    95 asset_id -> asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity
    96 == Декомпозиција по 2НФ
     99- `user_id -> email, username, password`
     100- `training_user_id -> training_gender, training_age, training_weight`
     101- `asset_id -> asset_ticker_symbol, asset_buy_price, asset_buy_date, asset_quantity`
     102
     103== **Декомпозиција по 2НФ**
    97104
    98105Атрибутите се групираат според тоа од кој клуч зависат:
    99106
    100 USERS(user_id, email, username, password)
    101 TRAINING_USERS(user_id, gender, age, weight)
    102 TRAINING_SESSIONS(training_id, training_user_id, date, type, duration, calories)
    103 INVESTOR_USERS(user_id)
    104 ASSETS(asset_id, user_id, ticker_symbol, buy_price, buy_date, quantity)
    105 WEIGHT_USERS(user_id, weight, height, goal_weight, goal_calories)
    106 DAILY_INTAKES(daily_intake_id, user_id, date, calories)
    107 DISCIPLINE_USERS(user_id)
    108 CUSTOM_TRACKING_CATEGORIES(custom_tracking_id, user_id, name)
    109 TASKS(task_id, discipline_user_id, custom_tracking_id, task_name, task_finished)
    110 DAILY_COMPLETION(daily_completion_id, user_id, date, procent)
    111 TASK_DAILY_COMPLETION(task_id, daily_completion_id)
    112 FINANCE_USERS(user_id, spending_budget, saving_budget, investing_budget, donation_budget, credit)
    113 INCOMES(income_id, user_id, date, amount)
    114 == Проверка за 3НФ
     107- **`USERS(user_id, email, username, password)`**
     108- **`TRAINING_USERS(user_id, gender, age, weight)`**
     109- **`TRAINING_SESSIONS(training_id, training_user_id, date, type, duration, calories)`**
     110- **`INVESTOR_USERS(user_id)`**
     111- **`ASSETS(asset_id, user_id, ticker_symbol, buy_price, buy_date, quantity)`**
     112- **`WEIGHT_USERS(user_id, weight, height, goal_weight, goal_calories)`**
     113- **`DAILY_INTAKES(daily_intake_id, user_id, date, calories)`**
     114- **`DISCIPLINE_USERS(user_id)`**
     115- **`CUSTOM_TRACKING_CATEGORIES(custom_tracking_id, user_id, name)`**
     116- **`TASKS(task_id, discipline_user_id, custom_tracking_id, task_name, task_finished)`**
     117- **`DAILY_COMPLETION(daily_completion_id, user_id, date, procent)`**
     118- **`TASK_DAILY_COMPLETION(task_id, daily_completion_id)`**
     119- **`FINANCE_USERS(user_id, spending_budget, saving_budget, investing_budget, donation_budget, credit)`**
     120- **`INCOMES(income_id, user_id, date, amount)`**
     121
     122== **Проверка за 3НФ**
    115123
    116124Ги разгледуваме релациите добиени по 2НФ.
    … …  
    118126Проблематични транзитивни/изведени атрибути се:
    119127
    120 num_tasks
    121 tasks
    122 weight_user_id во TRAINING_SESSIONS како непотребна зависност за оваа верзија на моделот
    123 == Декомпозиција по 3НФ
     128- **`num_tasks`**
     129- **`tasks`**
     130- **`weight_user_id`** во `TRAINING_SESSIONS` како непотребна зависност за оваа верзија на моделот
    124131
    125 DISCIPLINE_USERS(user_id) -> се задржува само идентификаторот што ја врзува дисциплинската улога со USERS.
     132== **Декомпозиција по 3НФ**
    126133
    127 CUSTOM_TRACKING_CATEGORIES(custom_tracking_id, user_id, name) -> се задржува само името на категоријата, без броење и листи на задачи.
     1341. **`DISCIPLINE_USERS(user_id)`** -> се задржува само идентификаторот што ја врзува дисциплинската улога со `USERS`.
    128135
    129 TRAINING_SESSIONS(training_id, training_user_id, date, type, duration, calories) -> сесијата се врзува само со training_user_id.
     1362. **`CUSTOM_TRACKING_CATEGORIES(custom_tracking_id, user_id, name)`** -> се задржува само името на категоријата, без броење и листи на задачи.
    130137
    131 Резултат
     1383. **`TRAINING_SESSIONS(training_id, training_user_id, date, type, duration, calories)`** -> сесијата се врзува само со `training_user_id`.
     139
     140**Резултат**
    132141
    133142Нема не-клучен атрибут што зависи од друг не-клучен атрибут во истата релација.
    134143
    135 == Проверка за БКНФ
     144== **Проверка за БКНФ**
    136145
    137146Сите добиени релации се во БКНФ, бидејќи секој детерминант е кандидат-ключ во својата релација.
    … …  
    139148Особено:
    140149
    141 USERS ги задржува алтернативните клучеви email и username
    142 TASK_DAILY_COMPLETION(task_id, daily_completion_id) е спојна релација без не-клучни атрибути
    143 профилните релации со user_id се чисти 1:1 продолжувања на USERS
    144 == Финален резултат и дискусија
     150- **`USERS`** ги задржува алтернативните клучеви `email` и `username`
     151- **`TASK_DAILY_COMPLETION(task_id, daily_completion_id)`** е спојна релација без не-клучни атрибути
     152- профилните релации со `user_id` се чисти 1:1 продолжувања на `USERS`
    145153
    146 == Нормализиран релациски модел
     154== **Финален резултат и дискусија**
     155
     156== **Нормализиран релациски модел**
    147157
    148158Финалниот модел што го користиме во тековната имплементација е:
    149159
    150 USERS
    151 TRAINING_USERS
    152 TRAINING_SESSIONS
    153 INVESTOR_USERS
    154 ASSETS
    155 WEIGHT_USERS
    156 DAILY_INTAKES
    157 DISCIPLINE_USERS
    158 CUSTOM_TRACKING_CATEGORIES
    159 TASKS
    160 DAILY_COMPLETION
    161 TASK_DAILY_COMPLETION
    162 FINANCE_USERS
    163 INCOMES
    164 == Дискусија
     160- **`USERS`**
     161- **`TRAINING_USERS`**
     162- **`TRAINING_SESSIONS`**
     163- **`INVESTOR_USERS`**
     164- **`ASSETS`**
     165- **`WEIGHT_USERS`**
     166- **`DAILY_INTAKES`**
     167- **`DISCIPLINE_USERS`**
     168- **`CUSTOM_TRACKING_CATEGORIES`**
     169- **`TASKS`**
     170- **`DAILY_COMPLETION`**
     171- **`TASK_DAILY_COMPLETION`**
     172- **`FINANCE_USERS`**
     173- **`INCOMES`**
     174
     175== **Дискусија**
    165176
    166177Разлики во однос на претходниот дизајн:
    167178
    168 Се отстранети num_tasks и tasks од дисциплинските табели.
    169 Се отстранета непотребната релација weight_user_id од TRAINING_SESSIONS.
    170 Се задржуваат профилните табели со user_id како заеднички примарен и странски клуч.
     179- Се отстранети **`num_tasks`** и **`tasks`** од дисциплинските табели.
     180- Се отстранета непотребната релација **`weight_user_id`** од `TRAINING_SESSIONS`.
     181- Се задржуваат профилните табели со **`user_id`** како заеднички примарен и странски клуч.
     182
    171183Одлука за следните фази:
    172184
    173 Овој нормализиран модел останува извор на вистина.
    174 API форматот може да остане стабилен, додека внатрешната шема е нормализирана.
    175 DDL и DML скриптите треба да ја следат оваа шема.
     185- **Овој нормализиран модел** останува извор на вистина.
     186- **API форматот** може да остане стабилен, додека внатрешната шема е нормализирана.
     187- **DDL и DML скриптите** треба да ја следат оваа шема.
     188