= Нормализација и Подобрување на дизајн == Функционални зависности(ФЗ) Со цел целосно репрезентирање на атрибутите присутни во релациското мапирање, одредени атрибути со исти имиња ќе бидат преименувани. Лесно се заприметуваат таквите атрибути во релацијата R, на пр. **user(id) -> user_id** и **permission(name) -> permission_name**. {{{ R( user: username, description, password, registered_at, email, sex,is_active,name, user_id #9 feedback: feedback_submission_type, feedback_created_at, feedback_description submission: submission_id, submission_status, submission_created_at, submission_description, blacklisted_user: blacklisted_start_date, blacklisted_end_date, reason tag: tag_name, #20 thread: thread_id, thread_created_at, thread_content topic_thread: guidelines, topic_title, parent_id project_thread: repo_url, project_title, is_moderated_by: moderator_started_at, associated_with: asc_started_at, asc_ended_at, channel: channel_name, channel_description, project_resource: resource_id, permissions: perm_name, project_roles: pr_name, pr_id, pr_override_type, sends_message_in: msg_send_at, msg_content, moderator: moderator_id ) }}} === Иницијални ФЗ 1. {{{ user_id -> username, description, password, registered_at, email, sex,is_active,name }}} 2. {{{ username -> user_id, description, password, registered_at, email, sex,is_active,name }}} 3. {{{ submission_id -> feedback_submission_type, feedback_created_at, feedback_description }}} 4. {{{ submission_id -> submission_status, submission_created_at, submission_description }}} 5. {{{ {user_id,moderator_id, thread_id, blacklisted_start_date} -> blacklisted_end_date, reason }}} 6. {{{ {thread_id, moderator_id} -> moderator_started_at }}} 7. {{{ thread_id -> thread_created_at, thread_content }}} 8. {{{ thread_id -> guidelines, topic_title, parent_id }}} 9. {{{ thread_id -> repo_url, project_title }}} 10. {{{ {thread_id, user_id } -> asc_started_at, asc_ended_at }}} 11. {{{ {thread_id, channel_name} -> channel_description }}} 12. {{{ resource_id -> channel_description, channel_name, thread_id }}} 13. {{{ {thread_id, msg_send_at, user_id } -> msg_content }}} 14. {{{ pr_id -> pr_name, pr_override_type }}} 15. {{{ moderator_id -> user_id }}} 16. {{{ parent_id -> thread_id }}} 17. {{{ project_title -> repo_url, thread_id, thread_created_at, thread_content }}} 18. {{{ {parent_id, topic_title} -> guidelines, thread_id, thread_created_at, thread_content }}} 19. {{{ {pr_name, thread_id} -> pr_override_type }}} === Изведени ФЗ 1. {{{ resource_id -> thread_created_at, thread_content }}} 2. {{{ resource_id -> guidelines, topic_title, parent_id }}} 3. {{{ resource_id -> repo_url, project_title }}} 4. {{{ moderator_id -> user_id }}} 5. {{{ parent_id -> thread_id }}} === Анализа на функционални зависности За анализата на функционални зависности ќе го користиме методот на LHS/RHS поделба. Според овај метод потребно е да ги поделиме атрибутите во 3 групи, односно атрибути што се среќаваат на лева страна од Функционалните зависности(LHS) и според истата логика атрибути на десна страна и атрибути кои се среќаваат на 2те страни. > **LHS**: >> {{{ submission_id, moderator_id,blacklisted_start_date, resource_id, msg_send_at,pr_id,tag_name }}} > **RHS**: >> {{{ description, password, registered_at, email, sex,is_active,name, feedback_submission_type, feedback_created_at, feedback_description, submission_status, submission_created_at, submission_description,blacklisted_end_date, reason, tag_name,thread_created_at, thread_content, guidelines,repo_url, moderator_started_at, asc_started_at, channel_description, perm_name, pr_override_type, msg_content }}} > **LHS & RHS**: >> {{{ user_id,thread_id,username,channel_name,parent_id,project_title,topic_title, pr_name }}} == Нормализација === Сегашна нормална форма Имајќи предвид дека guidelines e повеќе вредносен атрибути, доаѓаме до заклучок дека сегашната имплементација на релација не е ни во 1NF форма. === Декомпозиција на R во 1NF Со оделување на guidelines во посебна релација {{{ R1(thread_id, guideline) }}} и {{{ R2(username, thread_id, password...) }}} постигнуваме релациите да се во 1NF. Според досега разгледаното за R1(thread_id, guideline) ги имаме следниве ФЗ: 1. {{{ thread_id -> thread_id }}} 2. {{{ guideline -> guideline }}} Според функционалните зависимости, единствената комбинација на атрибути која го задоволува условот за супер клуч е {{{ {thread_id, guideline} }}}, бидејќи {{{ {thread_id, guideline}+ = {thread_id, guideline} }}}. Сепак, со цел да оптимизираме операциите на базата (особено внесување и пребарување), ќе воведеме нов сурогат клуч **id** како примарен клуч. Заедно со него ги додаваме и следниве ФЗ {{{ id -> thread_id, guideline }}}. Ова е практично бидејќи природниот клуч {{{ {thread_id, guideline} }}} содржи guideline, која е varchar атрибут со променлива големина. Ако се користеше само природниот клуч, PostgreSQL ќе креираше B-tree индекс врз guideline, кој е поголем по големина и поради тоа побавно ќе се ажурира при **DRU** операции (потребни се повеќе IO страници за индексирање и податоци). Со воведување на сурогат клуч **id** како мал фиксно-димензионален атрибут (на пр. serial или bigserial), индексите се помали и операциите се поефикасни. Со ова R1 ни се совпаѓат со релацијата **topic_guidelines**, отсега понатаму ќе ја референцираме како таква. === Декомпозиција R1 до BCNF Според следниве ФЗ за R1: 1. {{{ thread_id -> thread_id }}} 2. {{{ guideline -> guideline }}} 3. {{{ id -> thread_id, guideline }}} Според тоа што само **id** ги определува сите атрибути({{{ id+ -> id,thread_id,guideline}}}) следува дека единствен супер клуч е **id**. Клуч за оваа релациja би бил **id**, бидејќи неговиот затварач е {{{ id+ = {thread_id, guideline} }}} и е најмал затварач кој ја определува целата релација. Според 2NF релацијата не смеe да содржи парцијални зависности. Ова веќе е задоволено од ФЗ за R1. Според 3NF релацијата потребно е секоја ФЗ(X->A) да ги задоволи следниве својства: 1. X e супер клуч на R 2. А е примарен атрибут во R. Според ова релацијата е веќе во 3NF. Според BCNF секоја релација потребно е да го задоволува следново својство: "За секое нетривијално (X->A) важи дека X е суперклуч на R". Според тоа што **id** e клуч на R1, следува дека релацијата е во BCNF. === Декомпозиција R2 во 2NF Најпрвин да согледаме дека во било кој супер клуч атрибутите кои се присутни само на левата страна мора да бидат вклучени. Најпрвин да започниме само со тие атрибути: {{{ {submission_id, moderator_id,blacklisted_start_date, resource_id, msg_send_at,pr_id }+ = {} }}} Според тоа што затворачот ги опфаќа сите атрибути може да се заклучи дека ова е најминималното множество чиишто покривач ја дава целата релација, што значи дека е примарен клуч. Имајќи во предвид примарниот клуч можит да ги изведиме следниве релации, притоа кај релациите кај кои има совпаѓање со некоја релација од релационото мапирање, ќе ги додаваме нивните имиња. {{{ R21(user_id,username, description, password, register_at, email,sex,is_active,name) == users }}} R22(project_title,repo_url,topic_title,guidelines,parent,thread_created_at,content) {{{ R23(thread_id,channel_name,channel_description, channel_creator_id) == channel }}} {{{ R24(thread_id,moderator_id,user_id,start_date,end_date) }}} {{{ R25(submission_id,status,submission_description,submission_created_at, submission_type,feedback_created_at,feedback_description, feedback_creator_id, submission_creator_id) }}} #Tuka ke imame problem, ama mozhit da rechime deka procenavme deka ke imat dosta nullki pa zaradi to rekovme da se odelat vo posebna relacija. {{{ R26(thread_id,user_id, start_at_developer,end_at_developer) == developer_associated_with_project }}} {{{ R27(thread_id, channel_name, message_sent_by_id, sent_at, message_content) === messages}}} {{{ R28(thread_id,custom_role_name,custom_role_description) == project_roles }}} {{{ R29(thread_id,moderator_id,moderator_started_at) == topic_threads_moderators}}}