174 | | [[span(style="color:#FF0000") complete_closure = {log_id, export_id, punishment_id, r_d_id, report_id}]] |
175 | | |
| 174 | [[span(style="font-size: 20px; color:#FF0000; font-weight: bolder;", complete_closure = { log_id, export_id, punishment_id, r_d_id, report_id } )]] |
| 175 | |
| 176 | === 1NF - Прва Нормална форма |
| 177 | |
| 178 | Оваа нормална форма бара секој атрибут во секоја редица да содржи само една вредност, односно атрибутите да не се составени од повеќе вредности. Не смее да има листи, множества или некои типови на колекции кои во суштина даваат повеќе од една информација. |
| 179 | |
| 180 | Пример за нешто што не би било во нормална форма е доколку се постават повеќе вредности за contact_phone (“071628936”, “078549987”) во иста колона. Ова би го нарушило правилот на 1NF. |
| 181 | |
| 182 | Ако се прегледа целата шема на базата на податоци, ќе може да се заклучи дека таа ја задоволува првата нормална форма, каде не се увидени повторувачки групи или некои неатомски вредности (повеќе вредности под ист атрибут). |
| 183 | |
| 184 | === 2NF - Втора Нормална форма |
| 185 | |
| 186 | Втората нормална форма е задоволена ако е задоволена првата нормална форма и дополнително ако нема парцијални функционални зависности. Подобро објаснето, секој атрибут кој не е примарен, треба целосно да биде функционално зависен од примарниот клуч. |
| 187 | |
| 188 | Во оваа фаза, мегарелацијата R е декомпонирана во неколку логички релации, така што: |
| 189 | * Секој атрибут е целосно функционално зависен од еден атомски примарен клуч |
| 190 | * Нема парцијални функционални зависности |
| 191 | * Секоја релација ја задоволува Втората Нормална Форма (2NF) |
| 192 | |
| 193 | За да ги отстраниме парцијалните зависности потребно е да ги оделиме атрибутите во релации во кои целосно ќе зависат од нивниот клуч: |
| 194 | |
| 195 | export_id -> session_id, export_format, file_name, filter_summary, export_date |
| 196 | |
| 197 | punishment_id -> report_id, value_unit, punishment_type, fine_to_pay, release_date |
| 198 | |
| 199 | log_id -> profile_id, change_description, changed_at |
| 200 | |
| 201 | r_d_id -> diagnosis_id, report_id, added_on |
| 202 | |
| 203 | report_id -> report_type, report_created_at, summary, person_id, location, resolved, crime_type_id, descriptive_punishment, academic_field, institution_id, description_of_report, start_date, end_date, job_role, income_per_month, next_control_date, doctor_id |
| 204 | |
| 205 | === BCNF комбинирано со 3NF |
| 206 | |
| 207 | R1: export_id PK, session_id , export_format, file_name, filter_summary, export_date – во BCNF |
| 208 | |
| 209 | R2: log_id PK, profile_id, change_description, changed_at – во BCNF |
| 210 | |
| 211 | R3: punishment_id PK, report_id, value_unit, punishment_type, fine_to_pay, release_date – во BCNF |
| 212 | |
| 213 | R4: r_d_id PK, diagnosis_id, report_id, added_on – во BCNF |
| 214 | |
| 215 | R5: report_id PK, report_type, report_created_at, summary, person_id, location, resolved, crime_type_id, descriptive_punishment, academic_field, institution_id, description_of_report, start_date, end_date, job_role, income_per_month, next_control_date, doctor_id – е во BCNF, но ќе резултира со многу null полиња во еден запис, по што може да употребиме „''Supertype-Subtype Specialization''“ |
| 216 | |
| 217 | Бидејќи report_id е клуч кај сите, и тие би биле соодветно диференцирани по тип земајќи го во предвид report_type, ќе може да се издвои еден Supertype и од него да произлегуваат соодветно неколку Subtypes. За правилно да го направиме ова, ќе ги гледаме функционалните зависности: |
| 218 | |
| 219 | * R5.1: report_id PK, report_type, report_created_at, summary, person_id – во BCNF |
| 220 | * R5.1.1: report_id PK, location, resolved, crime_type_id, descriptive_punishment – во BCNF |
| 221 | * R5.1.2: report_id PK, academic_field, institution_id, description_of_report – во BCNF |
| 222 | * R5.1.3: report_id PK, start_date, end_date, job_role, income_per_month – во BCNF |
| 223 | * R5.1.4: report_id PK, next_control_date, doctor_id – во BCNF |
| 224 | |
| 225 | Атрибутите од подтип се условни од report_type својството, затоа ги логички подобро би фигурирале во погрануларни релации. Секоја од овие продолжува поединечно да го задоволува својството за BCNF, а со тоа и 3NF. |
| 226 | |
| 227 | R6: остатокот од атрибути = { report_id, export_id, log_id, punishment_id, r_d_id, user_id, user_name, user_surname, email, password_hash, is_user_active, user_created_at, role_id, username, profile_created_at, role_name, role_descrioption, filter_description, searched_at, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – во ниту еден случај не е во BCNF |
| 228 | |
| 229 | Гарантиравме дека role_name е уникатно, па затоа може да издвоиме релација |
| 230 | |
| 231 | Ф.З кои ги гледаме: |
| 232 | * role_id -> role_name |
| 233 | * role_name -> role_description |
| 234 | |
| 235 | R6.1: role_id PK, role_name UNIQUE, role_description – во BCNF |
| 236 | |
| 237 | R6.2: role_id U R6-initial -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, user_name, user_surname, email, password_hash, is_user_active, user_created_at, role_id, username, profile_created_at, filter_description, searched_at, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 238 | |
| 239 | Сега може со корисник да одиме, каде ги гледаме следните Ф.З |
| 240 | |
| 241 | * user_id -> email, user_name, user_surname, password_hash, is_user_active, user_created_at |
| 242 | * email -> user_id |
| 243 | |
| 244 | Бидејќи email е во склоп со функционалната зависност, но тој е исто така уникат, може да кажеме дека имаме алтернативен клуч, по кој исто така може да ги пребаруваме самите записи. |
| 245 | |
| 246 | R6.2.1: user_id PK, email UNIQUE, user_name, user_surname, password_hash, is_user_active, user_created_at – во BCNF |
| 247 | |
| 248 | R6.2.2: user_id U R6.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, username, profile_created_at, filter_description, searched_at, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 249 | |
| 250 | Потоа тргнуваме со следната функционална зависност а тоа е |
| 251 | * profile_id -> user_id, role_id, profile_created_at, username |
| 252 | |
| 253 | R6.2.2.1: profile_id PK, user_id UNIQUE FK→R6.2.1, role_id FK→R6.1, profile_created_at, username – во BCNF |
| 254 | |
| 255 | R6.2.2.2: profile_id U R6.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, filter_description, searched_at, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 256 | |
| 257 | Еве уште една функционална зависност поради која се нарушува правилото за BCNF |
| 258 | * session_id → user_id, filter_description, searched_at |
| 259 | |
| 260 | R6.2.2.2.1: session_id PK, user_id FK→ R6.2.1, filter_description, searched_at – во BCNF |
| 261 | |
| 262 | R 6.2.2.2.2: session_id U R6.2.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 263 | |
| 264 | Следна Ф.З е |
| 265 | * person_id → embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone |
| 266 | |
| 267 | R6.2.2.2.2.1: person_id PK, embg, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone – во BCNF |
| 268 | |
| 269 | R 6.2.2.2.2.2: person_id U R6.2.2.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, institution_name, institution_address, city, type, year_established, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 270 | |
| 271 | Потоа следува |
| 272 | * institution_id -> institution_name, institution_address, city, type, year_established |
| 273 | |
| 274 | R6.2.2.2.2.2.1: institution_id PK, institution_name, institution_address, city, type, year_established – во BCNF |
| 275 | |
| 276 | R 6.2.2.2.2.2: institution_id U R6.2.2.2.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, label, severity_level, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 277 | |
| 278 | * Функционална зависност crime_type_id -> severity_level, label |
| 279 | |
| 280 | R6.2.2.2.2.2.2.1: crime_type_id PK, severity_level, label – во BCNF |
| 281 | |
| 282 | R 6.2.2.2.2.2.2.2: crime_type_id U R6.2.2.2.2.2.2-> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, doctor_name, doctor_surname, specialization, years_of_experience, is_active, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 283 | |
| 284 | * Ф.З doctor_id -> doctor_name, doctor_surname, specialization, years_of_experience, is_active |
| 285 | |
| 286 | R6.2.2.2.2.2.2.2.1: doctor_id PK, doctor_name, doctor_surname, specialization, years_of_experience, is_active – во BCNF |
| 287 | |
| 288 | R 6.2.2.2.2.2.2.2.2: crime_type_id U R6.2.2.2.2.2.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id, short_description, therapy, is_chronic, severity } – сеуште не е во BCNF |
| 289 | |
| 290 | * Ф.З diagnosis_id -> short_description, therapy, is_chronic, severity |
| 291 | |
| 292 | R6.2.2.2.2.2.2.2.2.1: diagnosis_id PK, short_description, therapy, is_chronic, severity – во BCNF |
| 293 | |
| 294 | R 6.2.2.2.2.2.2.2.2.2: crime_type_id U R6.2.2.2.2.2.2.2.2 -> { report_id, export_id, log_id, punishment_id, r_d_id, user_id, role_id} – оваа релација е непотребна бидејќи содржи само клучеви, кои си имаат веќе свои посебни релации, затоа истата не би била додадена во самата шема од табели. |
| 295 | |
| 296 | Издвоени сите релации кои се добиваат на крајот од нормализацијата: |
| 297 | |
| 298 | **EXPORT**(export_id PK, session_id FK→SESSION, export_format, file_name, filter_summary, export_date) |
| 299 | |
| 300 | **LOG**(log_id PK, profile_id FK→PROFILE, changed_at, change_description) |
| 301 | |
| 302 | **PUNISHMENT**(punishment_id PK, report_id FK→CRIMINAL_REPORT, value_unit, punishment_type, fine_to_pay, release_date) |
| 303 | |
| 304 | **MEDICALREPORT_DIAGNOSIS**(r_d_id PK, report_id FK→MEDICAL_REPORT, diagnosis_id FK→DIAGNOSIS, added_on) |
| 305 | |
| 306 | **REPORT**(report_id PK, report_type, report_created_at, summary, person_id FK→PERSON) |
| 307 | |
| 308 | **CRIME_REPORT**(report_id PK/FK→REPORT, location, resolved, crime_type_id FK→CRIME_TYPE, descriptive_punishment) |
| 309 | |
| 310 | **ACADEMIC_REPORT**(report_id PK/FK→REPORT, academic_field, institution_id FK→INSTITUTION, description_of_report) |
| 311 | |
| 312 | **EMPLOYMENT_REPORT**(report_id PK/FK→REPORT, start_date, end_date, job_role, income_per_month) |
| 313 | |
| 314 | **MEDICAL_REPORT**(report_id PK/FK→REPORT, next_control_date, doctor_id FK→DOCTOR) |
| 315 | |
| 316 | **USER**(user_id PK, email UNIQUE, user_name, user_surname, password_hash, is_user_active, user_created_at) |
| 317 | |
| 318 | **PROFILE**(profile_id PK, user_id UNIQUE FK→USER, role_id FK→ROLE, profile_created_at, username) |
| 319 | |
| 320 | **ROLE**(role_id PK, role_name UNIQUE, role_description) (or split ROLE/ROLE_NAME if role_name isn’t unique) |
| 321 | |
| 322 | **SESSION**(session_id PK, user_id FK→USER, filter_description, searched_at) |
| 323 | |
| 324 | **PERSON**(person_id PK, embg UNIQUE, name, surname, gender, date_of_birth, is_alive, date_of_death, address_of_living, contact_phone) |
| 325 | |
| 326 | **INSTITUTION**(institution_id PK, institution_name, institution_address, city, type, year_established) |
| 327 | |
| 328 | **CRIME_TYPE**(crime_type_id PK, label, severity_level) |
| 329 | |
| 330 | **DOCTOR**(doctor_id PK, doctor_name, doctor_surname, specialization, years_of_experience, is_active) |
| 331 | |
| 332 | **DIAGNOSIS**(diagnosis_id PK, short_description, therapy, is_chronic, severity) |
| 333 | |
| 334 | === Заклучок |
| 335 | Процесот на нормализација на базата на податоци Reportium беше успешно спроведен преку систематска примена на теоријата на релациони бази на податоци. Почнувајќи од единечна мега-релација R која ги содржеше сите можни атрибути од системот, преку детална анализа на функционалните зависности, идентификување на кандидат клучеви и примена на алгоритмот за декомпозиција, успешно се постигна Бојс-Кодова нормална форма (BCNF) за сите релации во шемата. |
| 336 | |
| 337 | **''Финалната нормализирана шема се состои од 18 логички поврзани релации кои го опфаќаат целосниот домен на системот Reportium.''** |
| 338 | |
| 339 | Секоја релација има јасно дефиниран примарен клуч, не содржи парцијални или транзитивни функционални зависности, и ги задоволува сите критериуми за добар дизајн според теоријата на релациони бази на податоци. Декомпозицијата е извршена **lossless (без загуба на податоци) и dependency-preserving (со зачувување на функционалните зависности)**. |
| 340 | |
| 341 | Нормализираната шема е налик на самата шема од почетокот, што покажува добар почетен дизајн и додавањето на нови типови на извештаи или нови ентитети во иднина, не би било проблем бидејќи нема да ја наруши самата скалабилност и нормализираност на шемата во базата на податоци. |