| Version 4 (modified by , 4 hours ago) ( diff ) |
|---|
Нормализација - TradingMK
Де-нормализирана форма на базата
Универзална релација
Тргнуваме од една единствена универзална релација која ги содржи сите атрибути од целиот домен на апликацијата — сите табели споени во еден единствен запис. Атрибутите се преименувани каде е потребно за да нема дупликати на имиња.
Universal_Relation_TradingMK( user_id, username, password, email, role, auth_provider, portfolio_id, balance, holding_id, holding_quantity, avg_price, stock_id, stock_symbol, stock_name, current_price, last_price, percentage, turnover, last_updated, history_id, history_price, history_timestamp, trade_id, trade_type, trade_status, trade_quantity, price_per_unit, trade_timestamp, trade_stock_symbol, transaction_id, txn_type, txn_quantity, txn_price, txn_timestamp, txn_origin, watchlist_id, price_above, price_below, oauth_token, oauth_email, oauth_provider, oauth_expires_at, oauth_created_at )
Напомени за именување:
- trade_stock_symbol е преименуван (наспроти stock_symbol) за да избегне конфликт на имиња во универзалната релација
- auth_provider е атрибут кој претставува вредност од user_auth_providers - повеќевредносен по природа
- Нема дупликати на имиња на атрибути во универзалната релација
Функционални зависности
Ги идентификуваме сите функционални зависности кои важат глобално во универзалната релација.
F = {
- FD1: user_id → username, password, email, role
- FD2: username → user_id
- FD3: email → user_id
- FD4: portfolio_id → balance, user_id
- FD5: user_id → portfolio_id
- FD6: stock_id → stock_symbol, stock_name, current_price, last_price, percentage, turnover, last_updated
- FD7: stock_symbol → stock_id
- FD8: holding_id → holding_quantity, avg_price, portfolio_id, stock_id
- FD9: history_id → history_price, history_timestamp, stock_id
- FD10: trade_id → trade_type, trade_status, trade_quantity, price_per_unit, trade_timestamp, trade_stock_symbol, portfolio_id
- FD11: transaction_id → txn_type, txn_quantity, txn_price, txn_timestamp, txn_origin, user_id, stock_id
- FD12: watchlist_id → price_above, price_below, user_id, stock_id
- FD13: oauth_token → oauth_email, oauth_provider, oauth_expires_at, oauth_created_at, user_id
}
Кандидат клучеви и примарен клуч
Класификација на атрибути (Лева / Десна страна)
| Атрибут | Лева страна | Десна страна | Класификација |
|---|---|---|---|
| user_id | ✓ (FD1, FD5) | ✓ (FD2, FD3, FD4, FD11, FD12, FD13) | и лево и десно |
| username | ✓ (FD2) | ✓ (FD1) | и лево и десно |
| password | ✗ | ✓ (FD1) | само десно |
| ✓ (FD3) | ✓ (FD1) | и лево и десно | |
| role | ✗ | ✓ (FD1) | само десно |
| auth_provider | ✗ | ✗ | не се јавува во ниедна FD |
| portfolio_id | ✓ (FD4) | ✓ (FD5, FD8, FD10) | и лево и десно |
| balance | ✗ | ✓ (FD4) | само десно |
| holding_id | ✓ (FD8) | ✗ | само лево |
| holding_quantity | ✗ | ✓ (FD8) | само десно |
| avg_price | ✗ | ✓ (FD8) | само десно |
| stock_id | ✓ (FD6) | ✓ (FD7, FD8, FD9, FD11, FD12) | и лево и десно |
| stock_symbol | ✓ (FD7) | ✓ (FD6) | и лево и десно |
| stock_name | ✗ | ✓ (FD6) | само десно |
| current_price | ✗ | ✓ (FD6) | само десно |
| last_price | ✗ | ✓ (FD6) | само десно |
| percentage | ✗ | ✓ (FD6) | само десно |
| turnover | ✗ | ✓ (FD6) | само десно |
| last_updated | ✗ | ✓ (FD6) | само десно |
| history_id | ✓ (FD9) | ✗ | само лево |
| history_price | ✗ | ✓ (FD9) | само десно |
| history_timestamp | ✗ | ✓ (FD9) | само десно |
| trade_id | ✓ (FD10) | ✗ | само лево |
| trade_type | ✗ | ✓ (FD10) | само десно |
| trade_status | ✗ | ✓ (FD10) | само десно |
| trade_quantity | ✗ | ✓ (FD10) | само десно |
| price_per_unit | ✗ | ✓ (FD10) | само десно |
| trade_timestamp | ✗ | ✓ (FD10) | само десно |
| trade_stock_symbol | ✗ | ✓ (FD10) | само десно |
| transaction_id | ✓ (FD11) | ✗ | само лево |
| txn_type | ✗ | ✓ (FD11) | само десно |
| txn_quantity | ✗ | ✓ (FD11) | само десно |
| txn_price | ✗ | ✓ (FD11) | само десно |
| txn_timestamp | ✗ | ✓ (FD11) | само десно |
| txn_origin | ✗ | ✓ (FD11) | само десно |
| watchlist_id | ✓ (FD12) | ✗ | само лево |
| price_above | ✗ | ✓ (FD12) | само десно |
| price_below | ✗ | ✓ (FD12) | само десно |
| oauth_token | ✓ (FD13) | ✗ | само лево |
| oauth_email | ✗ | ✓ (FD13) | само десно |
| oauth_provider | ✗ | ✓ (FD13) | само десно |
| oauth_expires_at | ✗ | ✓ (FD13) | само десно |
| oauth_created_at | ✗ | ✓ (FD13) | само десно |
Атрибути кои се појавуваат САМО на лева страна
Овие атрибути мора да бидат дел од секој кандидат клуч, бидејќи не можат да се изведат од ниедна FD:
- holding_id - мора да биде дел од секој кандидат клуч
- history_id - мора да биде дел од секој кандидат клуч
- trade_id - мора да биде дел од секој кандидат клуч
- transaction_id - мора да биде дел од секој кандидат клуч
- watchlist_id - мора да биде дел од секој кандидат клуч
- oauth_token - мора да биде дел од секој кандидат клуч
- auth_provider - мора да биде дел од секој кандидат клуч (не учествува во ниедна FD; изводливо само преку себе)
Пресметка на затворач
Чекор 1: Започнуваме со задолжителни:
{holding_id, history_id, trade_id, transaction_id, watchlist_id, oauth_token, auth_provider}:
- Од FD8 (holding_id →): holding_quantity, avg_price, portfolio_id, stock_id
- Од FD9 (history_id →): history_price, history_timestamp, stock_id
- Од FD10 (trade_id →): trade_type, trade_status, trade_quantity, price_per_unit,
trade_timestamp, trade_stock_symbol, portfolio_id
- Од FD11 (transaction_id →): txn_type, txn_quantity, txn_price, txn_timestamp, txn_origin,
user_id, stock_id
- Од FD12 (watchlist_id →): price_above, price_below, user_id, stock_id
- Од FD13 (oauth_token →): oauth_email, oauth_provider, oauth_expires_at, oauth_created_at, user_id
- Од FD4 (portfolio_id →): balance, user_id
- Од FD5 (user_id →): portfolio_id
- Од FD1 (user_id →): username, password, email, role
- Од FD6 (stock_id →): stock_symbol, stock_name, current_price, last_price,
percentage, turnover, last_updated
- Од FD7 (stock_symbol →): stock_id
- Од FD2 (username →): user_id
- Од FD3 (email →): user_id
{holding_id, history_id, trade_id, transaction_id, watchlist_id, oauth_token, auth_provider}
= Universal_Relation_TradingMK ✓ (сите атрибути се изводливи)
Проверка за минималност
| Подмножество (отстранет атрибут) | Недостасуваат атрибути | Суперклуч? |
|---|---|---|
| без holding_id | holding_quantity, avg_price | ✗ НЕ |
| без history_id | history_price, history_timestamp | ✗ НЕ |
| без trade_id | trade_type, trade_status, trade_quantity, price_per_unit, trade_timestamp, trade_stock_symbol | ✗ НЕ |
| без transaction_id | txn_type, txn_quantity, txn_price, txn_timestamp, txn_origin | ✗ НЕ |
| без watchlist_id | price_above, price_below | ✗ НЕ |
| без oauth_token | oauth_email, oauth_expires_at, oauth_created_at | ✗ НЕ |
| без auth_provider | auth_provider не е изводливо | ✗ НЕ |
Секој атрибут е неопходен - множеството е минимално.
Избор на примарен клуч
Кандидат клуч (и избран примарен клуч):
PK = {holding_id, history_id, trade_id, transaction_id, watchlist_id, oauth_token, auth_provider}
Образложение: Примарниот клуч е голем бидејќи универзалната релација содржи повеќе независни ентитети (корисници, портфолија, акции, трговски барања, трансакции, watchlist записи, OAuth токени, auth провајдери) кои не се директно поврзани преку функционални зависности. Секој независен ентитет бара барем еден идентификатор во клучот. Клучот е минимален - отстранувањето на кој било атрибут го прави невозможно изведувањето на дел од атрибутите.
Нормална форма пред декомпозиција
Universal_Relation_TradingMK е во 1NF (сите атрибути се атомарни, со исклучок на auth_provider кој е мулти-вредносен). Релацијата НЕ е во 2NF поради следните парцијални зависности - секој идентификатор ги определува само своите атрибути, независно од останатиот примарен клуч:
- FD8: holding_id → holding_quantity, avg_price, portfolio_id, stock_id
- FD9: history_id → history_price, history_timestamp, stock_id
- FD10: trade_id → trade_type, trade_status, ..., portfolio_id
- FD11: transaction_id → txn_type, ..., user_id, stock_id
- FD12: watchlist_id → price_above, price_below, user_id, stock_id
- FD13: oauth_token → oauth_email, oauth_provider, oauth_expires_at, oauth_created_at, user_id
1NF Декомпозиција
Анализа
Анализирана релација: Universal_Relation_TradingMK
Функционални зависности: FD1 - FD13 (сите)
Кандидат клуч / Примарен клуч: {holding_id, history_id, trade_id, transaction_id, watchlist_id, oauth_token, auth_provider}
Нормална форма: Релацијата е делумно во 1NF - атрибутот auth_provider претставува повеќевредносен (multi-valued) атрибут. Еден корисник може да има повеќе auth провајдери (интерен, Google), па оваа вредност не може да биде атомарна во унификованата релација.
Зависност која го предизвикува проблемот: auth_provider е неделива повторувачка вредност поврзана со user_id - нема функционална зависност од единечен детерминант, туку претставува множество вредности.
