Basic Database System Part 4 - Normalization Process , 1NF , 2NF , 3NF, BCNF

Basic Database System Part 4 - Normalization Process , 1NF , 2NF , 3NF, BCNF

ในตอนที่แล้วเราได้รู้ว่า Normalization คืออะไรไปแล้ว ตอนนี้เรามาดูว่า Normalization มีขั้นตอนอะไรบ้าง จากนั้นเราไปรู้จัก 1NF , 2NF , 3NF, BCNF ว่ามันคืออะไร

Normalization Process

กระบวนการทำ Normalization มีขั้นตอนง่ายๆดังต่อไปนี้

  1. ตรวจสอบว่า Table ที่ทำการตรวจสอบนั้นอยู่ใน 1NF ไหม ถ้าไม่อยู่ในรูปแบบ 1NF ต้องทำให้อยู่ในรูปแบบ 1NF
  2. ทำการตรวจสอบว่า Table นั้นอยู่ใน NF ชั้นที่ต้องการแล้วรึยัง ถ้าไม่อยู่ให้ทำการแยก Table ตามหลักการของแต่ NF โดยทั่วไปแล้วเราจะทำจนกว่าจะถึงชั้น 5NF (ใครบอกถึง 3NF ถือว่าผิดนะครับ ต้องทำถึง 5NF)
  3. กลับทำข้อ 2 ไปเรื่อยๆจนกว่าทุก Table ที่เรามีจะอยู่ใน NF ที่เราต้องการ ( โดยทั่วไปคือต้องถึง 5NF )

อ่านถึงตรงนี้แล้วอาจจะงงเพราะติดศัพท์พวก NF คืออะไร 1NF คืออะไร 5 NF คืออะไร เดี๋ยวเรามาค่อยๆดูกันครับว่า NF คืออะไร ไล่ไปเรื่อยๆจนถึง BCNF แล้วไปต่อ 4NF , 5NF ในตอนต่อไป

Normal form (NF)

Normal form คือ Table (Relation) ที่อยู่ในรูปแบบที่ดี (Good form) โดยแต่ละ Normal form นั้นจะแก้ปัญหาเกี่ยวกับ INSERT UPDATE DELETE ในกรณีต่างๆ ซึ่งแต่ละ Normal form นั้นระบุเงื่อนไขไว้ว่าต้องมีคุณสมบัติอะไรจึงจะผ่าน Normal form นั้น ในกรณีไม่ผ่านก็จะมีวิธีแก้ไขบอกว่าต้องทำอย่างไร

1NF

A relation table structure T is in the first normal form (1NF) , if and only if all of its attributes contain atomic values only , and each attribute belongs to only one domain

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

Table ที่จะเป็น 1NF ได้นั้น Column (Attribute) ทั้งหมดของ Table นั้นจะต้องมีค่าเป็น atomic value และ Column เหล่านั้นต้องมีค่ามาจาก Domain เดียวกัน

อ่านแบบนี้คงจะไม่เข้าใจเรามาลองดูตัวอย่าง Table ที่ไม่ผ่าน 1NF กันดีกว่า

All of its attributes contain atomic values only : Column (Attribute) ทั้งหมดของ Table นั้นจะต้องมีค่าเป็น atomic value

เรามาดูตัวอย่าง Table ที่ Column (Attribute) มีค่าไม่เป็น atomic value

Column : MOBILE_NO ไม่เป็น Atomic value

จากตัวอย่าง Table ในภาพจะเห็นว่า Column “MOBILE_NO” นั้นไม่เป็น Automic value เพราะมีค่าเป็น List ของเบอร์มือถือที่ User คนนั้นมี ถามว่าปัญหาที่จะเกิดขึ้นจาก Table ที่เก็บค่าแบบนี้คือ เวลาคุณอยากเพิ่มเบอร์โทรขึ้นมาคุณจะสั่งยังไง มันจะไม่ใช่การสั่งแบบ INSERT เบอร์โทรศัพท์ใหม่เข้าไป แต่ต้องไปดูก่อนว่ามี Row ของ User นี้อยู่ใน Database ไหม ถ้าไม่มีจะ INSERT แต่ถ้ามีต้องเป็น UPDATE ค่าที่ Row เก่า ซึ่งคุณจะต้องทำการ Substring ตัดต่อ String เบอร์โทรศัพท์ เช่นกันถ้าต้องการลบข้อมูลโทรศัพท์คุณจะไม่ได้สั่ง DELETE ROW แต่จะกลายเป็นต้องเข้าไปหา ROW ของ USER นั้นจากนั้นดึงค่าจากนั้นต้อง Replace string แล้วเอาค่าใหม่ใส่เข้าไปแทน

อีกทั้งถ้าคุณจำได้ Relation คือ Subset of the Cartesian product of domains ผลลัพธ์ของ Cartesian product of domains ที่ออกมาใน attribute ต่างๆจะไม่มีทางเป็น Set หรือ List ดังนั้น Table ที่เราเห็นนี้ไม่ใช่ Relation ด้วยซ้ำไป

วิธีแก้ไข

วิธีแก้ไข Table นี้ให้อยู่ในรูปแบบ 1NF ก็คือทำให้มันเป็น Automic value คือให้ 1 row มี 1 ค่าไป ซึ่งจะได้ผลลัพธ์ออกมาดังภาพด้านล่าง

Table ที่ถูกแก้ให้เป็น 1NF

Each attribute belongs to only one domain : แต่ละ Column (Attribute) ต้องอยู่ภายใน 1 Domain เท่านั้น

เรามาดูตัวอย่าง Table ที่ไม่ถูกกฎนี้กัน

Column : VALUES มีค่ามาจากหลากหลาย Domain

จากตัวอย่าง Table จะเห็นว่า Column : VALUES นั้นมีค่ามาจากหลาย Domain คือจะเห็นว่าเป็นค่าที่มา Domain : เบอร์มือถือ , Domain : email ปัญหาที่จะเกิดกับ Table นี้คือ ถ้าคุณอยากหาแสดงข้อมูล USERNAME , EMAIL , MOBILE_NO, NICKNAME ของ USER ทั้งหมดที่มี EMAIL = ‘surapong007@hotmail.com’ คุณจะเขียน SQL ยังไงออกมา (เขียนได้นะครับแต่เขียนยากในระดับหนึ่งเลย)

อีกทั้ง Table นี้ไม่จัดเป็น Relation เพราะ ผลลัพธ์ของ Cartesian product of domains ที่ออกมาใน attribute ต่างๆต้องมาจาก Domain เดียวกันไม่ใช่มาจากหลากหลาย Domain

วิธีแก้ไข

วิธีแก้ไขให้ Table นี้อยู่ในรูปแบบ 1NF คือแยก Column ที่มาจากหลาย Domain ให้เป็น Column ใหม่ไปเลยดังภาพด้านล่าง

Table ที่ถูกแก้ให้เป็น 1NF

จะเห็นว่า Table ถูกเพิ่ม Column : EMAIL , MOBILE_NO, NICKNAME เข้าไป

ลองตรวจสอบกับ TABLE : CURRENTCY_TRADING_SYSTEM ว่าเป็น 1NF ไหม

TABLE : CURRENTCY_TRADING_SYSTEM

เราลองตรวจ TABLE : CURRENTCY_TRADING_SYSTEM ดูว่าเป็น 1NF ไหมโดยดูตามกฏของ 1NF ที่ว่า

  • All of its attributes contain atomic values only
    ข้อนี้ผ่านเพราะทุกค่าของแต่ละ Column เป็น Atomic value
  • Each attribute belongs to only one domain
    ข้อนี้ผ่านเพราะทุกค่าของแต่ละ Column มาจาก Domain เดียวกัน

ดังนั้น TABLE : CURRENTCY_TRADING_SYSTEM จึงเป็น 1NF

2NF

A relation table structure T is in the second normal form (2NF) if and only if the relationship between primary key and every nonkey attribute is in full functional dependence

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

Table ที่จะเป็น 2NF ได้นั้น ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวต้องเป็น Full functional dependence

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

Nonkey attribute

คือ Column หรือกลุ่มของ Column ที่ไม่ได้เป็น Candidate key (จริงๆ Column มันคือ Attribute นั่นแหละ ถ้าตามทฤษฎีเราต้องเรียก Column ว่า Attribute เรียก Row ว่า Tuple แต่ขอละเป็น Column ละกันนะ)

Functional dependence (FD)

คือความสัมพันธ์แบบ Function อ่านแล้วงงใช่ไหมครับ คิดง่ายๆครับว่าถ้า A มีความสัมพันธ์แบบ Function กับ B ( A -> B ) แปลว่า ถ้าเรากำหนดค่า A เป็นค่าหนึ่ง จะได้ค่า B เป็นค่าหนึ่งเสมอ ซึ่งผมว่าก็ไม่เข้าใจอีกแหละ เราลองมาดูตัวอย่างอย่างกัน

 ความสัมพันธ์ระหว่าง USERNAME กับ EMAIL

คุณลองดู COLUMN USERNAME กับ EMAIL ครับ คุณจะเห็นว่าถ้าเรากำหนดค่า USERNAME เป็น sarun เราจะได้ email เป็น fax_inwza007@hotmail.com เสมอ ซึ่งไม่ได้แค่ USERNAME เป็น sarun USERNAME อื่นๆก็เป็นแบบนี้ ความสัมพันธ์แบบนี้คือ Funcational dependence ครับ ถามว่าแล้วเราจะรู้ได้ไงว่ามันเป็น ต้องมานั่งไล่ดูค่าทุกค่าเลยเหรอ จริงๆคือไม่ใช่ครับ เราดูค่าเบื้องต้นเพื่อคาดเดาว่าอาจจะใช่ การจะบอกว่าใช่หรือไม่ใช่นั้นต้องไปดูความสัมพันธ์ตามงานจริงครับ คือในงานนี้ USERNAME กับ EMAIL เป็น Functional dependence ( USERNAME -> EMAIL ) เพราะ USERNAME มี EMAIL ได้แค่ EMAIL เดียว ดังนั้นถ้ากำหนดค่า USERNAME อะไรก็จะอ้างถึง EMAIL ได้ EMAIL เดียวเสมอ มันจะแตกต่างกับความสัมพันธ์ระหว่าง USERNAME กับ CURRENCY_CODE ครับที่ 1 USERNAME สามารถมีได้หลาย CURRENCY_CODE

ความสัมพันธ์ระหว่าง USERNAME กับ CURRENCY_CODE

Full Functional dependence

ในส่วนที่แล้วเรารู้ว่า Functional dependence (FD) แต่ Full Functional dependence คืออะไรล่ะ อธิบายยากคุณลองดูตัวอย่างดีกว่า คุณสังเกตุดูจะเห็นว่า { USERNAME , CURRENCY_CODE } มีความสัมพันธ์ FD กับ EMAIL

คุณลองดูได้เลยครับว่าจริงไหม มันจริงแน่นอนครับเพราะ USERNAME มันเป็น FD กับ EMAIL ดังนั้นจะเอา USERNAME ไปรวมกับ Column ไหนมันก็เป็น FD หมดแหละ แต่สิ่งที่เราต้องการจริงๆคือความสัมพันธ์แบบ USERNAME -> EMAIL ไม่ใช่ { USERNAME , CURRENCY_CODE } -> EMAIL ดังนั้นจะเป็น Full Functional dependence ก็ต่อเมื่อ EMAIL นั้นขึ้นอยู่กับค่า USERNAME และ CURRENCY_CODE ทั้งคู่ ซึ่งจะเห็นว่าไม่ใช่เพราะ EMAIL ขึ้นอยู่กับค่า USERNAME ค่าเดียว

  • { USERNAME , CURRENCY_CODE } -> EMAIL
  • USERNAME -> EMAIL

หรือว่าง่ายๆถ้าหาค่าฝั่งซ้ายที่เป็น Subset ได้ก็แปลว่าไม่เป็น Full FD ละ จากตัวอย่าง { USERNAME , CURRENCY_CODE } -> EMAIL ไม่เป็น Full FD เพราะเราเจอ FD : USERNAME -> EMAIL ซึ่งจะเห็น USERNAME เป็น Subset ของ { USERNAME , CURRENCY_CODE }

ลองตรวจสอบกับ TABLE : CURRENTCY_TRADING_SYSTEM ว่าเป็น 2NF ไหม

เรามา List แต่ละส่วนประกอบที่เราต้องใช้ตรวจสอบ

  1. Primary key : { USERNAME , CURRENCY_CODE }

  2. Nonkey attribute มีดังต่อไปนี้

    • EMAIL
    • USER_TYPE
    • PRIORITY
    • CURRENCY_NAME
    • COUNTRY
    • AMOUNT
  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • USERNAME -> EMAIL
    • USERNAME -> USER_TYPE
    • USERNAME -> PRIORITY
    • CURRENCY_CODE -> CURRENCY_NAME
    • CURRENCY_CODE -> COUNTRY
    • USER_TYPE -> PRIORITY
    • { USERNAME , CURRENCY_CODE } -> AMOUNT

จากนิยาม

A relation table structure T is in the second normal form (2NF) if and only if the relationship between primary key and every nonkey attribute is in full functional dependence

Table ที่จะเป็น 2NF ได้นั้น ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวต้องเป็น Full functional dependence

จะเห็นว่า TABLE : CURRENTCY_TRADING_SYSTEM ไม่เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ไม่ได้เป็น Full functional dependence ดูได้จาก { USERNAME , CURRENCY_CODE } ไม่ได้เป็น Full FD กับ EMAIL , USER_TYPE , PRIORITY , CURRENCY_NAME , COUNTRY

วิธีแก้ไข

วิธีแก้ทำให้ Table นี้เป็น 2NF ก็คือแยก Table ออกไปโดยเราจะแยก Table ตาม FD ที่เป็น Subset ของ Primary เลยครับ จากนั้นก็ตรวจสอบอีกครั้งว่าเป็น 2NF ไหม โดยจากตัวอย่างเราจะแยกได้ 3 Table คือ

Table : USER

TABLE : USER

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : USERNAME

  2. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE

    • PRIORITY

      คุณอาจจะสงสัยว่าทำไม EMAIL หายไปไหน ที่มันหายไปเพราะ EMAIL เป็น Candidate key นะครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • USERNAME -> USER_TYPE
    • USERNAME -> PRIORITY
    • USER_TYPE -> PRIORITY

Table นี้เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute เป็น Full FD ทั้งหมด

Table : CURRENCY

Table : CURRENCY

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : CURRENCY_CODE

  2. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY

      คุณอาจจะสงสัยว่าทำไม CURRENCY_NAME หายไปไหน ที่มันหายไปเพราะ CURRENCY_NAME เป็น Candidate key นะครับ ทำไม Country ไม่เป็น ที่ไม่เป็นก็เพราะบางประเทศมีหลายสกุลเงินนะครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • CURRENCY_CODE -> COUNTRY

Table : USER_CURRENCY

Table : USER_CURRENCY

ตรวจสอบว่า Table นี้เป็น 2NF ไหม

  1. Primary key : { USERNAME , CURRENCY_CODE }

  2. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY

      คุณอาจจะสงสัยว่าทำไม CURRENCY_NAME หายไปไหน ที่มันหายไปเพราะ CURRENCY_NAME เป็น Candidate key นะครับ ทำไม Country ไม่เป็นล่ะ ที่ไม่เป็นก็เพราะบางประเทศมีหลายสกุลเงินครับ

  3. Full Functional Dependency ของ Column (Attribute ) ใน Table นี้

    • { USERNAME , CURRENCY_CODE } -> AMOUNT

Table นี้ 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute เป็น Full FD ทั้งหมด

3NF

A relation table structure T is in the third normal form (3NF) if and only if T is in 2NF and there are no funcational dependencies between nonkey attributes of T

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

Table จะเป็น 3NF ก็ต่อเมื่อ Table นั้นเป็น 2NF และ Table นั้นไม่มี funcational dependence ระหว่าง nonkey attributes ของ Table นั้น

สำหรับขั้นนี้นั้นเราไม่ติดศัพท์อะไรแล้ว เรามาตรวจสอบ Table ที่เราได้จากขั้นตอนที่แล้วกันเลยว่าจะสามารถเป็น 3NF ได้หรือไม่

Table : USER_CURRENCY

Table : USER_CURRENCY

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF

Table : CURRENCY

Table : CURRENCY

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • COUNTRY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF

Table : USER

Table : USER

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE
    • PRIORITY
  2. FD ระหว่าง Nonkey attribute

    • USER_TYPE -> PRIORITY

Table นี้ไม่เป็น 3NF เพราะเราตรวจพบ FD คือ USER_TYPE -> PRIORITY ซึ่งเป็น Nonkey attribute

วิธีแก้ไข

ให้ทำการแยกตารางออกไปตาม FD ของ Nonkey attribute ครับ ส่วน Table เดิมเก็บ Column ที่เป็นตัวกำหนดไว้ ส่วน Column ที่มีค่าตามให้ลบออกจาก Table โดยจากตัวอย่างเราจะแก้ไข Table : USER ลบ Column : PRIORITY และ สร้าง Table USER_TYPE ขึ้นมาใหม่

Table : USER

Table : USER

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • USER_TYPE
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF ตามนิยาม

Table : USER_TYPE

Table : USER_TYPE

ตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Nonkey attribute มีดังต่อไปนี้

    • PRIORITY
  2. FD ระหว่าง Nonkey attribute

    ไม่มีเพราะมี Nonkey attribute ตัวเดียว

เนื่องจาก Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes และ Table นี้ก็เป็น 2NF ดังนั้น Table จึงเป็น 3NF ตามนิยาม

Table ที่เป็น 3NF ที่มีปัญหา INSERT , DELETE , UPDATE

Table ที่เป็น 3NF และมีปัญหา INSERT , DELETE , UPDATE

เรามาดูรายละเอียดของ TABLE นี้เพื่อนำไปใช้ในการตรวจสอบว่า Table นี้เป็น 3NF ไหม

  1. Primary key : { USERNAME , CURRENCY_CODE }
  2. Candidate key : { USERNAME , CURRENCY_CODE } , { EMAIL, CURRENCY_CODE }
  3. Nonkey attribute มีดังต่อไปนี้
    • AMOUNT
      EMAIL ไม่เป็น Nonkey attribute เพราะมันเป็น 1 ใน Candidate key
  4. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT
    • { EMAIL , CURRENCY_CODE } -> AMOUNT
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

ตรวจสอบ NF แต่ละขั้น

  • 1NF
    เป็น 1NF เพราะทุก Column ( Attribute ) เป็น Atomic และ แต่ละ Column มีค่ามาจาก Domain เดียว
  • 2NF
    เป็น 2NF เพราะ ความสัมพันธ์ระหว่าง Primary key กับ nonkey attribute ทุกตัวเป็น Full functional dependence ดูได้จาก { USERNAME , CURRENCY_CODE } เป็น Full FD กับ AMOUNT ซึ่งเป็น nonkey attribute ตัวเดียว
  • 3NF
    เป็น 3NF เพราะ Table นี้เป็น 2NF และ Table นี้ไม่มี funcational dependence ระหว่าง nonkey attributes ดูได้จาก Nonkey attribute มีตัวเดียว

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

ตัวอย่างปัญหา Insert ข้อมูลไม่ถูกต้องเข้าไปได้

Table นี้จะมีปัญหาการ Insert ข้อมูลที่ไม่ถูกต้องเข้าไปได้ดูได้จากเราสามารถ Insert ข้อมูล EMAIL ของ USERNAME : apirat เป็น champ007@gmail.com ได้ ซึ่งนั่นทำให้เกิดปัญหา Data inconsistency

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

จากตัวอย่างเราไม่สามารถ Insert ข้อมูลของ User ใหม่เข้าไปได้เลย เช่น ถ้าผมต้องการ Insert ข้อมูล User : wasinee เข้าไปผมจะไม่สามารถเข้าไปได้เพราะติดกฎ Primary key must not be null

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

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

จากตัวอย่างถ้าเราลบข้อมูลการ Row ที่ผมล้อมกรอบสีแดงไว้ ข้อมูลของ User : apirat จะหายไปเลย ทั้งๆที่เราอยากลบข้อมูลการที่เขามีเงินสกุล THB ไปเท่านั้น

ตัวอย่างปัญหา Delete ข้อมูล

ซึ่งจากป้ญหานี้จึงต้องทำ Normalization ขั้นตอนต่อไป

BCNF

A relation table structure T is in the Boyce/Codd normal form (BCNF) if and only determinant in T is a candidate key of T.

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

Table จะเป็น BCNF ได้นั้น Determinant ทั้งหมดใน Table จะต้องเป็น Candidate key ของ Table

ผมว่าคุณน่าจะไม่เข้าใจเพราะติดศัพท์เทคนิค Determinant ว่าคืออะไร

Determinant

ถ้าเราบอกว่า A กับ B มีความสัมพันธ์แบบ Functional dependence โดยค่าของ A เป็นตัวกำหนดว่าค่าของ B เราจะสามารถซึ่งจะเขียนอธิบายแบบนี้ A -> B ซึ่ง A จะเป็น Determinant ดังนั้นถ้ามีความสัมพันธ์ FD ที่ USERNAME -> EMAIL ก็แปลว่า USERNAME เป็น Determinant

ตรวจสอบ Table ที่เป็น 3NF ที่มีปัญหาว่าเป็น BCNF ไหม

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

  1. Candidate key : { USERNAME , CURRENCY_CODE } , { EMAIL, CURRENCY_CODE }
  2. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT
    • { EMAIL , CURRENCY_CODE } -> AMOUNT
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

เนื่องจาก Table นี้มี Determinant ที่ไม่เป็น Candidate key คือ USERNAME และ EMAIL ดังนั้น Table นี้ไม่ได้เป็น BCNF

วิธีแก้ไข

วิธีแก้ไขให้ Table นี้ให้เป็น BCNF นั้นสามารถทำได้โดยแยกเอา COLUMN ที่เป็น Determinant ที่ไม่ได้เป็น Candidate key ออกไปโดยผมจะเลือกเอา Column EMAIL ออกไปซึ่งจะทำให้เราจะได้ตารางใหม่สองตารางเป็น

TABLE : BCNF_USER_CURRENCY

TABLE : BCNF_USER_CURRENCY

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

  1. Candidate key : { USERNAME , CURRENCY_CODE }
  2. FD ใน Table
    • { USERNAME , CURRENCY_CODE } -> AMOUNT

เนื่องจาก Determinant ของทุก FD เป็น Candidate key ดังนั้น Table นี้จึงเป็น BCNF

TABLE : BCNF_USER

TABLE : BCNF_USER

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

  1. Candidate key : USERNAME , EMAIL
  2. FD ใน Table
    • USERNAME -> EMAIL
    • EMAIL -> USERNAME

เนื่องจาก Determinant ของทุก FD เป็น Candidate key ดังนั้น Table นี้จึงเป็น BCNF

เกี่ยวกับ BCNF

โดยปกติแล้ว Table ที่เป็น 3NF ส่วนใหญ่นั้นจะไม่มีปัญหา INSERT , DELETE , UPDATE ที่มาจากความสัมพันธ์ FD แล้ว แต่จะมีบางกรณีแบบในตัวอย่างที่เป็น 3NF แล้วแต่ยังมีปัญหา ดังนั้นจึงมีการคิดค้น BCNF เพื่อตรวจสอบและจัดการกับกรณีนี้

สรุป

สำหรับตอนนี้เราได้เรียนรู้เกี่ยวกับ Normalization Process ว่ามีกระบวนการอย่างไร Normal Form ตั้งแต่ขึ้น 1NF ถึง BCNF ได้รู้ว่า Functional Dependency คืออะไร เราได้ลองทำ Normalization Process กับ Table : CURRENTCY_TRADING_SYSTEM ไปจนถึงขั้น BCNF แล้ว (ตัวอย่างผมทำให้ดูถึง 3NF คุณลองไปทำต่อดูว่า Table เหล่านั้นเป็น BCNF ได้ยังไง) ซึ่งเราจะได้ Table ทั้งหมดตามภาพด้านล่าง

Table ทั้งหมดที่เป็น BCNF

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

Ref

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