Нормализација
Ја дизајнирав базата на податоци со surrogate примарни клучеви(system-generated identifier) со една атрибутна колона (на пр. user_id
, transaction_id
) за едноставност и конзистентност. Вака, секој атрибут кој што не е клуч, директно зависи од примарниот клуч, што значи дека шемата ги исполнува 1NF, 2NF и 3NF/BCNF.
Единствената намерна редундантност е колоната net_amount
во TRANSACTION
. Ја вклучив затоа што овозможува побрзи пребарувања и извештаи, иако е изведлива од TRANSACTION_BREAKDOWN
. Ова беше свесен компромис заради перформанси.
Кај many-to-many табелите (TRANSACTION_BREAKDOWN
и TAG_ASSIGNED_TO_TRANSACTION
) користам surrogate клучеви заради конзистентност на целата шема иако композитни клучеви би биле построго нормализирано решение, surrogate пристапот обезбедува унифицирана структура и јасност.
Анализа по Табела
1. USER
USER (user_id, user_name, email, password)
user_id → user_name, email, password
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч.
Додадов UNIQUE ограничување на email затоа што е природен идентификатор.
2. TRANSACTION_ACCOUNT
TRANSACTION_ACCOUNT (transaction_account_id, account_name, balance, user_id* (USER))
transaction_account_id → account_name, balance, user_id
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч.
3. TRANSACTION
TRANSACTION (transaction_id, transaction_name, amount, net_amount, date)
transaction_id → transaction_name, amount, net_amount, date
Атрибутот net_amount
може да се изведе од TRANSACTION_BREAKDOWN
. Го задржав намерно заради перформанси, за да избегнам постојано пресметување. За да нема неконзистентност, ќе се одржува преку triggers и апликациска логика.
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч, со свесен компромис.
4. TRANSACTION_BREAKDOWN
TRANSACTION_BREAKDOWN (transaction_breakdown_id, transaction_id* (TRANSACTION), transaction_account_id* (TRANSACTION_ACCOUNT), spent_amount, earned_amount)
transaction_breakdown_id → transaction_id, transaction_account_id, spent_amount, earned_amount
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч.
Го задржав surrogate примарниот клуч за унифициран пристап.
5. TAG
TAG (tag_id, tag_name)
tag_id → tag_name
tag_name → tag_id бидејќи имињата на тагови се уникатни.
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч.
Го дефинирав UNIQUE (tag_name) за да обезбедам интегритет.
6. TAG_ASSIGNED_TO_TRANSACTION
TAG_ASSIGNED_TO_TRANSACTION(tag_assigned_to_transaction_id, tag_id* (TAG), transaction_id* (TRANSACTION))
tag_assigned_to_transaction_id → tag_id, transaction_id
- 1NF: Сите атрибути се атомски, нема повторувачки групи.
- 2NF: Сите табели имаат едноатрибутни surrogate примарни клучеви → нема делумни зависности.
- 3NF/BCNF: Сите атрибути кои не се клучеви зависат само од примарниот клуч.
И овде користам surrogate клуч за конзистентност, но истовремено додадов UNIQUE(tag_id, transaction_id) за да спречам дупликати.
Шемата е во 3NF (практично BCNF) за сите табели. Единствениот свесен исклучок е net_amount
во TRANSACTION
, кој е додаден заради перформанси.