Basic Database System Part 2 - Relational Database Model

Basic Database System Part 2 - Relational Database Model

ในตอนที่แล้วเราได้รู้ว่า Database , Database Model , DBMS คืออะไรกันไปแล้ว ในตอนนี้เราจะมาลงรายละเอียดเกี่ยวกับ Relational Database Model กัน

Relation คืออะไร

ถ้าคุณไปถามคนในวงการคอมพิวเตอร์ว่า Relation คืออะไรในเนื้อหาเกี่ยวกับ Database บางคนอาจจะบอกว่ามันคือความสัมพันธ์ ซึ่งอยากจะบอกว่ามันไม่ใช่นะครับ ตามนิยามแล้ว Relation คือ Subset ของ Cartesian product ของ Domain ( Subset of the Cartesian product of domains ) ซึ่งผมเชื่อว่าหลายคนอ่านแล้วอาจจะไม่เข้าใจ ตอนผมเรียนตอนปี 3 ผมฟังครั้งแรกก็ไม่เข้าใจเหมือนกันครับ ดังนั้นเรามาดูตัวอย่างเพื่อทำความเข้าใจกันดีกว่า

กำหนดให้มี Domain ดังต่อไปนี้ (จะมองว่า Domain คือ Column ก็ได้นะครับ)

Domain : Name มีค่าที่เป็นไปได้คือ : { Wasinee , Sunisa , Thanaporn }

Domain : Subject มีค่าที่เป็นไปได้คือ : { Math , Physic }

Domain : Status มีค่าที่เป็นไปได้คือ : { PASS , FAIL }

Cartesian product ของ Domain ก็คือเอาทุกค่าของแต่ละ Domain มารวมกันในทุกความเป็นไปได้ ซึ่งจะเห็นว่ามีทั้งหมด 12 แบบซึ่งเกิดจาก 3 x 2 x 2 ดังภาพ

Cartesian product ของ Domain

ถ้าสังเกตจะเห็นว่าค่ามันอาจจะดูแปลกๆในความเป็นจริงที่ Wasinee จะสอบผ่านและสอบตกวิชา Physic พร้อมกัน อีกทั้งคนหนึ่งคนไม่จำเป็นต้องสอบทุกวิชาหรือบางคนอาจไม่สอบสักวิชาเลยก็ได้ ซึ่งข้อมูลที่เกิดขึ้นจริงที่จะคือ

ข้อมูลที่เกิดขึ้นจริง

ซึ่งจะเห็นว่าข้อมูลที่เกิดขึ้นจริงนั้นเป็น Subset ของ Cartesian product ของ Domain (คุ้นๆไหม) ดังนั้นข้อมูลที่เกิดขึ้นจริงก็คือ Relation นั่นเอง

คราวนี้คุณก็เข้าใจแล้วนะครับว่า Relation คืออะไร ทำไมต้องเป็น Subset ของ Cartesian product ของ Domain

( อันนี้เรื่องตลกนะครับรู้ไว้เอาฮาไม่รู้ก็ไม่เป็นไร เวลารุ่นพี่รุ่นน้องเด็กวิศวคอมลาดกระบังเจอกันแล้วไม่รู้จักกัน คำถามหนึ่งที่สามารถถามกันเพื่อเช็คว่าเฮ้ยเอ็งใช่รุ่นพี่หรือรุ่นน้องจริงรึเปล่าวะคำถามหนึ่งคือ Relation คืออะไร ซึ่งเด็กวิศวคอมลาดกระบังที่เรียน Database แล้วจะตอบแนวๆนี้หมดครับ )

Relational Database Table

เรารู้แล้วว่า Relation คืออะไร แต่เราจะแสดง Relation ให้คนดูยังไงให้เข้าใจ วิธีที่จะแสดง Relation ให้คนเข้าใจก็คือเอาไปแสดงเป็น Table นั่นเอง จริงๆ Relation มันจะไม่มีการบอกว่าค่าแต่ล่ะค่ามาจาก Domain (Column) อะไร ตัวอย่าง Relation แบบไม่แสดงในตารางจะเป็นแบบด้านล่าง (จริงๆ Relation แสดงได้ด้วยสมการทางคณิตศาสตร์เลยนะครับ)

1
2
3
4
5
Relation = { 
(Wasinee, Math, PASS) ,
(Thanaporn, Math, PASS) ,
(Thanaporn, Physic, FAIL)
}

ดังนั้นเพื่อให้คนทั่วไปเข้าใจ Relation ได้ง่ายขึ้นเขาจึงทำให้มันอยู่ในรูปแบบของ Table ดังภาพที่คุณเห็นตัวอย่างที่ผมอธิบายที่มีหัวตารางเป็นการบอกว่าค่านี้มาจาก Domain (Column) ไหนเพื่อให้เข้าใจง่ายขึ้น คราวนี้ Table ที่แสดง Relation ได้นั้นจะต้องมีคุณสมบัติดังต่อไปนี้

  1. Row ต้องไม่ซ้ำ

  2. ลำดับของ Row ไม่มีความสำคัญ ว่าง่ายๆคือ Row 1 กับ Row 2 สลับที่กันก็ไม่มีความสำคัญ

  3. ลำดับของ Column ไม่มีความสำคัญ ว่าง่ายๆคือ จะสลับ Column 1 กับ Column 2 กันก็ไม่มีผลอะไร

  4. ค่าใน Column นั้นต้องเป็นค่าที่อยู่ใน Domain เดียวกัน ไม่ได้มาจากหลากหลาย Domain

  5. ค่าใน Column ต้องเป็นค่าค่าเดียวไม่ใช่ Set หรือ List

กฎของ Relational Database

ในส่วนที่แล้วเรารู้แล้วว่า Relation คืออะไร หน้าตาเป็นอย่างไร ซึ่งเป็นหนึ่งในส่วนประกอบของ Database model ส่วนต่อมาที่เราต้องรู้คือกฎของ Database นั่นเอง

The Entity Integrity : Primary key must not be NULL

ก็ตามนั้นเลยครับ Primary key ต้องไม่มีค่าเป็น NULL คราวนี้คุณอาจจะสงสัยว่า Primary key คืออะไร NULL คืออะไร เรามาทำความเข้าใจกันทีละตัวครับ เริ่มจาก NULL ก่อน

NULL

สำหรับ NULL นั้นแปลว่าไม่มีค่าหรืออาจจะแปลว่าไม่รู้ก็ได้ครับ ตัวอย่างเช่น Relation ดังภาพด้านล่าง

ตัวอย่างการเก็บค่า NULL

จะเห็นว่า Row : Wasinee นั้นมีค่า Salary เป็น NULL ซึ่งแปลว่าเราไม่รู้ว่าค่า Salary ของ Wasinee เป็นเท่าไหร่

Primary key

ก่อนรู้จัก Primary key เรามารู้จัก Super key ก่อน Super key คือกลุ่มของ Column ที่ใช้เป็นใช้อ้างถึง Row นั้นได้เพียง Row เดียว (ภาษาไทยอธิบายยาก ภาษาอังกฤษเขานิยามไว้แบบนี้น่าจะเข้าใจมากกว่า : A super key is a set of attribute whose value uniquely identifies a tuple ) ผมว่าอ่านที่ผมอธิบายแล้วน่าจะไม่เข้าใจ ดังนั้นดูตัวอย่างน่าจะเข้าใจง่ายกว่า

ตัวอย่าง Table : USER

จากภาพด้านบนเราจะเห็นว่า Table (ขอเรียก Relation เป็น Table เลยนะครับ) นี้มี 3 Column คือ USERNAME , EMAIL , DATE OF BIRTH ถ้าดูตอนนี้เราจะพบว่ามี Super key ทั้งหมดคือ

  1. USERNAME , EMAIL , DATE OF BIRTH

  2. USERNAME , EMAIL

  3. USERNAME , DATE OF BIRTH

  4. EMAIL , DATE OF BIRTH

  5. USERNAME

  6. EMAIL

วิธีพิสูจน์ว่าจริงไหมให้คุณเอาค่าจากกลุ่ม Column เหล่านี้ไปหาใน Table ครับ เวลาเอาค่าไปหามันจะอ้างถึงแค่ Row เดียวเสมอ ซึ่งจะเห็นว่า DATE OF BIRTH Column เดียวไม่สามารถอ้างถึง Row ได้แค่ Row เดียวดูได้จากถ้าอ้างด้วย 1990-05-16 จะอ้างถึงได้ 2 Row

ต่อไปเรามารู้จัก Candidate Key ซึ่งก็คือ Super key ที่ไม่มี Super key อื่นเป็น Subset (นิยามภาษาอังกฤษน่าจะเข้าใจง่ายกว่า : A candidate key is defined as a superkey which has no other superkeys as a subset (or has no superkeys as its proper subset) ) ก็ตามเดิมครับอ่านแล้วไม่เข้าใจมาดูตัวอย่างกันดีกว่า เรามาไล่พิจารณาจาก Super key ที่เราหาได้จากตัวอย่างที่แล้วว่ามีอันไหนเป็น Candidate Key ได้บ้าง

  1. USERNAME , EMAIL , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME , EMAIL } ที่เป็น Subset

  2. USERNAME , EMAIL

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME } ที่เป็น Subset

  3. USERNAME , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { USERNAME } ที่เป็น Subset

  4. EMAIL , DATE OF BIRTH

    ไม่เป็น Candidate key เพราะมี Super key อื่นเป็น Subset ดูได้จาก Super key { EMAIL } ที่เป็น Subset

  5. USERNAME

    เป็น Candidate key เพราะไม่มี Super key อื่นเป็น Subset

  6. EMAIL

    เป็น Candidate key เพราะไม่มี Super key อื่นเป็น Subset

ทั้งหมดที่อธิบายนั้นปูทางมาเพื่ออธิบายว่า Primary key คือตัวหลักที่ใช้อ้างอิงถึง Row นั้นโดยเราจะเลือกตัวอ้างอิงหลักนี้มาจาก Candidate key ( การแปลเป็นไทยมันยากมาก ผมว่าอ่านนิยามภาษาอังกฤษเข้าใจง่ายกว่า The primary key is the principle identifier of the relation; and is simply defined as a selected by candidate key ) ถ้าจากตัวอย่างด้านบนเราสามารถกำหนด Primary key ได้จาก USERNAME หรือ EMAIL ซึ่งเป็น Candidate key ครับ

สมมติถ้าเราเลือก USENAME เป็น Primary key Column USERNAME จะต้องไม่มีค่าเป็น NULL ครับ นี่คือ กฎที่ว่า Primary key must not be NULL

ตรงนี้อาจจะมีคนสงสัยว่าทำไมต้องห้าม Primary key มีค่าเป็น NULL ลองอ่านกฎข้อต่อไปครับจะเข้าใจ

The Referential Integrity : Foreign key values must match primary key values or be null

Foreign key is defined as nonkey attribute(s) in a relation which is the primary key of other relation or the same relation. A non key attribute is define as an attribute which is not a candidate key.

ผมว่าเริ่มด้วยนิยาม Foreign key แบบภาษาอังกฤษเลยดีกว่าถ้าเข้าใจแล้วจะได้ไม่ต้องเสียเวลามาอ่านภาษาไทยที่ผมพยายามจะอธิบาย หากใครอ่านไม่เข้าใจลองมาอ่านที่ผมอธิบายดูครับ

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

Foreign key คือ Column หรือ กลุ่มของ Column ที่ไม่ได้เป็น Candidate key ของ Relation ปัจจุบัน (ที่ Foreign key นี้อยู่ ) ซึ่ง Column หรือกลุ่มของ Column นั้นต้องอ้างอิงถึง Primary key ของ Relation อื่นหรือ Relation เดียวกัน อ่านแล้วอาจจะงง (แน่นอนผมก็งง) ลองไปดูตัวอย่างดีกว่าครับ ของแบบนี้ดูตัวอย่างน่าจะเข้าใจง่ายกว่า

ตัวอย่าง Foreign key

จากภาพด้านบนเราจะเห็นว่ามี Table : Book ที่เก็บข้อมูลเกี่ยวกับการยืมหนังสือ คราวนี้สังเกตที่ Column : Borrow By ที่เป็น Column ที่บอกว่าใครเป็นคนยืม โดยตัว Column นี้ต้องการอ้างอิงถึง Primary key ของ Table : User ที่เก็บข้อมูลผู้ใช้ ดังนั้นเมื่อต้องการอ้างอิงแบบนี้ตัว Column : Borrow By จะกลายเป็น Foreign key

คราวนี้เรามาลองตรวจดูว่า Column : Borrow By เป็น Foreign key ได้หรือไม่

  1. Column หรือ กลุ่มของ Column ไม่ได้เป็น Candidate key

    จากตัวอย่างจะเห็นว่า Column : Borrow By นี้ไม่ได้เป็น Candidate key (ดูได้จากถ้าหา Row ด้วยค่าของ Column นี้จะผลลัพธ์ออกมามากกว่า 1 Row )

  2. อ้างอิงถึง Primary key ของ Relation อื่นหรือ Relation ตัวเอง

    จากตัวอย่าง Column : BORROW BY อ้างอิงถึง Column : USERNAME ซึ่งเป็น Primary key ของ Table : USER

ถ้าเราเลือก Column : Borrow By จะเป็น Foreign key ดังนั้นค่าที่อยู่ใน Column : Borrow By จะต้องมีค่าจริงๆอยู่ใน Table : USER Columnn : USERNAME หรือไม่ก็มีค่าเป็น NULL ซึ่งจากในตัวอย่างจะเห็นว่าค่าใน Column : Borrow By มีค่าตรงกับ Column : USERNAME หรือไม่ก็มีค่า NULL นี่แหละครับ นี่คือตัวอย่างของกฎที่ว่า Foreign key values must match primary key values or be null

สำหรับใครที่สงสัยว่าทำไมกฎข้อแรกบอกว่า Primary key ห้ามมีค่าเป็น NULL ตรงนี้น่าจะเข้าใจแล้วนะครับ เพราะถ้าเรายอมให้ค่า Primary key มีค่าเป็น NULL ได้ เวลามี Row นั้นไม่มีได้ต้องการอ้างอิงถึงอีก Table เช่นถ้าจากตัวอย่างคือหนังสือเล่มนี้ไม่ได้ถูกยืม พอไม่ถูกยืมเลยจะกำหนดค่า BORROW BY เป็น NULL คราวนี้ถ้าเรายอมให้ Primary key มีค่าเป็น NULL ได้มันก็กลายเป็นว่าจะอ้างอิงถึง Row ที่ Primary key มีค่าเป็นค่า NULL ซึ่งนั่นไม่ใช่สิ่งที่เราต้องการ เราต้องการบอกว่าหนังสือไม่มีคนยืมไม่ใช่อ้างอิงถึงหนังสือที่ Primary key มีค่าเป็น NULL ดังนั้นจึงต้องมีการกำหนดให้ Primary key ต้องไม่มีค่าเป็น NULL

ภาษาที่ใช้กับ Relational Database Model

สำหรับภาษาที่นิยมนำมาใช้กับ Relational Database Model นั้นคือภาษา Structured Query Language (SQL) โดยเราสามารถแบ่งภาษา SQL ออกเป็นประเภทตามการใช้งานได้ดังต่อไปนี้

  1. Data Definition Language (DDL)

    คำสั่งประเภทนี้จะเกี่ยวข้องกับการกำหนดโครงสร้างต่างๆของ Database เช่น ทำการสร้าง Database , สร้าง Table แก้ไข Table ลบ Table เป็นต้น โดยคำสั่งพวกนี้จะมี Key word ประมาณ CREATE , ALTER , DROP เรามาดูตัวอย่างคำสั่งเหล่านี้กันครับ

    ตัวอย่างการสร้าง Database

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE DATABASE PRESIDENT;
    ```

    ตัวอย่างการสร้าง Table

    ```sql
    CREATE TABLE IF NOT EXISTS PRESIDENT (
    `PRES_NAME` VARCHAR(128) ,
    `BIRTH_YR` INT,
    `YRS_SERV` INT,
    `DEATH_AGE` INT ,
    `PARTY` VARCHAR(128) ,
    `STATE_BORN` VARCHAR(128)
    );
  2. Data Manipulation Language (DML)

    คำสั่งเหล่านี้จะเป็นคำสั่งเกี่ยวกับการ ค้นหา เพิ่ม ลบ แก้ไข ข้อมูล เช่น ต้องการค้นหาข้อมูลใน Table ภายใต้เงื่อนไขต่างๆ หรือ ต้องการเพิ่มข้อมูลเข้าไปใน Table โดยคำสั่งประเภทนี้จะมี Key word ประมาณ SELECT , UPDATE , DELETE , INSERT

    ตัวอย่าง คำสั่ง INSERT ที่ต้องการเพิ่มข้อมูล Table PRESIDENT

    1
    2
    3
    4
    INSERT INTO PRESIDENT VALUES
    ('Washington G',1732,7,'67','Federalist','Virginia'),
    ('Adams J',1735,4,'90','Federalist','Massachusetts'),
    ('Jefferson T',1743,8,'83','Demo-Rep','Virginia');

    ตัวอย่าง คำสั่ง SELECT ที่ทำการค้นหาข้อมูลที่ใน Table : PRESIDENT ภายใต้เงื่อนไขที่ว่า PARTY = ‘Federalist’

    1
    2
    3
    SELECT *
    FROM PRESIDENT
    WHERE PARTY = 'Federalist';

    ตัวอย่าง คำสั่ง UPDATE ทำการแก้ไขข้อมูล YRS_SERV ที่ ROW ที่มีค่า PRES_NAME = ‘Washington G’

    1
    2
    3
    UPDATE PRESIDENT 
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Washington G';

    ตัวอย่าง คำสั่ง DELETE ลบข้อมูล ROW ที่มีค่า PRES_NAME = ‘Washington G’

    1
    2
    DELETE FROM PRESIDENT
    WHERE PRES_NAME = 'Washington G';

    สำหรับใครอยากเรียนเกี่ยวกับคำสั่ง SQL ประเภท Data Manipulation Language ในส่วนของการ SELECT ผมมีทำคลิปสอนไว้ คุณสามารถไปดูได้ตาม Link นี้เลยครับ

  3. Data Control Language (DCL)

    คำสั่งจำพวกนี้จะเป็นคำสั่งเกี่ยวกับการกำหนดสิทธิ์ เช่น กำหนดสิทธิ์ให้สามารถทำอะไรกับ Database ได้บ้าง เช่น SELECT ข้อมูลใน Table ได้ไหม DELETE ข้อมูลใน Table ได้ โดย Key word ของคำสั่งประเภทนี้จะเป็น GRANT , REVOKE

  4. Transaction Control Language (TCL)

    คำสั่งประเภทนี้เป็นคำสั่งที่เกี่ยวกับ Transaction ซึ่งจะเกี่ยวกับการสั่งให้ตัว Database บันทึกข้อมูลทั้งหมดที่ได้ทำไป หรือ ทำการคืนค่าทั้งหมดที่เคยกลับไปเหมือนไม่มีอะไรเกิดขึ้น (นิยามของ Transaction ไม่ใช่ที่ผมพูด ผมแค่ยกตัวอย่างว่ามันเอาไปใช้งานยังไง นิยาม Transaction จริงๆเดี๋ยวจะอธิบายในตอนอื่นครับ) โดยคำสั่งประเภทนี้จะมี Keyword ประมาณ COMMIT , ROLLBACK , SET AUTO COMMIT OFF เรามาดูตัวอย่างกันดีกว่า

    ถ้าสมมติเราต้องการแก้ไขค่าข้อมูลของ Table : PRESIDENT โดยทำการแก้ไขข้อมูลโดยต้องการทำการเปลี่ยน YRS_SERV ของ Washington G เป็น 4 และ Jefferson T เป็น 5 เราจะได้คำสั่ง SQL ประมาณนี้

    1
    2
    3
    4
    5
    6
    7
    8

    UPDATE PRESIDENT
    SET YRS_SERV = 4
    WHERE PRES_NAME = 'Washington G';

    UPDATE PRESIDENT
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Jefferson T';

    ถ้าเราสั่งคำสั่ง SQL แบบนี้ทุกครั้งจะทำการบันทึกทันทีหลังทำการสั่ง คราวนี้คนที่สั่งเราพึ่งค้นพบว่าเขาบอกข้อมูลผิดแล้วอยากให้เราแก้กลับเป็นค่าเดิมก่อนแก้ไข ซึ่งถ้าเราต้องการอะไรแบบนี้เราสามารถทำได้โดยสั่ง SET AUTO COMMIT OFF ตรงนี้จะเป็นการสั่งว่า คำสั่งที่สั่งไปจะยังไม่ถูกบันทึกลง Database แบบสมบูรณ์ (จริงๆมันบันทึกครับแต่บันทึกให้สามารถย้อนกลับได้) จนกว่าจะสั่ง COMMIT ดังนั้นถ้าได้รับคำสั่งให้แก้ไขข้อมูลแล้วเผื่อให้ย้อนกลับได้ถ้ายังไม่ COMMIT เราสามารถสั่งแบบนี้

    1
    2
    3
    4
    5
    6
    7
    8
    9
    SET AUTO COMMIT OFF;

    UPDATE PRESIDENT
    SET YRS_SERV = 4
    WHERE PRES_NAME = 'Washington G';

    UPDATE PRESIDENT
    SET YRS_SERV = 5
    WHERE PRES_NAME = 'Jefferson T';

    คราวนี้เมื่อสั่งเสร็จคุณอาจจะรอ Confirm กับคนสั่งอีกรอบ ถ้าคนสั่งตรวจทานแล้วข้อมูลถูกต้องแน่นอนคุณก็แค่สั่ง COMMIT ข้อมูลจะถูกบันทึกลง Database แบบสมบูรณ์

    1
    COMMIT;

    แต่ถ้าคนสั่งเขาตรวจอีกรอบแล้วข้อมูลไม่ถูกต้องเขาบอกให้เราแก้ไขข้อมูลกลับไปก่อนมีการแก้ไขเราก็แค่สั่ง ROLLBACK ข้อมูลจะถูกย้อนกลับไปตอนหลังสั่ง SET AUTO COMMIT OFF;

    1
    ROLLBACK;

สรุป

สำหรับตอนนี้เราได้ลงรายละเอียดของ Relational Database Model ตั้งแต่ Relation คืออะไร เราจะเห็นข้อมูลของ Relation ในรูปแบบไหน กฎของ Relational Database model ว่ามีอะไรบ้าง Primary key คืออะไร Foreign key และสุดท้ายมาจบด้วยภาษา SQL ที่ใช้ทำงานกับ Relational Database Model ในตอนถัดไปเรามาพูดถึงเรื่อง Normalization ว่ามันคืออะไร สำคัญอย่างไรกันครับ

Ref

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