What is Database Normalization?
What is Database Normalization?
The process of structuring a relational database in accordance with a series of so-called normal forms in order to reduce data redundancy and improve data integrity
ขั้นตอนในการจัดการ relational database ให้เป็นรูป normal forms เพื่อลด Data redundancy(การซ้ำซ้อนกันของ Data) และเพิ่ม Data integrity(ความสมบูรณ์ของ Data)
เมื่อพิจารณา Player Table จะพบว่า Table ข้างต้น จะมีปัญหากับ Column PlayerItem อย่างมาก
- Red ได้ Master Ball เพิ่มมาหนึ่งลูก จะอัพเดท PlayerItem ได้อย่างไร ตัด String ยากๆเลยดีไหม?
- อยากจะนับว่า Green มี Item ในกระเป๋ากี่ชิ้น จะนับได้อย่างไร? ตารางนี้ Group มา Count ไม่ได้นะ
- วันหนึ่ง Developer ประกาศว่า Ultra Ball ถูกเปลี่ยนชื่อเป็น Ultimate Ball เราจะ Update ชื่อใน PlayerItem อย่างใด?
การแก้ปัญหาดังกล่าว โดยการลดรูป Database ให้เป็น “Normal Form” นั้น คือความหมายของ “Database Normalization”
First Normal Form (1NF)
First Normal Form (1NF) sets the basic rules to organize the data in a database. A database is said to be in first normal form if it satisfies the following conditions:
Rule 1 (Atomic Values) — Every column of a table should contain only atomic values. An atomic value is a value that cannot be divided further.
Rule 2 (No Repeating Groups) — There are no repeating groups of data. This means a table should not contain repeating columns.
- PlayerItem นั้นมีค่าที่สามารถแบ่งออกได้ (Divided) นั้นย่อมไม่ใช่ Atomic Values
การที่ 1 Column มีได้เพียง 1 ค่าเท่านั้น เรียกว่า Atomic Values
เราจึงออกแบบตารางใหม่ ให้เป็น Atomic Values ทั้งหมด ดังภาพ
- สังเกตว่า Table ใหม่ จะมี Item ซ้ำกันหลาย Column ถ้าอนาคตมี Item เพิ่มขึ้นมา Column จะเพิ่มขึ้นเช่นกัน
- ค่าส่วนใหญ่ในตาราง Item มีค่า 0 ทำให้สิ้นเปลืองเนื้อที่ในการเก็บ
การที่มีหลาย Column ที่มีความหมายเดียวกัน แต่เก็บคนละค่าเช่นนี้ เรียกว่า Repeating Groups
เราสามารถใช้ความรู้ในด้าน Relational Database มาแก้ไขปัญหาได้
- Red ได้ MasterBall ขึ้นมา 1 ลูก สามารถเพิ่ม Rows ใหม่ใน Item Table ได้เลย
- จะนับจำนวน Item ของ Player ก็สามารถทำได้ง่ายผ่าน GROUP BY ใน Item Table
หลังจากกำจัด Repeating Group ไปแล้ว DataBase ของเพื่อนๆจะเป็น First Normal Form (1NF)
- ถ้าวันหนึ่ง Developer เปลี่ยนชื่อ Ultra Ball เป็น Ultimate Ball , Developer สามารถเปลี่ยนที่ Item Desc Table ที่ ItemID 4 ได้ทันที
Second Normal Form (2NF)
The Second Normal Form states that it should meet all the rules for 1NF and there must be no partial dependences of any of the columns on the primary key
- ถ้า Player 0 เกิดถูกลดขั้นเป็น Junior เราต้องแก้ Player Rank ถึง 2 Rows
- ถ้า Player 0 เช่นเดิม มี Item 20 ชนิด เราจำเป็นต้องแก้ Player Rank ถึง 20 Rows
เมื่อเราลองคิดให้ดีแล้ว PlayerRank นั้น “ผูก” กับ PlayerID เพียงอย่างเดียว ไม่ “ผูก”กับ PlayerItem เลย
การที่ “บาง” primary key นั้นมี dependences กับ columns ใดๆ นั้นเรียกว่า เกิด partial dependences
- หลังจากนี้ ถ้าเราจะเปลี่ยนแปลง Player Rank ของ Player ใดๆ สามารถแก้ที่ PlayerRankTable เพียง 1 Rows ได้ทันที
หลังจากกำจัด Partial Dependences ไปแล้ว DataBase ของเพื่อนๆจะเป็น Second Normal Form
Third Normal Form (3NF)
A table is in a third normal form when the following conditions are met −
- It is in second normal form.
- All nonprimary fields are dependent on the primary key.
- ถ้า Player Level เพิ่มขึ้นจาก 6 ไป 7 เราต้อง Update ทั้ง PlayerRank และ PlayerLevel
- วันหนึ่ง Game Design ต้องการเพิ่ม Rank ใหม่ World Pro สำหรับ Level 10 ขึ้นมา เราจำเป็นต้อง Update ทุก Player ที่ Level 10 เป็น World Pro
เมื่อเราลองคิดดูให้ดี จะพบว่า PlayerRank นั้น “ผูก” กับ Player Level เสมอ ถ้าเราทราบ PlayerLevel จะทราบ PlayerRank
การที่ “บาง” Column “ที่ไม่ใช่ primary key” นั้นมี Dependences กับ Columns ใดๆ นั้นเรียกว่า เกิด Transitive Dependences
- ถ้า Player Level เพิ่มขึ้นจาก 6 ไป 7 เราจะ Update Player Level เพียง 1 Column
- วันหนึ่ง Game Design ต้องการเพิ่ม Rank ใหม่ World Pro สำหรับ Level 10 ขึ้นมา เราจะอัพเดทเพียงเพิ่ม Rows ในตาราง PlayerLevel-PlayerRank
หลังจากกำจัด Transitive Dependences ไปแล้ว DataBase ของเพื่อนๆจะเป็น Third Normal Form
Boyce-Codd Normal Form (BCNF)
BCNF is the advance version of 3NF. It is stricter than 3NF.
A table is in BCNF if every functional dependency X → Y, X is the super key of the table.
- Visual Novel Ranking เป็นตาราง 3NF เพราะไม่มีทั้ง PD และ TD
- ต่อมาวันหนึ่ง มีคนมาแจ้งว่า White Album จริงๆออกปี 2010 ตังหาก เราจำเป็นต้องแก้ทั้ง ReleaseYear และ ReleaseYearMonth
- ถ้าเราจำเป็นต้องแก้ ReleaseYear เราก็แก้แค่ ReleaseYear ไม่ต้องยุ่งกับ ReleaseMonthอีก
~closing chapters~
เนื่องจากช่วงนี้ ผู้เขียนได้มีโอกาสได้ Implement Backend แล้วรู้สึกว่า ตัวเองก็ออกแบบตารางได้ดีนั่นละ(อวยตัวเองหน่อย LOL) แต่ถ้ามีคนถามขอคำอธิบายจะตอบได้ไม่ดีเลย ซึ่งคิดว่าเพื่อนๆก็น่าจะเป็นเช่นเดียวกัน จึงถือว่าโอกาสนี้เขียนบทความนี้มาแชร์ความรู้กับเพื่อนๆเลยครับ
เนื่องจากเป็นอธิบายล้วนๆเลย จึงแทบจะเป็นบทความที่ยากที่สุดที่ผู้เขียนได้ลองเขียนเลย (ปกติแล้วก็อปโค๊ตแปะๆเอา TT) ก็ถ้าอ่านไม่รู้เรื่องยังไง เพิ่มเติมส่วนไหนแล้วเข้าใจได้มากขึ้น รวมไปถึงตรงไหนผิดพลาด ก็สามารถมาพูดคุยหรือสอนมวยกันได้เลยนะครับ
ที่อยากจะเตือนเพื่อนๆไว้คือ จริงๆแล้ว การ Normalize นั้นมีถึง 5 ขั้นด้วยกัน แต่ปกติทำถึง 3rd Form ก็น่าจะใช้งานได้ดีมากๆแล้ว ประเด็นคือ บางครั้งเราอาจจะยอมไม่ Normalize เพื่อ Performance ได้เหมือนกัน
ที่เจอบ่อยๆคือ 3rd ในฟิลล์ที่มันไม่น่าจะมีการเพิ่ม-เปลี่ยนแปลง ค่า (คิดสภาพ จังหวัด-รหัสไปรษณีย์) Case นี้ เราอาจจะเก็บข้อมูลลดลง แต่ Join นั้นมีราคาที่แพงมาก (มันรันช้า) บางครั้งอาจจะยอมเก็บข้อมูลซ้ำซ้อน เพื่อที่จะได้ไม่ต้อง Join ใน Table ที่เราต้อง Join กันบ่อยครับ
สุดท้ายนี้ก็ขอบคุณเพื่อนๆที่อ่านบทความนี้จนจบนะครับ หวังเป็นอย่างยิ่งว่าบทความนี้จะเป็นประโยชน์กับเพื่อนๆแก๊ง Backend ด้วยกัน เจอกันในบทความหน้าๆนะครับ