Chapter 9
Normalization
Database အခြေခံကို CRUD သိပြီဆိုရင်တော့ Normalization ကို လေ့လာလို့ ရပါပြီ။ Database ကို ဖန်တီးသည့် အခါမှာ Normalization တွေကို level အလိုက် ခွဲပြီး ဖန်တီးပါတယ်။
Normalization ဆိုတာကတော့ Data တွေ ဖောင်းပွမှု မရှိအောင် နဲ့ Table တွေ ချိတ်ဆက်ပြီး အသုံးပြုနိုင်အောင် အဆင့်ဆင့် ခွဲချပြီး data တွေ အဆင်ပြေ ကျစ်လစ်အောင် ဖန်တီးထားခြင်း ဖြစ်ပါတယ်။
Normalization မှာ
- 1NF (First Normal Form)
- 2NF (Second Normal Form)
- 3NF (Third Normal Form)
- BCNF (Boyce-Codd Normal Form)
စသည်ဖြင့် ရှိပါတယ်။
Normalization မလုပ်ထားသည့် အခါမှာ Data တွေကို Insert/Delete/Update ပြုလုပ်သည့် အခါမှာ အဆင်မပြေတော့ပါဘူး။
ဥပမာ ကြည့်ရအောင်။
rollno | name | branch | hod | office_tel |
---|---|---|---|---|
1 | Aung Moe | CS | U Kyaw | +9599999999 |
2 | Khin Khin | CS | U Kyaw | +9599999999 |
3 | Myo Min | CS | U Kyaw | +9599999999 |
4 | Kyaw Gyi | CS | U Kyaw | +9599999999 |
အထက်ပါ Table ကို ကြည့်ရင် Branch , HOD (Head of Department), Office Telephone စတာတွေက တူပြီး ထပ်နေတာကို တွေ့ရပါလိမ့်မယ်။ ကျောင်းသား အသစ်ထည့်သည့် အခါမှာ data တွေကို ထပ်ပြီး ထပ်နေလိမ့်မယ်။ Table size ဟာလည်း ကြီးနေပါလိမ့်မယ်။
ဖျက်သည့်အခါမှာလည်း branch information တွေပါ ပျက်ကုန်ပါတယ်။ Student မရှိတော့သည့်အခါမှာ branch information တွေပါ ပျောက်ကုန်ပါလိမ့်မယ်။ U Kyaw ကနေ U Min ပြောင်းသွားသည့်အခါမှာ တစ်ကြောင်းဆီကို ပြန်ပြောင်းပေးနေရပါမယ်။
Normalization ပြုလုပ်သည့်အခါမှာတော့ Student Table နဲ့ Branch information ခွဲထုတ်ပါမယ်။
Branch Table
branch | hod | office_tel |
---|---|---|
CS | U Kyaw | +9599999999 |
Student Table
rollno | name | branch |
---|---|---|
1 | Aung Moe | CS |
2 | Khin Khin | CS |
3 | Myo Min | CS |
4 | Kyaw Gyi | CS |
အခု ဆိုရင် Student တစ်ယောက်ထည့်ရင် branch name ပဲ ထည့်ရပါတတော့မယ်။ Student record တွေ အကုန် ဖျက်လိုက်ရင်တောင် branch information မပျောက်သွားတော့ပါဘူး။
U Kyaw ကနေ U Min ပြောင်းမယ်ဆိုရင်လည်း Branch Table မှာပဲ တစ်ကြောင်းတည်း သွားပြင်လိုက်ရင် ရပါပြီ။
အခုဆိုရင်တော့ Normalization ဘာကြောင့်လိုတယ် ဆိုတာ သဘောပေါက်လောက်ပြီထင်ပါတယ်။
1NF (First Normal Form)
1NF က ပထမဆုံး အဆင့်ဖြစ်သည့်အတွက် လက်ရှိ ရှိနေသည့် data တွေဟာ bad database design ဖြစ်နေမှသာ 1NF ကို စလို့ရပါမယ်။
1NF အတွက် စမယ်ဆိုရင်
- Column တစ်ခုမှာ data တွေဟာ multiple ပါလို့မရပါဘူး။
- Column Value တွေသိမ်းသည့်အခါမှာ same format ဖြစ် ဖို့ လိုပါတယ်။ DOB, Name လို့ သိမ်းထားပြီး နောက် row တစ်ခုမှာ Name, DOB ပြောင်းသိမ်းလို့မရပါဘူး။
- Column တွေမှာ နာမည်ထပ်နေလို့မရပါဘူး။ ဥပမာ Name, Name အစား First_Name, Second_Name လို့ပြောင်းပေးဖို့ လိုပါတယ်။
rollno | name | subject |
---|---|---|
1 | Aung Myo | Java, Python |
2 | Khin Khin | Java |
3 | Myo Min | C++ , C |
4 | Kyaw Gyi | Python |
အထက်ပါ table ကို ကြည့်ရင် subject ထဲမှာ value တစ်ခု ထက် ပိုပါနေတာကို တွေ့နိုင်ပါတယ်။ 1NF နဲ့ ကိုက်အောင် အောက်ပါအတိုင်း ပြင်နိုင်ပါတယ်။
rollno | name | subject |
---|---|---|
1 | Aung Myo | Java |
1 | Aung Myo | Python |
2 | Khin Khin | Java |
3 | Myo Min | C++ |
3 | Myo Min | C |
4 | Kyaw Gyi | Python |
အခုဆိုရင်တော့ 1NF နဲ့ ကိုက်သွားပြီ။ 2NF ကို သွားရအောင်။
2NF (Second Normal Form)
2NF အတွက် လိုက်နာရမယ့် Rule ကတော့
- 1NF လုပ်ထားပြီး ဖြစ်ရမယ်။
- Partial Dependency မဖြစ်ရဘူး
Partial Dependency မဖြစ်ရဘူး အတွက် Dependency ကို နားလည်ဖို့ လိုပါတယ်။
Student Table ကို အရင် ကြည့်ရအောင်။
student_id | name | reg_no | branch | address |
---|---|---|---|---|
1 | Aung Myo | CS-202080702 | CS | No 443, Aw Ba Road, Yangon |
2 | Aung Myo | CT-202080707 | CT | No 43, Bandola Road, Yangon |
အခု table မှာ student_id
က primary key ပါ။ Primary Key ဆိုတာကတော့ table မှာ unique ဖြစ်ပါတယ်။ တနည်းပြောရင် မထပ်ရပါဘူး။ student_id
1 က နှစ်ယောက် ဖြစ်နေလို့ မရပါဘူး။ Primary key ကို indexing အတွက်လည်း အသုံးပြုပါတယ်။ ဥပမာ student_id 2 ရဲ့ branch ကို ပြပါဆိုရင် CT ဆိုတာကို တစ်ခါတည်း သိနိုင်သည့် သဘောပါ။ ကျွန်တော် တို့ ဟာ တခြား table တွေနဲ့ တွဲ သုံးဖို့က stuent_id တစ်ခု ပဲလိုပါတယ်။ အခြား column တွေဟာ student_id
ပေါ်မှာ မှီခိုနေပါတယ်။ အခုဆိုရင် Dependency ကို နားလည်ပြီ ထင်ပါတယ်။ အခုလိုမျိုးကို Functional Dependency လို့လည်း ခေါ်ပါတယ်။
Partial Dependency
Student Table ပြီးတော့ subject ကို ကြည့်ရအောင်။
subject_id | subject_name |
---|---|
1 | Java |
2 | C++ |
3 | Php |
အခု subject table မှာကတော့ subject_id က primary key အနေနဲ့ သုံးထားပါတယ်။
အခု Student table နဲ့ Subject Table ကို ချိတ်ထားသည့် Score Table တစ်ခု ထပ်ဖြည့်ပါမယ်။
score_id | student_id | subject_id | mark | teacher |
---|---|---|---|---|
1 | 10 1 | 70 | 80 | Java Teacher |
2 | 10 1 | 75 | 81 | C++ Teacher |
3 | 10 2 | 75 | 77 | C++ Teacher |
4 | 11 1 | 80 | 79 | Java Teacher |
score_id က primary key အနေနဲ့ သုံးထားပါတယ်။
Student Id နဲ့ Subject ID ပေါင်းပြီးမှသာ လိုချင်သည့် score ကို ဆွဲထုတ်လို့ရပါမယ်။ Student ID နဲ့ ဆိုရင်တော့ subject_id
၂ ခုရှိနေရင် ၂ ခု ထွက်လာပါလိမ့်မယ်။ subject_id
75 ကို ဆွဲထုတ်ရင် student id တစ်ခု ထက်မက ပါလာပါလိမ့်မယ်။ ဒါကြောင့် score table မှာ student_id
နဲ့ subject_id
ကို ဆွဲထုတ်မှသာ mark ကို ရပါမယ်။ mark က student_id
နဲ့ subject_id
ကို depend ဖြစ်နေပမယ့် teacher ကတော့ subject_id
ပေါ်မှာပဲ depend ဖြစ်နေတာပါ။ အဲဒါကို Partial Dependency လို့ ခေါ်ပါတယ်။
Partial Dependency ကို ဖြေရှင်းခြင်း
2NF အရ Partial Dependency မဖြစ်ရပါဘူး။ Teacher ကို score table ကနေ ခွဲထုတ်ရပါမယ်။ Teacher ကို ထုတ်ပြီးရင် ဘယ်လို အသုံးပြုရမလဲ ဆိုတာကို အမျိုးမျိုး ဖြစ်နိုင်ပါတယ်။
score_id | student_id | subject_id | mark |
---|---|---|---|
1 | 10 1 | 70 | 80 |
2 | 10 1 | 75 | 81 |
3 | 10 2 | 75 | 77 |
4 | 11 1 | 80 | 79 |
subject_id | subject_name | teacher |
---|---|---|
1 | Java | Java Teacher |
Subject table ထဲမှာ Teacher ကို ထည့်နိုင်သလို teacher table သီးသန့် လည်း ခွဲထုတ်နိုင်ပါတယ်။
teacher_id | name |
---|---|
1 | Java Teacher |
2 | PHP Teacher |
ဒါဆိုရင် partial Dependency မဖြစ်တော့ပါဘူး။ အခု 3NF ကို ဆက်လေ့လာရအောင်။
3NF (Third Normal Form)
3NF အတွက်
- 2NF လုပ်ထားပြီး ဖြစ်ရမည်။
- Transitive Dependency မဖြစ်ရပါဘူး။
အခု ကျွန်တော်တို့မှာ အောက်ပါ Table တွေ ရှိပါတယ်။
Student Table
- student_id (Primary Key)
- name
- reg_no
- branch
- address
Score Table
- score_id (Primary Key)
- student_id (Foreign Key)
- subject_id (Foreign Key)
- marks
Subject Table
- subject_id (Primary Key)
- subject_name
- teacher
ကျွန်တော်တို့ exam name နဲ့ total marks ကို ထည့်ဖို့ ကျန်ပါသေးတယ်။ အခု exam name နဲ့ total marks ကို score table ထဲကို ထည့်လိုက်ပါမယ်။
Score Table
- score_id (Primary Key)
- student_id (Foreign Key)
- subject_id (Foreign Key)
- marks
- exam_name
- total_marks
ဥပမာ အားဖြင့် score table က အောက်ကလို ဖြစ်ပါမယ်။
score_id | student_id | subject_id | marks | exam_name | total_marks |
---|---|---|---|---|---|
1 | 23 | 123 | 78 | Workshop | 200 |
exam_name က student_id + subject_id ပေါ်မှာ depend ဖြစ်နေပါတယ်။ Exam name က student ပေါ်မှာ မူတည်ပြီးတော့ ဘယ်သူ ဖြေမှာလဲ ဆိုတာကို သိနိုင်ပါတယ်။ Exam name ဟာလည်း ဘယ် subject လည်း ဆိုတာကို ထပ်ပြီး depend ဖြစ်နေပါတယ်။
သို့ပေမယ့် total marks ကတော့ exam name ပေါ်မှာပဲ depend ဖြစ်ပါတယ်။ exam_name က primary key မဟုတ်ပါဘူး။
အဲဒါက Transitive Dependency ဖြစ်နေတာပါ။၊
အဲဒီ လိုအခါမှာ exam_name နဲ့ total_marks ကို သီးသန့် ခွဲထုတ်ဖို့ လိုပါတယ်။ အဲဒါဟာ 3NF ပါပဲ။ 3NF အတွက် အောက်ပါ အတိုင်း ခွဲထုတ်နိုင်ပါတယ်။
Exam Table
exam_id | exam_name | total_marks |
---|---|---|
1 | Workshop | 200 |
2 | Mains | 70 |
3 | Practicals | 30 |
Score Table
score_id | student_id | subject_id | marks | exam_id |
---|---|---|---|---|
1 | 23 | 123 | 78 | 1 |
အခု ဆိုရင် 3NF ကို သဘောပေါက်ပြီလို ထင်ပါတယ်။
Boyce-Codd Normal Form (BCNF)
Boyce-Codd Normal Form ကို 3.5 NF လို့လည်း ခေါ်ပါတယ်။ အများအားဖြင့် Normalization ကို BCNF အထိပဲလုပ်ကြပါတယ်။ BCNF မှာ
- 3NF ဖြစ်ပြီးသား ဖြစ်ဖို့လိုပါတယ်။
- A ကနေ B ကို Depend ဖြစ်နေဖို့လိုတယ်။ A က super key ဖြစ်နေဖို့ လိုတယ်။
student_id | subject | professor |
---|---|---|
101 | Java | P.Java |
101 | C++ | P.Cpp |
102 | Java | P.Java2 |
103 | C# | P.Chash |
104 | Java | P.Java |
ဒီ Table ကြည့်ရင်
- student id 101 က Java နဲ့ C++ ကို တက်နေပါတယ်။
- subject တိုင်းမှာ သင် သည့် professor နာမည်ပါပါတယ်။
- Subject တစ်ခုကို သင် သည့် professor မတူတာလည်း ဖြစ်နိုင်ပါတယ်။
အခု table မှာ ဆိုရင် student_id + subject
က professor ကို depend ဖြစ်နေပါတယ်။
professor က subject ပေါ်မှာ depend ဖြစ်နေပါတယ်။ သို့ပေမယ့် professor က super key မဟုတ်ပါဘူး။ BCNF နဲ့ အဆင်ပြေအောင် professor ကို table ခွဲထုတ်လိုက်ပါမယ်။
Student Table
student_id | p_id |
---|---|
101 | 1 |
101 | 2 |
Professor Table
p_id | professor | subject |
---|---|---|
1 | P.Java | Java |
2 | P.Cpp | C++ |
အခု ဆိုရင် BCNF နဲ့ ကိုက်ညီမှုရှိသွားပါပြီ။
Intermediate Table
Many To Many tables တွေ အတွက် ချိတ်ဆက်ဖို့ အတွက် intermediate table ကို အသုံးပြုပါတယ်။ ဥပမာ Students တစ်ယောက်ဟာ projects အများကြီး လုပ်ရတယ်။ Projects တစ်ခု ကို studetns အများကြီး က လုပ်ရတယ်။ အဲဒီလိုမျိုး အတွက် Intermediate Table ကို အသုံးပြုရပါတယ်။
Student Table
s_id | name |
---|---|
1 | Aung Aung |
2 | Ko Zin |
3 | Win Win |
4 | Moe Moe |
5 | Yan Aung |
6 | Lin Lat |
Project Table
pj_id | name |
---|---|
1 | Project A |
2 | Project B |
ဒီ table နှစ်ခု ကို many to many ချိတ်ဆက်ဖို့ အတွက် intermediate table လိုအပ်ပါတယ်။
Stu_proj Table
id | s_id | pj_id |
---|---|---|
1 | 2 | 1 |
2 | 5 | 1 |
3 | 6 | 1 |
4 | 1 | 2 |
5 | 3 | 2 |
6 | 4 | 2 |
ဒီ Table မှာ ဆိုရင် Student 2,5,6 က Project A ကို လုပ်ပြီးတော့ Student 1,3,4 ကတော့ Project B ကို လုပ်တာ ကို ဖော်ပြထားပါတယ်။