Changes between Version 2 and Version 3 of Normalization


Ignore:
Timestamp:
04/20/26 18:39:48 (2 weeks 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