wiki:normalization

Нормализација - 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) само десно
email ✓ (FD3) ✓ (FD1) и лево и десно
role ✓ (FD1) само десно
auth_provider само лево
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 - нема функционална зависност од единечен детерминант, туку претставува множество вредности.

Декомпозиција - Извлекување на auth_provider

Last modified 24 hours ago Last modified on 02/27/26 04:42:12
Note: See TracWiki for help on using the wiki.