Basic Database System Part 5 - Normalization Process 4NF , 5NF

Basic Database System Part 5 - Normalization Process 4NF , 5NF

ในตอนที่แล้วเราได้ทำ Normalization Process ไปถึงขั้น BCNF ซึ่งจากตัวอย่างที่เราได้ลองทำกันนั้นมันไม่มีปัญหา INSERT , DELETE , UPDATE ซึ่งนั่นทำให้เกิดความเข้าใจผิดๆว่าทำ Normalization Process ถึงขั้น BCNF ก็พอ ในตอนนี้เราจะมาดูว่า Table ที่เป็น BCNF ก็ยังเกิดปัญหา INSERT , DELETE , UPDATE ได้ จากนั้นเราจะมาทำ Normalization Process กันต่อจนถึงขั้น 5NF

Table : Course Teacher Text (CTX)

Course Teacher Text

นี่เป็นรายละเอียดเกี่ยวของ Course เรียนที่บอกว่าจะสอนวิชาอะไร ใครเป็นอาจารย์ และต้องใช้หนังสืออะไรบ้าง ซึ่งจากตัวอย่างเราจะเห็นว่า Course : Database มีอาจารย์สอน 2 คนคือ John , Smith ใช้หนังสือสำหรับสอนวิชานี้ 2 เล่มคือ Set theory , DBMS Technology ส่วน Course : Math มีอาจารย์สอน 1 คนคือ John ใช้หนังสือสำหรับสอนวิชานี้ 3 เล่มคือ Set theory , Algebra , Calculus

ถ้าเราอยากเก็บข้อมูลนี้ให้อยู่ใน Relational Database Model เราสามารถทำได้โดยใช้ Normalization Process ที่เราเรียนไปในตอนที่แล้ว ซึ่ง Table ที่ได้ออกมาจะมีหน้าตาแบบนี้

Table : Course Teacher Text (CTX) ที่เป็น BCNF

รายละเอียดของ Table

  1. Primary key : { COURSE , TEACHER , TEXT }
  2. Candidate key : { COURSE , TEACHER , TEXT }
  3. Nonkey attribute : ไม่มี
  4. FD ไม่มี

ตรวจสอบว่าเป็น BCNF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และแต่ละ Column มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น

Table เป็น BCNF แต่ปัญหา INSERT , DELETE , UPDATE

คุณจะเห็นว่า Table : Course Teacher Text (CTX) นั้นเป็น BCNF แล้ว ซึ่งถ้าคุณเชื่อตามความเชื่อผิดๆที่บอกไปตอนต้นว่า Table ที่เป็น BCNF (บางคนบอก 3NF) แล้วจะไม่มีปัญหาเรื่องการ INSERT , DELETE , UPDATE เรามาลองพิสูจน์กันครับว่าจริงไหม

ปัญหา Insert ข้อมูลเข้าไปไม่ได้

ถ้าผมต้องการอยากเพิ่ม COURSE : PROGRAMMING เข้าไปโดยวิชานี้ใช้ TEXT : BASIC C, C++ , JAVA Programming เข้าไป เราจะได้ข้อมูลที่จะ INSERT เป็น

ข้อมูลที่ต้องการ INSERT ลง TABLE : CTX

ซึ่งจะเห็นว่าเราไม่สามารถ INSERT ข้อมูลได้เพราะติดกฎเรื่อง Primary key must not be null

ปัญหา Delete

ถ้าสมมุติผมต้องการลบข้อมูล TEACHER : John ออกไป คุณจะเห็นว่าถ้าลบข้อมูล John ออกไป ข้อมูลของ TEXT ที่เกี่ยวกับ COURSE : Math ทั้งหมดจะหายไปด้วย ซึ่งนั่นไม่ใช่สิ่งที่เราต้องการ

ข้อมูลที่ต้องการ DELETE

ยังมีปัญหาอยู่

คุณจะเห็นแล้วว่าแม้ Table จะเป็น BCNF แต่มันก็ยังเกิดปัญหา INSERT , UPDATE , DELETE อยู่ ดังนั้นถ้าใครบอกว่า Normalization Process ทำแค่ BCNF (3NF) ก็พอ ผมแนะนำให้เอา Table : Course Teacher Text (CTX) ให้เขาดูครับ เขาจะได้เข้าใจว่ามันไม่ใช่อย่างที่เขาคิด

ความสัมพันธ์ระหว่าง Column (Attriubte) ของ Table : CTX

ใน Table : CTX นั้นไม่มีความสัมพันธ์แบบ FD เลย แต่ถ้าคุณดูความสัมพันธ์ตามงานจริงคุณจะรู้ว่าตัว COURSE นั้นจะเป็นตัวบอกว่ามี TEACHER คนไหนบ้างที่สอนวิชานี้ และ COURSE นั้นเป็นตัวบอกว่ามี TEXT เล่มไหนถูกใช้ในการสอนบ้าง และ TEXT กับ TEACHER นั้นไม่ได้มีความเกี่ยวข้องกันเลย (TEACHER ไม่ได้เป็นตัวบอกว่าใช้ TEXT เล่มไหน และ TEXT ก็ไม่บอกว่า TEACHER คนไหนต้องใช้ ) เราจะเรียกความสัมพันธ์ใน Table นี้ว่า Multivalued dependence ( MVD )

Multivalued dependence ( MVD )

Given a relational table structure T , With attributes X , Y and Z , the multivalued dependence (MVD) T.X ->-> T.Y holds in T if and only if the set of Z-values matching a given (X-value, Y-value) pair in T depends only on the X-Value and is independent of the Y-value. As usual , X, Y and Z may be composite.
Note that MVDs as defined can exist only if the relational table structure T has at least three attributes.

ผมแนะนำให้อ่านนิยามภาษาอังกฤษนะครับ สำหรับภาษาไทยที่ผมจะแปลผมไม่รู้จะแปลยังไงให้ถูกดี ลองอ่านดูละกันครับ

กำหนดให้ Table T มี Column (Attribute) X , Y และ Z โดย Multivalued dependence (MVD) T.X ->-> T.Y จะอยู่ใน Table T ก็ต่อเมื่อ มี Set ของค่าใน Column Z ตรงกับคู่ของค่า ( X-value , Y-value ) โดยค่า Z นั้นจะขึ้นอยู่กับ X เท่านั้น และค่า Z เป็นอิสระต่อ Y โดยปกติแล้ว X Y และ Y นั้นจะอยู่ด้วยกัน ดังนั้น MVD จะเกิดขึ้นได้ก็ต่อเมื่อ Table นั้นมีอย่างน้อย 3 Attribute

อ่านแล้วอาจจะงงเรามาดูตัวอย่างของ Table : CTX

Table : CTX มี 3 Column (Attribute) คือ COURSE , TEACHER , TEXT

  1. MVD COURSE ->-> TEACHER

    X คือ COURSE , Y คือ TEACHER , Z คือ TEXT

    ตรงนี้เราพอเห็นแล้วว่า COURSE ->-> TEACHER น่าจะเป็น MVD เพราะค่า COURSE นั้นกำหนดกลุ่มของค่า TEACHER แต่เราต้องตรวจสอบด้วยนิยามคือดูค่า TEXT ว่าตรงตามเงื่อนไขไหม

    ตรวจสอบทีละเงื่อนไขว่าเป็น MVD หรือไม่

    • Z ขึ้นอยู่กับ X เท่านั้น ดูได้จากค่า Text = { Set theory , DBMS Technology } เมื่อ Course = Database และ Text = { Set theory , Algebra , Calculus } เมื่อ Course = Math

    • Z เป็นอิสระจาก Y ดูได้จาก TEXT สามารถเปลี่ยนค่าได้โดยไม่เกี่ยวข้องกับ TEACHER เลย

    • Z (Text) = { Set theory , DBMS Technology } นั้นสามารถ Map ได้กับคู่ของ COURSE , TEACHER ซึ่งก็คือ {Database , John} , { Database , Smith } ได้

      MVD COURSE ->-> TEACHER

  1. MVD COURSE ->-> TEXT

    X คือ COURSE , Y คือ TEXT , Z คือ TEACHER

    ตรวจสอบทีละเงื่อนไขว่าเป็น MVD หรือไม่

    • Z ขึ้นอยู่ X เท่านั้น ดูได้จากค่า TEACHER = { John , Smith } เมื่อ Course = Database และ TEACHER = { John } เมื่อ Course = Math

    • Z เป็นอิสระจาก Y ดูได้จาก TEACHER สามารถเปลี่ยนค่าได้โดยไม่เกี่ยวกับ TEXT เลย

    • TEACHER = { John , smith } นั้นสามารถ Map ได้กับคู่ของค่า COURSE , TEXT ซึ่งก็คือ { Database , Set theory } , { Database , DBMS Technology }

      MVD COURSE ->-> TEXT

ข้อสังเกตเกี่ยวกับ MVD

  • เวลาเกิด MVD นั้นจะเกิดเป็นคู่อย่างในตัวอย่างเมื่อเกิด MVD COURSE ->-> TEACHER ก็จะเกิด MVD COURSE ->-> TEXT เกิดขึ้นเสมอ ดังนั้นเขาจะเขียน MVD เป็น MVD COURSE ->-> TEACHER | TEXT

  • ความสัมพันธ์แบบ MVD นั้นเป็นความสัมพันธ์แบบ 1 to Many ตัวอย่างเช่น MVD COURSE ->-> TEXT นั้นค่า COURSE หนึ่งค่าสามารถกำหนดว่าค่า TEXT สามารถมีค่าเป็นอะไรได้หลายค่า เช่น ถ้า COURSE = Database ค่า TEXT ที่สามารถเป็นได้คือ { Set theory , DBMS Technology } คราวนี้ถ้าเราเกิดสมมุติว่าความสัมพันธ์แบบ MVD X ->-> Y แล้ว Set ของ Y มีค่า 1 ค่า มันก็จะกลายเป็น 1 to 1 ซึ่งนั่นก็หมายความว่ามันคือความสัมพันธ์แบบ FD ดังนั้นความสัมพันธ์แบบ FD ซึ่งเป็นกรณีพิเศษของ MVD

4NF

A relational table structure T is in th fourth normal form (4NF) if it is in BCNF and all MVDs in T are FDs Only.

ผมแนะนำให้อ่านนิยามภาษาอังกฤษเพราะเป็นนิยามที่ถูกต้องครับ แต่ถ้าไม่เข้าใจลองอ่านที่ผมแปล

Table จะเป็น 4NF เมื่อ Table นั้นเป็น BCNF และ MVD ทั้งหมดใน Table ต้องเป็น FD

ตรวจสอบ Table : CTX

MVD ของ Table : CTX

  • MVD COURSE ->-> TEACHER
  • MVD COURSE ->-> TEXT

Table นี้ไม่เป็น 4NF เพราะ MVD ไม่ได้เป็น FD ดูได้จากเพราะค่า COURSE –>–> TEACHER เป็น 1 to many ดังนั้น MVD นี้ไม่ได้เป็น FD

วิธีแก้ไข

ให้ทำการแยกความสัมพันธ์ MVD ออกไปเป็น Table ใหม่ Table : CTX มี 2 MVD ก็จะได้เป็น 2 Table คือ Table : Course Teacher (CT) กับ Table : Course Text (CX)

Table : Course Teacher (CT)

Table : Course Teacher (CT)

รายละเอียดของ Table

  1. Primary key : { COURSE , TEACHER }
  2. Candidate key : { COURSE , TEACHER }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี
  5. MVD : ไม่มี

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

Table : Course Text (CX)

Table : Course Text (CX)

รายละเอียดของ Table

  1. Primary key : { COURSE , TEXT }
  2. Candidate key : { COURSE , TEXT }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี
  5. MVD : ไม่มี

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

ตรวจสอบปัญหา Insert Update Delete

ปัญหา Insert ข้อมูลเข้าไปไม่ได้

ถ้าผมต้องการอยากเพิ่ม COURSE : PROGRAMMING เข้าไปโดยวิชานี้ใช้ TEXT : BASIC C, C++ , JAVA Programming เข้าไป เราจะได้ข้อมูลที่จะ INSERT เข้า Table : Course Text (CX) ได้เลย

INSERT ข้อมูลลง TABLE : CX

ซึ่งจะไม่ติดปัญหา Primary Must not be null

ปัญหา Delete

ถ้าสมมุติผมต้องการลบข้อมูล TEACHER : John ออกไป เราก็สามารถลบข้อมูลออกจาก Table : Course Teacher (CT) ได้เลยซึ่งข้อมูลเกี่ยวกับ Text จะไม่หายไปเหมือนกรณีที่แล้ว

DELETE ข้อมูล TABLE : CT

Table : Vendor Item Project (VIJ)

Table : Vendor Item Project (VIJ)

Table : Vendor Item Project (VIJ) Table นี้นั้นทำการเก็บข้อมูลว่า Vendor ไหน ส่ง Item อะไร ให้ Project ไหน ดูแล้วมันก็เหมือน Table ทั่วไปใช่ไหมครับ โดยตัว Table นี้เก็บข้อมูลเกี่ยวกับ Vendor ไหนมี Item อะไร Item อะไรถูกใช้กับ Project ไหน และ Project ไหนใช้งาน VENDOR เจ้าไหน ฟังแล้วมันก็เก็บข้อมูลทั่วๆไปใช่ไหมครับแต่ Table นี้มีความพิเศษครับ เรามาลองดูกันครับ

รายละเอียดของ Table

  1. Primary key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าอยู่ใน 4NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม

Table เป็น 4NF แต่ยังมีปัญหา INSERT , DELETE , UPDATE

คุณอ่านไม่ผิดครับ Table นี้เป็น 4NF และยังมีปัญหา ปัญหา INSERT , DELETE , UPDATE อยู่ครับ (ใครบอก 3NF ไม่มีปัญหา นี่ 4NF แล้วยังมีปัญหาเลย) ลองมาดูปัญหากัน

ปัญหา Insert ข้อมูลไม่ได้

ถ้าผมอยาก Insert ข้อมูลว่า VENDOR : V2 ว่ามี ITEM : I2 ขาย เราจะทำการ INSERT ข้อมูลเข้าไปดังภาพ ซึ่งจะไม่สามารถทำได้เพราะติด Primary must not be null

ข้อมูลที่ต้องการ INSERT ลง TABLE : VIJ

ปัญหา Delete ข้อมูล

ถ้าผมอยากลบข้อมูลที่ VENDOR : V1 ขาย ITEM : I2 ซึ่งถ้าผมลบข้อมูลนี้ไปแล้ว ข้อมูลที่ว่า ITEM : I2 นั้นถูกใช้ใน PROJECT : 1 นั้นจะถูกลบไปด้วยครับ

5NF

A relational table structure T is in projection-join normal form (PJ/NF) or the fifth normal form (5NF) if and only if every join dependency in T is implied by the candidate keys of T.

แนะนำให้อ่านนิยามภาษาอังกฤษครับ หากอ่านไม่เข้าใจจริงๆค่อยมาอ่านที่ผลแปลไทย

Table จะเป็น 5NF ก็ต่อเมื่อทุก Join dependency ใน Table จะต้องมี candidate key ของ Table นั้น

ผมว่าอ่านแล้วน่าจะไม่เข้าใจเพราะติดศัพท์ Join dependency ดังนั้นเรามาทำความเข้าใจ Join dependency คืออะไร

Join dependency

เราทราบแล้วว่าตัว Table : CTX นั้นสามารถถูกแยกออกมาเป็น Table : CT , Table : CX ซึ่งการแยก Table ได้หรือไม่นั้นมาจากการแยก Table แล้วสามารถ Join กลับมาเป็นข้อมูลเดิมได้ ดังตัวอย่าง CTX ด้านล่างที่สามารถแยกและ Join กลับได้ข้อมูลดังเดิม

ตัวอย่างการแยก Table ที่สามารถ Join กลับได้

แต่ถ้าเราเปลี่ยนการแยก Table เป็น Table : CT กับ Table : TX นั้นจะไม่สามารถ JOIN กลับได้เหมือนเดิม

ตัวอย่างการแยก Table แล้วไม่สามารถ Join กลับได้

ดังนั้น Table : CTX นั้นมี Join dependency กับการแยก Table ด้วย ( COURSE , TEXT ) , (COURSE , TEACHER ) แต่ไม่มี Join dependency กับ ( COURSE , TEACHER ) ( TEACHER , TEXT )

โดยเวลาเราเขียนความสัมพันธ์แบบ Join dependency จะเขียนอยู่ในรูป

R(A,B,C) มีความสัมพันธ์แบบ JD * (AB , AC)

โดยถ้าจากตัวอย่างของเราจะเขียนอยู่ในรูป

CTX(COURSE , TEACHER , TEXT) มีความสัมพันธ์แบบ JD * ( (COURSE , TEACHER) , (COURSE , TEXT) )

JD ของ TABLE : VIJ

TABLE : VIJ มี Join dependency คือ

VIJ(VENDOR_ID , ITEM_ID , PROJECT_ID) มีความสัมพันธ์แบบ JD * ( (VENDOR_ID , ITEM_ID ) , ( ITEM_ID , PROJECT_ID ) , ( PROJECT_ID , VENDOR_ID ) )

ตัวอย่างการแยก TABLE : VIJ แล้วสามารถ JOIN กลับ

ตรวจสอบว่า TABLE : VIJ เป็น 5NF ไหม

  1. Primary key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID , PROJECT_ID }
  3. JD : ( (VENDOR_ID , ITEM_ID ) , ( ITEM_ID , PROJECT_ID ) , ( PROJECT_ID , VENDOR_ID ) )

Table : VIJ ไม่เป็น 5NF เพราะ JD ไม่ได้มี Candidate key ในนั้น

วิธีแก้ไข

ทำการแยก Table ออกไปตาม JD ของ Table นั้น ซึ่งจากตัวอย่างเราจะแยก Table ออกเป็น 3 Table คือ

TABLE : VENDOR ITEM (VI)

TABLE :  VENDOR ITEM (VI)

รายละเอียด Table

  1. Primary key : { VENDOR_ID , ITEM_ID }
  2. Candidate key : { VENDOR_ID , ITEM_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

TABLE : ITEM_PROJECT (IJ)

TABLE :  ITEM_PROJECT (IJ)

รายละเอียด Table

  1. Primary key : { ITEM_ID , PROJECT_ID }
  2. Candidate key : { ITEM_ID , PROJECT_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

TABLE : PROJECT_VENDOR (JV)

TABLE : PROJECT_VENDOR (JV)

รายละเอียด Table

  1. Primary key : { PROJECT_ID , VENDOR_ID }
  2. Candidate key : { PROJECT_ID , VENDOR_ID }
  3. Nonkey attribute : ไม่มี
  4. FD : ไม่มี (ลองพิสูจน์ดูครับ)
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)
  6. JD : ไม่มี (ลองพิสูจน์ดูครับ)

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table นี้ไม่มี Nonkey attribute และ ไม่มี FD ดังนั้นจึงผ่านเรื่อง Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี Nonkey attriubte จึงไม่มี FD ระหว่าง Nonkey attribute
  • BCNF : เป็นเพราะ Table นี้ไม่มี FD ดังน้ันจึงไม่ต้องเช็คว่า Determinant ของ FD ใน Table นี้ต้องเป็น Candidate key เท่านั้น
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ Table นี้ไม่มี JD ดังนั้นจึงไม่ต้องเช็คว่าทุก JD มี Candidate key อยู่ไหม

ตรวจสอบว่ามีปัญหา INSERT UPDATE DELETE ไหม

ปัญหา INSERT ข้อมูลไม่ได้

ถ้าผมอยาก Insert ข้อมูลว่า VENDOR : V2 ว่ามี ITEM : I2 ขาย เราสามารถทำการ INSERT ข้อมูลลง Table : VENDOR_ITEM ได้เลย โดยไม่ติดปัญหา Primary key must not be null

ปัญหา DELETE ข้อมูล

ถ้าผมอยากลบข้อมูลที่ VENDOR : V1 ขาย ITEM : I2 ก็สามารถลบข้อมูลได้เลยไม่ติดอะไร

การทำ 5NF ต้องทำให้ Table เหลือแค่ 2 Column (Attribute)

เรื่องนี้เป็นความเข้าใจผิดว่าเวลาจะทำให้ Table ให้เป็น 5NF ได้นั้นต้องแยก Table ให้เหลือ 2 Column ซึ่งนั่นทำให้เกิดปัญหาเรื่อง Join ข้อมูลทำให้เกิดปัญหาเรื่อง performance แต่นี่เป็นความเข้าใจที่ผิดครับ หากคุณอ่านนิยามของ 5NF ดีๆไม่มีตรงไหนบอกว่าต้องมี Column (Attribute) เหลือแค่ 2 Column เรามาดูตัวอย่าง Table ที่เป็น 5NF และมีมากกว่า 2 Column ดูกันครับ (คุณเคยเห็น Table นี้แล้ว)

TABLE : USER

รายละเอียด Table

  1. Primary key : USERNAME

  2. Candidate key :

    • USERNAME
    • EMAIL
  3. Nonkey attribute :

    • USER_TYPE
  4. FD :

    • USERNAME -> EMAIL
    • EMAIL -> USERNAME
    • USERNAME -> USER_TYPE
    • EMAIL -> USER_TYPE
  5. MVD : ไม่มี (ลองพิสูจน์ดูครับ)

  6. JD

    • ( (USERNAME , EMAIL ) , ( USERNAME , USER_TYPE ) )

    • ( (USERNAME , EMAIL ) , ( EMAIL , USER_TYPE ) )

    • ( (EMAIL , USERNAME) , ( USERNAME , USER_TYPE) )

    • ( (EMAIL , USERNAME ) , ( EMAIL , USER_TYPE ) )

      จะเห็นว่า 1 Table สามารถมีได้หลาย JD นะครับ ลองแยก Table แล้วกลับไป JOIN ดูครับมัน JOIN กลับได้ข้อมูลเดิมทั้งหมด

ตรวจสอบว่าเป็น 5NF ไหม

  • 1NF : เป็นเพราะทุก Column (Attribute) เป็น Atomic และ แต่ละ Column (Attribute ) มาจาก Domain เดียว
  • 2NF : เป็นเพราะ Table Primary key กับ Nonkey Attribute เป็น Full FD
  • 3NF : เป็นเพราะ Table นี้ไม่มี FD ระหว่าง Nonkey attribute
  • BCNF: เป็นเพราะ Determinant ของ FD ใน Table นี้เป็น Candidate key ทั้งหมด
  • 4NF : เป็นเพราะ Table นี้เป็น BCNF และ Table นี้ไม่มี MVD ดังนั้นจึงไม่ต้องเช็คว่าทุก MVD เป็น FD ไหม
  • 5NF : เป็นเพราะ ทุก JD มี Candidate key อยู่ด้วยทั้งหมด (ลองดูครับจะเห็นว่ามี USERNAME , EMAIL เป็นส่วนประกอบในทุกๆ JD )

จากตัวอย่างนี้คุณจะเห็นว่า Table ที่มี 3 Column ก็เป็น 5NF ได้นะครับ (จริงๆจะกี่ Column ก็ได้ครับ ตราบเท่าที่มันตรงนิยาม)

อย่า Split ถ้าไม่จำเป็น

อย่า Split ถ้าไม่จำเป็น เป็นคำพูดที่อาจารย์สอนวิชา Database ผมพูดเสมอ เพราะคนส่วนใหญ่มักจะเข้าใจผิดว่าการทำ Normalization นั้นคือการพยายามแยก Table ให้เล็กที่สุด แบบที่บางคนเข้าใจกันว่า 5NF ต้องมี 2 Column (Attribute) ซึ่งการทำ Normalization นั้นมีเป้าหมายเพื่อจัดการให้ Table ไม่มีปัญหา INSERT , DELETE , UPDATE ซึ่งเมื่อเกิดปัญหาก็ต้องแก้โครงสร้างของ Table นั้นคือการแยกตาราง ดังนั้นอย่าเข้าใจผิดนะครับ เราทำเพื่อแก้ปัญหา ไม่ใช่ทำเพื่อแยก Table

สรุป

ตอนนี้เราได้รู้ว่า 4NF , 5NF คืออะไร วิธีการแก้ไขให้ Table เป็น 4NF , 5NF และเราได้ทำลายความเชื่อและความเข้าใจผิดๆที่ว่าการทำ Normalization ทำถึง BCNF (3NF) ก็พอผ่านการแสดงให้เห็นปัญหา INSERT DELETE UPDATE ที่ยังคงมีอยู่

สุดท้ายผมหวังว่าเนื้อหาเกี่ยวกับ Normalization ทั้ง 3 ตอนที่ผมเขียนไปคงมีประโยชน์ไม่มากก็น้อย และที่สำคัญผมแนะนำให้ท่านไปหาหนังสือเกี่ยวกับวิชา Database จริงๆมาอ่านเพราะหนังสือเหล่านั้นจะอธิบายได้ดีกว่าที่ผมอธิบายเยอะมากๆครับหรือถ้ามีโอกาสควรไปเรียนกับอาจารย์ที่สอนวิชา Database ดูครับ คุณจะได้เห็นตัวอย่างที่ทำให้เข้าใจมากกว่านี้ครับ และหากข้อมูลตรงจุดไหนไม่ถูกต้อง ไม่ครบถ้วน สามารถแจ้งผมได้เลยนะครับ เดี๋ยวจะไปแก้ให้ถูกต้องให้ครับ

ในตอนถัดไปเราจะมาดูวิธีการ Design Database ด้วยการใช้ ER Diagram กันครับ

REF

  • กระบวนการ Normalization Process และนิยามที่เป็นภาษาอังกฤษทั้งหมด และตัวอย่าง Table : CTX , Table : VIJ เอามาจาก หนังสือ Relational database systems : language, conceptual modeling and design for engineers