Table, Row, Column
Mental model ของฐานข้อมูลเชิงสัมพันธ์ row คือ record, column คือ field, primary key + foreign key เชื่อมตารางกัน
Database ของ Vibe Mart มี 5 ตาราง คือ users, categories, products, orders, และ order_items แต่ละตารางเก็บข้อมูลคนละเรื่อง แต่เชื่อมกันด้วย key ก่อนจะเขียน query แรก เราต้องเข้าใจก่อนว่าทำไมถึงต้องแยกตารางแบบนี้
Row, Column, Table ในภาษามนุษย์
ถ้าเคยใช้ Excel มาก่อน ภาพในหัวจะใกล้เคียงกันมาก
- Table เปรียบเหมือน 1 sheet ใน Excel ที่เก็บข้อมูล "หนึ่งเรื่อง" เช่นตาราง users เก็บแค่ลูกค้า ไม่เก็บคำสั่งซื้อ
- Row คือ 1 บรรทัด หมายถึง 1 record เช่น 1 row ในตาราง users คือลูกค้า 1 คน
- Column คือช่อง field ที่กำหนดประเภทข้อมูลไว้แล้ว เช่น
priceเป็น INTEGER จะใส่ตัวอักษรลงไปไม่ได้
ลองเล่นกับ schema ของ Vibe Mart ด้านล่างได้ สลับ tab ไปดูตัวอย่างข้อมูลจริงก็ได้ หรือคลิก column ที่มีกุญแจหรือลูกศร เพื่อดูว่าแต่ละตารางเชื่อมกันยังไง
ทำไมต้องแยก users กับ orders
เคยเห็น spreadsheet ที่ยัดทุกอย่างไว้ใน sheet เดียวไหม ทั้งชื่อลูกค้า email จังหวัด สินค้า ราคา รวมในแถวเดียวหมด ปัญหาคือถ้าลูกค้าคนเดียว สั่งซื้อ 50 ครั้ง ชื่อกับ email จะถูก copy ไปอยู่ครบ 50 ครั้ง วันที่ลูกค้าเปลี่ยน email คุณต้องไล่แก้ครบทั้ง 50 row พลาดไปสักจุด ข้อมูลก็จะเริ่มไม่ตรงกัน
Database ไม่ทำแบบนั้น ลูกค้าจะถูกเก็บไว้ที่ users ตารางเดียว คำสั่งซื้อเก็บที่ orders โดยมี column user_id ที่ "ชี้กลับ" ไปบอกว่าคำสั่งซื้อนี้เป็นของใคร ลูกค้าเปลี่ยน email ก็แก้ที่ตาราง users ที่เดียว คำสั่งซื้อทั้ง 50 อันก็เห็น email ใหม่ทันที
หลักการนี้มีศัพท์เรียกว่า normalization หมายถึง เก็บข้อมูลแต่ละเรื่องไว้ที่เดียว ใครอยากใช้ก็มาดึงผ่าน key
Primary Key กับ Foreign Key
- Primary Key (PK) คือรหัสที่ไม่ซ้ำของ row นั้น ส่วนใหญ่จะเป็น
idที่เป็นเลขนับขึ้นเรื่อยๆ เช่นusers.id = 1, 2, 3, ... - Foreign Key (FK) คือ column ที่ "ชี้กลับ" ไปที่ PK ของอีกตาราง เช่น
orders.user_idชี้ไปที่users.id
Database จะ "การันตี" ความสัมพันธ์นี้ให้ ถ้าคุณ insert order ที่มี user_id = 999 แต่ใน users ไม่มี id นี้อยู่ database จะปฏิเสธทันที ไม่ปล่อยให้มี order ที่ไม่มีเจ้าของ
Datatype สำคัญยังไง
ใน Excel เราพิมพ์อะไรลงช่องราคาก็ได้ ทั้ง "100", "หนึ่งร้อย", หรือแม้แต่ "🤡" ไม่มีใครห้าม ส่วน Database บังคับว่า price INTEGER NOT NULL หมายความว่าต้องเป็นเลขจำนวนเต็ม ห้ามว่าง ลองยัดตัวอักษรเข้าไปก็จะโดนปฏิเสธทันที
ผลที่ได้คือ bug ที่เกิดจาก "ข้อมูลผิดประเภท" จะถูกจับตั้งแต่ตอน insert ไม่ใช่รอไปพังตอนที่ user กำลังใช้งานอยู่ในช่วงสุดสัปดาห์
สรุปบทนี้
- Table เก็บข้อมูลเรื่องเดียว row คือ record column คือ field ที่มี datatype กำกับไว้
- Primary Key คือรหัสไม่ซ้ำของแต่ละ row ในตาราง
- Foreign Key ชี้กลับไปยัง PK ของอีกตาราง เพื่อเชื่อมความสัมพันธ์
- Datatype ช่วยบังคับประเภทข้อมูล ทำให้จับ bug ได้ตั้งแต่ตอน insert ไม่ต้องรอให้พังตอน query
- บทถัดไปจะเริ่มดึงข้อมูลออกมาดูด้วย
SELECTและWHERE