ความสัมพันธ์ Table ใน MS Access ฉบับเข้าใจง่าย

ความสัมพันธ์ของ Table แบบง่าย ๆ

เวลาพูดถึง Table ใน Access หลายคนจะนึกถึงตารางสี่เหลี่ยม ๆ คล้าย Excel ก่อนเลย ซึ่งก็ไม่ผิดครับ แต่สิ่งที่ทำให้ Access ต่างจาก Excel มาก ๆ คือ Table แต่ละตัวมันสามารถ "สัมพันธ์กัน" ได้

ถ้าเข้าใจเรื่องความสัมพันธ์ของ Table ได้ ต่อไปเวลาสร้าง Query, Form หรือ Report จะง่ายขึ้นมาก แต่ถ้าไม่เข้าใจ เรามักจะเผลอเอาทุกอย่างไปยัดไว้ในตารางเดียว แล้วสุดท้ายก็จะเจอข้อมูลซ้ำ แก้ยาก และรายงานเพี้ยน

บทความนี้จะเล่าแบบง่าย ๆ ก่อนนะครับ ยังไม่ลงลึกทุกสัญลักษณ์ เอาแค่ให้เห็นภาพว่า Table ควรคุยกันยังไง

เริ่มจากตัวอย่างงานขายง่าย ๆ

สมมติว่าเราจะทำระบบขายของเล็ก ๆ เราอาจจะเริ่มคิดว่า "ก็สร้างตารางขายของขึ้นมาตารางเดียวสิ มีชื่อลูกค้า ชื่อสินค้า จำนวน ราคา วันที่ขาย"

ตอนข้อมูลยังน้อย วิธีนี้ดูง่ายครับ

แต่พอใช้งานจริงจะเริ่มเจอคำถามแบบนี้

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

พอคำถามพวกนี้เริ่มมา แปลว่าเราควรแยก Table แล้วครับ

3 ตารางสำหรับตัวอย่างระบบขายนี้

สำหรับตัวอย่างนี้ เราอาจแยกเป็น 3 ตารางก่อน

  • Customer เก็บข้อมูลลูกค้า
  • Order เก็บหัวใบสั่งซื้อ เช่น วันที่ขาย ลูกค้าคนไหน
  • OrderDetail เก็บรายการสินค้าในใบสั่งซื้อนั้น

เหตุผลที่ต้องแยกแบบนี้ เพราะข้อมูลแต่ละอย่างมีหน้าที่ไม่เหมือนกัน

  • ลูกค้า 1 คน อาจมีหลายใบสั่งซื้อ
  • ใบสั่งซื้อ 1 ใบ อาจมีหลายรายการสินค้า

ดังนั้นถ้าเอาทุกอย่างรวมกันในตารางเดียว ข้อมูลลูกค้าจะซ้ำ ข้อมูลหัวใบสั่งซื้อจะซ้ำ และตอนแก้ไขจะปวดหัวแน่นอนครับ

ความสัมพันธ์แบบ 1 ต่อหลาย

ความสัมพันธ์ที่เจอบ่อยที่สุดใน Access คือแบบ 1 ต่อหลาย

พูดแบบบ้าน ๆ คือ ฝั่งหนึ่งมีข้อมูล 1 รายการ แต่อีกฝั่งมีได้หลายรายการ

ตัวอย่าง

  • ลูกค้า 1 คน มีใบสั่งซื้อได้หลายใบ
  • ใบสั่งซื้อ 1 ใบ มีรายการสินค้าได้หลายรายการ
  • หมวดสินค้า 1 หมวด มีสินค้าได้หลายตัว
  • พนักงาน 1 คน บันทึกเอกสารได้หลายใบ

ใน Access เวลาเราสร้างความสัมพันธ์แบบนี้ ฝั่งที่เป็น "หลาย" จะต้องเก็บรหัสของฝั่ง "หนึ่ง" ไว้ด้วย ซึ่งรหัสนั้นเราเรียกว่า Foreign Key

Primary Key กับ Foreign Key จำยังไง

ให้จำแบบนี้ก่อนก็ได้ครับ

Primary Key คือรหัสประจำแถวของตารางตัวเอง เช่น CustomerID, OrderID

Foreign Key คือรหัสของตารางอื่นที่เราเอามาเก็บไว้เพื่อบอกว่าแถวนี้เกี่ยวข้องกับใคร เช่น ในตาราง Order จะมี CustomerID เพื่อบอกว่าใบสั่งซื้อนี้เป็นของลูกค้าคนไหน

ถ้าเปรียบเทียบง่าย ๆ

  • Customer มีรหัสลูกค้าที่ระบบออกให้เอง เช่น CUST001
  • Order เก็บ CustomerID เอาไว้ เพื่อบอกว่าใบสั่งซื้อนี้เป็นของลูกค้าคนไหน

แล้วทำไมไม่ใช้ชื่อลูกค้าเป็นตัวเชื่อม?

คำถามนี้เจอบ่อยครับ

ถ้าใช้ชื่อลูกค้าเป็นตัวเชื่อม เช่น "สมชาย" ปัญหาคือ

  • อาจมีคนชื่อซ้ำ
  • ชื่ออาจสะกดผิด
  • ลูกค้าอาจเปลี่ยนชื่อ
  • ช่องชื่อมักเป็นข้อความยาวและแก้ไขได้

เพราะฉะนั้นเราจึงใช้รหัสที่แน่นอนกว่า เช่น CustomerID เป็นตัวเชื่อม แล้วชื่อ เบอร์โทร ที่อยู่ เป็นแค่รายละเอียดของลูกค้า

แล้วความสัมพันธ์แบบหลายต่อหลายล่ะ?

ในงานจริงเราจะเจอความสัมพันธ์แบบหลายต่อหลายด้วย เช่น ใบสั่งซื้อ 1 ใบมีสินค้าได้หลายตัว และสินค้า 1 ตัวก็ไปอยู่ได้ในหลายใบสั่งซื้อ

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

วิธีที่ใช้กันคือสร้างตารางกลาง เช่น OrderDetail

  • Order 1 ใบ มี OrderDetail ได้หลายแถว
  • Product 1 ตัว อยู่ใน OrderDetail ได้หลายแถว
  • OrderDetail แต่ละแถวบอกว่าสินค้าตัวไหน อยู่ในใบสั่งซื้อใบไหน จำนวนเท่าไหร่ ราคาเท่าไหร่

พอมองแบบนี้ ความสัมพันธ์แบบหลายต่อหลายจะถูกแยกออกเป็นความสัมพันธ์แบบ 1 ต่อหลายสองชุด ทำให้ Access จัดการได้ง่ายขึ้น

ตัวอย่าง Many to Many ใน Access ต้องมี Table กลาง

จุดที่มือใหม่พลาดบ่อย

จากที่เคยเห็นมา จุดที่พลาดบ่อยคือ

  • สร้างตารางเดียวใหญ่ ๆ เก็บทุกอย่าง
  • ไม่ตั้ง Primary Key
  • ใช้ชื่อแทนรหัสในการเชื่อมตาราง
  • เก็บข้อมูลซ้ำ เช่น ชื่อลูกค้าอยู่ทั้งใน Customer และ Order
  • ยังไม่รู้ว่า Form/Report ที่อยากได้ ต้องเริ่มจาก Table ที่ออกแบบดี

ถ้าหลีกเลี่ยง 5 ข้อนี้ได้ โปรแกรม Access ของเราจะดูแลง่ายขึ้นเยอะครับ

สรุป

ความสัมพันธ์ของ Table ไม่ใช่เรื่องไว้โชว์ใน Diagram อย่างเดียว แต่มันคือโครงกระดูกของโปรแกรม Access ทั้งตัว

ถ้า Table สัมพันธ์กันดี Query จะง่าย Form จะง่าย Report ก็จะง่าย

แต่ถ้า Table วางผิดตั้งแต่แรก ทุกอย่างข้างหลังจะเหนื่อยตามไปหมด

บทความต่อ ๆ ไปจะลงรายละเอียดเรื่อง Table ให้มากขึ้น ว่าตอนสร้าง Table ใน Access ควรตั้งชื่อ field ยังไง เลือกชนิดข้อมูลแบบไหน และอะไรที่ไม่ควรใส่ลงไปในตารางครับ

บทความที่เกี่ยวข้อง

คำถามที่พบบ่อย

ทำไมต้องแยกหลายตาราง ใช้ตารางเดียวให้จบไม่ได้เหรอ

พอข้อมูลเริ่มเยอะ การยัดทุกอย่างในตารางเดียวจะเจอข้อมูลซ้ำ แก้ที่หนึ่งไม่ครบทั้งหมด รายงานเริ่มเพี้ยน และเพิ่ม field ใหม่ลำบาก การแยกตามหน้าที่ของข้อมูลจะดูแลง่ายกว่าในระยะยาว

ใช้ AutoNumber เป็น Primary Key ดีไหม

เหมาะกับ Primary Key ภายในระบบเพราะไม่ซ้ำและไม่ต้องคิดค่าเอง แต่ถ้าต้องการรหัสที่ผู้ใช้เห็นและจำได้ เช่น รหัสสินค้า รหัสลูกค้า ควรมี field รหัสแยกอีกตัวที่ออกแบบรูปแบบเองและตั้งเป็น Unique ไม่ใช่ใช้ AutoNumber โชว์ลูกค้า

ความสัมพันธ์แบบ Many to Many ทำยังไงใน Access

ใช้ตารางกลางเชื่อมสองตารางที่สัมพันธ์แบบ Many to Many เช่น ระหว่าง Order กับ Product จะมีตาราง OrderDetail ที่เก็บ OrderID กับ ProductID ทำให้แต่ละ Order มีหลาย Product และแต่ละ Product อยู่ในหลาย Order ได้

ออกแบบ Table ผิดไปแล้ว แก้ทีหลังได้ไหม

แก้ได้แต่ยิ่งช้ายิ่งเจ็บ ถ้ายังไม่มีข้อมูลจริง การ refactor เร็วและคุ้ม พอมีข้อมูล Form Query Report ผูกหลายชั้นแล้ว ต้องวางแผนย้ายข้อมูลพร้อม ๆ กับเปลี่ยน Form/Query/Report ที่ขึ้นกับโครงสร้างเดิม

บทความที่เกี่ยวข้องกัน: