กฎ
ก่อนจะเริ่มทำการออกแบบฐานข้อมูลตามกฎของนอมอลฟอร์มขั้นที่ 2 ผู้ออกแบบจะต้องแน่ใจก่อนว่าได้ออกแบบฐานข้อมูลผ่านนอมอลฟอร์มขั้นที่ 1 เรียบร้อยแล้ว
การออกแบบฐานข้อมูลให้ผ่านนอมอลฟอร์มขั้นที่ 2 ฐานข้อมูลจะต้องตรงตามเงื่อนไข คือ
- ต้องไม่มีบางส่วนของไพรมารีคีย์ (Prime Attribute) ที่นำไปสู่ (Functional Dependency) ข้อมูลในคอลัมน์ที่ไม่ได้เป็นส่วนหนึ่งของไพรมารีคีย์(Non-Prime Attribute)
Prime Attribute ใช้เรียกคอลัมน์ที่ถูกเลือกให้เป็นส่วนหนึ่งของแคนดิเดทคีย์ (Candidate Key) หรือ ไพรมารีคีย์ (Primary Key)
Non-Prime Attribute ใช้เรียกคอลัมน์ที่ไม่ได้ถูกเลือกให้เป็นส่วนหนึ่งของแคนดิเดทคีย์ (Candidate Key) หรือ ไพรมารีคีย์ (Primary Key)
นำไปสู่ (Functional Dependency : สัญลักษณ์ → ) ถ้าให้ X และ Y เป็นแอตตริบิวต์หรือชุดแอตตริบิวต์ X นำไปสู่ Y (X→Y) ก็ต่อเมื่อหยิบข้อมูลใดๆใน X มาหนึ่งตัว จะต้องได้ข้อมูลใน Y หนึ่งตัว
อ่านรายละเอียดหรือตัวอย่างเพิ่มเติมเกี่ยวกับคำศัพท์เหล่านี้ได้ในบทความอื่น
ก่อนอื่นต้องทำความเข้าใจก่อนว่า Second Normal Form มีแค่กฎที่ใช้บอกว่า การออกแบบเทเบิลผ่านเกณฑ์แล้ว แต่ไม่ได้บอกกระบวนวิธีหรือขั้นตอนในการสร้างรวมไปถึงการออกแบบหรือแตกเทเบิล กระบวนวิธีที่ผู้เขียนเสนอจึงเป็นแค่คำแนะนำ ไม่ใช่ข้อบังคับ หากผู้ออกแบบเห็นว่ามีกระบวนวิธีที่ดีกว่า ก็ขอให้เลือกวิธีที่ดีกว่านั้น
ตัวอย่าง
สมมติ ผู้เขียนเปิดร้านขายหนังสือ มีหลายสาขา ทุกครั้งที่มีลูกค้าซื้อหนังสือจะมีใบเสร็จจากเครื่องเก็บเงิน ต่อมาผู้เขียนเห็นว่าถึงเวลาต้องใช้ระบบไอทีเก็บข้อมูลเหล่านี้ลงคอมพิวเตอร์โดยตรง ซึ่งง่ายต่อการประมวลผล แทนที่การเก็บข้อมูลในใบเสร็จ
มีเทเบิลที่ผ่านนอมอลฟอร์มขั้นที่ 1 มาแล้วชื่อ Book ซึ่งมีลักษณะดังนี้
Book Table
BOOKNAME (PK) | VER (PK) | CATEGORY | PRICE/UNIT |
---|---|---|---|
SQL | 1 | IT | 200 |
SQL | 2 | IT | 200 |
Jedi | 1 | Sci | 100 |
Java | 1 | IT | 400 |
เทเบิล Book ผ่านนอมอลฟอร์มขั้นที่ 1 เนื่องจากไม่มีความซ้ำซ้อนของแถวในชุดคอลัมน์ใดๆ ในเทเบิล (ดูที่มาของเทเบิล Book ได้ที่บทความอื่น) แต่ไม่ผ่านนอมอลฟอร์มขั้นที่ 2 สาเหุที่ไม่ผ่านเพราะ
ไพรมารีคีย์ของเทเบิล Book คือ {BookName, Ver}
ซึ่งทำให้ ไพร์มแอตตริบิวต์ ได้แก่ BookName และ Ver
ส่วนนอนไพร์มแอตตริบิวต์ได้แก่ Category และ Price/Unit
คุณสมบัติของไพรมารีคีย์ทำให้
{BookName, Ver} → Category และ {BookName, Ver} → Price/Unit
แต่ถ้าดูจากข้อมูลในเทเบิลพบว่า
เมื่อหยิบข้อมูลใน BookName เป็น SQL ไม่ว่าแถวใด จะได้ Category เป็น IT เสมอ และจะได้ Price/Unit เป็น 200 เสมอ
เมื่อหยิบข้อมูลใน BookName เป็น Jedi ไม่ว่าแถวใด จะได้ Category เป็น Sci เสมอ และจะได้ Price/Unit เป็น 100 เสมอ
เมื่อหยิบข้อมูลใน BookName เป็น Java ไม่ว่าแถวใด จะได้ Category เป็น IT เสมอ และจะได้ Price/Unit เป็น 400 เสมอ
ซึ่งสรุปได้ว่า BookName → Category และ BookName → Price/Unit
BookName ซึ่งเป็นส่วนหนึ่งของไพรมารีคีย์ นำไปสู่ Category และ Price/Unit ซึ่งเป็นนอนไพรมแอตตริบิวต์ สิ่งนี้เป็นสาเหตุทำให้เทเบิล Book ไม่ผ่านนอมอลฟอร์มขั้นที่ 2
การที่จะให้เทเบิล Book ผ่านนอมอลฟอร์มขั้นที่ 2ได้ จะต้องนำเอาคอลัมน์ BookName, Category และ Price/Unit แตกออกมาอีกเทเบิลหนึ่งและตัดแถวที่ซ้ำกันออก คอลัมน์ที่เคยเป็นส่วนหนึ่งของไพรมารีคีย์จะกลายเป็นไพรมารีคีย์ของเทเบิลใหม่ ผลที่ได้จะเป็นดังนี้
Book Table (New)
BOOKNAME (PK) | CATEGORY | PRICE/UNIT |
---|---|---|
SQL | IT | 200 |
Jedi | Sci | 100 |
Java | IT | 400 |
BookVer Table
BOOKNAME (PK) (FK-Book) | VER (PK) |
---|---|
SQL | 1 |
SQL | 2 |
Jedi | 1 |
Java | 1 |
ทำการสำรวจเทเบิลอื่นในฐานข้อมูลว่ามีเทเบิลไหนขัดกับกฎนอมอลฟอร์มขั้นที่ 2 อีกหรือไม่ ถ้ามี ให้แก้ไขให้เรียบร้อยตามคำแนะนำที่ให้ไว้ข้างต้น