เมื่อวานคุณสั่งลาเต้เย็นผ่านแอปร้านกาแฟ แล้วปิดแอปไป เช้านี้เปิดขึ้นมาใหม่ ปุ่ม “สั่งแก้วเดิมอีกครั้ง” รออยู่ พร้อมชื่อของคุณและเมนูเดิมเป๊ะ แอปไม่ได้มีความจำเหมือนคน แล้วใครเป็นคนจำ?
คำตอบสั้น ๆ คือ ฐานข้อมูล แต่ก่อนจะไปถึงคำนั้น เราต้องเข้าใจก่อนว่าทำไมหน้าเว็บเองถึงจำอะไรไม่ได้เลย
ตอนที่ 1หน้าเว็บเป็นสิ่งที่ขี้ลืมมาก
ทุกครั้งที่คุณเปิดหน้าเว็บ เบราว์เซอร์จะสร้างหน้านั้นขึ้นมาใหม่จากไฟล์ที่ได้รับ ข้อมูลที่เกิดขึ้นระหว่างใช้งาน เช่น จำนวนกาแฟในตะกร้า ถูกเก็บไว้ใน หน่วยความจำชั่วคราว ของเครื่องคุณ ซึ่งเป็นพื้นที่ทำงานที่เร็วมาก แต่ถูกล้างทิ้งทันทีที่ปิดแท็บหรือกดรีเฟรช
ลองนึกถึงการจดตัวเลขบนไวต์บอร์ดระหว่างประชุม พอประชุมจบ แม่บ้านมาลบกระดานทิ้ง ถ้าไม่มีใครจดลงสมุด ตัวเลขนั้นก็หายไปตลอดกาล หน้าเว็บก็คือไวต์บอร์ดแผ่นนั้น
หยุดคิดสักนิด
ถ้าหน้าเว็บลืมทุกอย่างเมื่อรีเฟรช แล้วคำสั่งซื้อเมื่อวานของเราไปอยู่ที่ไหน ถึงยังเปิดดูได้วันนี้?
ทดลองดูด้วยตัวเองด้านล่าง ฝั่งซ้ายคือข้อมูลที่อยู่แค่ในหน้าเว็บ ฝั่งขวาคือข้อมูลที่ถูกส่งไปบันทึกบนเซิร์ฟเวอร์ หยิบกาแฟใส่ตะกร้า บันทึกบ้าง ไม่บันทึกบ้าง แล้วกดรีเฟรช
ทดลอง · ความจำชั่วคราว vs ความจำถาวร
Simulationในหน้าเว็บ (ตัวแปรในหน่วยความจำ)
ตะกร้า: 0 แก้ว
ว่างเปล่า
บนเซิร์ฟเวอร์ (ฐานข้อมูล)
บันทึกไว้: 0 แก้ว
ยังไม่มีอะไรถูกบันทึก
หยิบกาแฟสักสองสามแก้ว ลองบันทึกบ้าง ไม่บันทึกบ้าง แล้วกดรีเฟรช
ความเชื่อที่พบบ่อย
“ประวัติการสั่งกาแฟของเราถูกเก็บไว้ในแอปบนมือถือของเราเอง”
ตอนที่ 2ฐานข้อมูลคือสมุดบันทึกที่เคร่งครัดที่สุดในโลก
- Databaseฐานข้อมูล
- โปรแกรมที่ทำงานอยู่บนเซิร์ฟเวอร์ มีหน้าที่เก็บข้อมูลไว้อย่างถาวรและเป็นระเบียบ ค้นหาสิ่งที่ถูกขอได้รวดเร็ว และปฏิเสธข้อมูลที่ผิดกฎที่ตั้งไว้ ตัวอย่างที่ใช้กันแพร่หลายคือ PostgreSQL, MySQL และ SQLite
ฐานข้อมูลไม่ใช่กล่องที่โยนอะไรลงไปก็ได้ มันเหมือนห้องเก็บเอกสารที่มีตู้หลายใบ ตู้แต่ละใบเก็บเอกสารเพียงชนิดเดียว และเอกสารทุกแผ่นต้องกรอกตามแบบฟอร์มเดียวกัน
เจาะลึก · สำหรับคนที่อยากรู้มากกว่านี้ทำไมไม่เก็บข้อมูลเป็นไฟล์ธรรมดาบนเซิร์ฟเวอร์ไปเลย?
ตอนที่ 3ตาราง แถว และคอลัมน์
ฐานข้อมูลส่วนใหญ่ที่เว็บไซต์ใช้ เก็บข้อมูลเป็น ตาราง หน้าตาคล้ายตารางใน Excel ร้านกาแฟของเราอาจมีตาราง customers สำหรับลูกค้า และตาราง orders สำหรับคำสั่งซื้อ
- Table · Row · Columnตาราง · แถว · คอลัมน์
- ตาราง คือที่เก็บข้อมูลชนิดเดียวกัน เช่น ลูกค้าทั้งหมด แถว คือข้อมูลหนึ่งชิ้น เช่น ลูกค้าหนึ่งคน คอลัมน์ คือคุณสมบัติที่ทุกแถวต้องมี เช่น ชื่อ หรือเมือง
id | name | city ---+------------------+----------- 1 | สมชาย ใจดี | เชียงใหม่ 2 | มาลี ศรีสุข | กรุงเทพฯ 3 | อนันต์ แก้วมณี | ขอนแก่น
ตารางมีไว้ให้ถาม ลองถามตาราง customers ของร้านด้วยตัวเอง ตอนนี้ร้านมีลูกค้าห้าคน กดคำถามทีละข้อ แถวที่ตอบคำถามจะสว่างขึ้น ส่วนแถวอื่นจางลง ยังไม่ต้องจำไวยากรณ์ของคำสั่ง แค่สังเกตว่าคำถามแต่ละแบบคัดแถวออกมาอย่างไร
ถามตาราง
ลูกค้าทั้งห้าคนของร้านกาแฟ
← เลือกคำถามด้านบน
| id | name | city |
|---|---|---|
| 1 | สมชาย ใจดี | เชียงใหม่ |
| 2 | มาลี ศรีสุข | กรุงเทพฯ |
| 3 | อนันต์ แก้วมณี | ขอนแก่น |
| 4 | ปรียา บุญมา | เชียงใหม่ |
| 5 | สมชาย รักดี | ภูเก็ต |
แถวที่ตอบคำถามจะสว่างขึ้น แถวอื่นจางลง
เป้าหมาย: กดลองคำถามให้ครบทั้ง 4 ข้อ
ตอนที่ 4สี่สิ่งที่ทำกับข้อมูลได้
ไม่ว่าแอปจะซับซ้อนแค่ไหน สิ่งที่มันทำกับฐานข้อมูลมีแค่สี่แบบ คือ สร้างของใหม่ อ่านของที่มี แก้ไข และลบทิ้ง วงการโปรแกรมเมอร์ย่อสี่คำนี้ว่า CRUD
- CRUDสร้าง · อ่าน · แก้ไข · ลบ
- ย่อมาจาก Create, Read, Update และ Delete การกระทำพื้นฐานสี่อย่างที่ระบบเกือบทุกระบบทำกับข้อมูล
- Create — สมัครสมาชิกใหม่ หรือกดสั่งกาแฟ ทำให้เกิดแถวใหม่ในตาราง
- Read — เปิดดูประวัติการสั่งซื้อ หรือค้นหาเมนู คือการอ่านโดยไม่เปลี่ยนอะไร
- Update — เปลี่ยนที่อยู่จัดส่ง คือการแก้ค่าในแถวที่มีอยู่แล้ว
- Delete — ลบบัญชีหรือยกเลิกรายการ คือการเอาแถวออกจากตาราง
ลองฝึกสายตาก่อนไปต่อ ทุกอย่างที่คุณทำในแอปร้านกาแฟ เบื้องหลังคือหนึ่งในสี่การกระทำนี้ บางข้อดูง่าย บางข้อมีกับดัก
ลองจัดกลุ่ม
กดแล้ว ฐานข้อมูลทำอะไร?
01สมัครสมาชิกครั้งแรกด้วยเบอร์โทร
02เลื่อนดูเมนูเครื่องดื่มทั้งหมด
03เปลี่ยนที่อยู่จัดส่งเป็นที่ทำงานใหม่
04กดปุ่ม “สั่งแก้วเดิมอีกครั้ง”
05เปิดดูแต้มสะสมที่มีอยู่
06ขอลบบัญชีออกจากแอปของร้าน
เป้าหมาย: จัดกลุ่มให้ถูกครบทั้ง 6 สถานการณ์
โปรแกรมบนเซิร์ฟเวอร์สั่งงานฐานข้อมูลด้วยภาษาชื่อ ซึ่งเขียนคล้ายประโยคภาษาอังกฤษสั้น ๆ คุณไม่จำเป็นต้องจำไวยากรณ์ตอนนี้ แค่ดูว่าแต่ละคำสั่งตรงกับ CRUD ตัวไหน
-- Create: เพิ่มลูกค้าใหม่
INSERT INTO customers (name, city) VALUES ('วิไล ทองดี', 'ระยอง');
-- Read: อ่านลูกค้าที่อยู่เชียงใหม่
SELECT * FROM customers WHERE city = 'เชียงใหม่';
-- Update: ลูกค้าเลข 2 ย้ายบ้าน
UPDATE customers SET city = 'นนทบุรี' WHERE id = 2;
-- Delete: ลบคำสั่งซื้อเลข 104
DELETE FROM orders WHERE id = 104;หยุดคิดสักนิด
สังเกตคำว่า WHERE ในคำสั่ง UPDATE ถ้าลืมเขียนส่วนนี้ไป จะเกิดอะไรขึ้น?
ตอนที่ 5กุญแจสองดอกที่ทำให้ข้อมูลไม่สับสน
ร้านกาแฟของเราอาจมีลูกค้าชื่อ “สมชาย” สองคน คนหนึ่งอยู่เชียงใหม่ อีกคนอยู่ภูเก็ต ถ้าวันหนึ่งสมชายเชียงใหม่ขอเปลี่ยนเบอร์โทร เราจะแก้แถวไหน?
หยุดคิดสักนิด
จะแยกลูกค้าสองคนที่ชื่อเหมือนกันออกจากกันได้อย่างไร โดยไม่มีวันผิดตัว?
- Primary Keyกุญแจหลัก
- คอลัมน์ที่ค่าในแต่ละแถวไม่ซ้ำกันเลย ใช้ระบุตัวตนของแถวนั้นแบบไม่มีทางสับสน มักเป็นเลขที่ฐานข้อมูลออกให้เองโดยอัตโนมัติ เรียงขึ้นไปเรื่อย ๆ
ทีนี้ คำสั่งซื้อแต่ละรายการต้องรู้ว่าเป็นของใคร ทางหนึ่งคือพิมพ์ชื่อลูกค้าลงไปในทุกคำสั่งซื้อ แต่ถ้าวันหนึ่งลูกค้าเปลี่ยนนามสกุล เราต้องตามแก้เป็นร้อยแถว และถ้าแก้ไม่ครบ ข้อมูลก็จะขัดแย้งกันเอง วิธีที่ดีกว่าคือเก็บแค่ หมายเลขลูกค้า ไว้ในคำสั่งซื้อ แล้วให้หมายเลขนั้นชี้กลับไปหาลูกค้า
- Foreign Keyกุญแจเชื่อม
- คอลัมน์ในตารางหนึ่งที่เก็บ Primary Key ของอีกตาราง เพื่อบอกว่าแถวนี้เกี่ยวข้องกับแถวไหน เช่น คอลัมน์ customer_id ในตาราง orders เก็บ id ของลูกค้าเจ้าของคำสั่งซื้อ
ลองตามกุญแจดูเอง ด้านล่างคือตาราง orders สังเกตว่าไม่มีชื่อลูกค้าสักคนในตารางนี้ มีแค่ตัวเลขในคอลัมน์ customer_id ที่ชี้กลับไปหาตาราง customers ในภาพ 1.2
ถามตาราง
คำสั่งซื้อทั้งหมดของร้าน
← เลือกคำถามด้านบน
| id | customer_id | menu | price |
|---|---|---|---|
| 101 | 1 | ลาเต้เย็น | 60 |
| 102 | 2 | อเมริกาโน่ร้อน | 50 |
| 103 | 1 | มอคค่าเย็น | 65 |
| 104 | 3 | ชาเขียวเย็น | 55 |
| 105 | 5 | ลาเต้ร้อน | 55 |
| 106 | 1 | อเมริกาโน่เย็น | 55 |
แถวที่ตอบคำถามจะสว่างขึ้น แถวอื่นจางลง
เป้าหมาย: กดลองคำถามให้ครบทั้ง 3 ข้อ
ห้องทดลองเปิดลิ้นชักด้วยมือตัวเอง
ด้านล่างคือฐานข้อมูลจำลองของร้านกาแฟ มีสองลิ้นชักคือ customers กับ orders ทุกครั้งที่คุณทำอะไร คุณจะเห็นตารางเปลี่ยนจริง เห็นคำสั่ง SQL ที่โปรแกรมจริงจะส่ง และเห็นคำอธิบายว่าฐานข้อมูลคิดอย่างไร ลองทำภารกิจเหล่านี้ตามลำดับ
- สร้าง ลูกค้าใหม่หนึ่งคน แล้วสังเกตว่าเขาได้ id เลขอะไร ทั้งที่คุณไม่ได้กรอก
- สร้าง คำสั่งซื้อที่ customer_id เป็น
99ซึ่งไม่มีอยู่จริง แล้วอ่านว่าฐานข้อมูลตอบว่าอะไร - กดชื่อ สมชาย ใจดี ในตาราง แล้วดูว่าคำสั่งซื้อแถวไหนบ้างที่ชี้มาหาเขา
- ลบ สมชายโดยยังไม่ติ๊กช่อง CASCADE แล้วลองอีกครั้งโดยติ๊ก
- สร้างลูกค้าใหม่อีกคน แล้วดูว่าเลข id ของสมชายถูกนำกลับมาใช้หรือไม่
- ค้นหา คำว่า “เย็น” แล้วลองกดปุ่ม “ให้เบราว์เซอร์แก้ฐานข้อมูลเองตรง ๆ”
LAB 03 — Data Memory Vault
ลิ้นชักข้อมูล
SELECT *
FROM customers;เกิดอะไรขึ้น?
ลิ้นชัก · TABLE
customers ลูกค้า
| id (Primary Key) | name | city |
|---|---|---|
| 1 | เชียงใหม่ | |
| 2 | กรุงเทพฯ | |
| 3 | ขอนแก่น | |
| 4 | ภูเก็ต |
ลองดูกดชื่อลูกค้าในตารางบน เพื่อดูว่าคำสั่งซื้อแถวไหนในตารางล่างชี้กลับมาหาเขา
ลิ้นชัก · TABLE
orders คำสั่งซื้อ
| id (Primary Key) | customer_id (Foreign Key ชี้ไปที่ customers.id) | item | total ฿ |
|---|---|---|---|
| 101 | ลาเต้เย็น | 65 | |
| 102 | อเมริกาโน่ร้อน | 55 | |
| 103 | โกโก้ปั่น | 70 | |
| 104 | ชาไทยเย็น | 50 | |
| 105 | คาปูชิโน่ | 60 | |
| 106 | เอสเพรสโซ่ | 45 |
ใครมีสิทธิ์เขียนลงฐานข้อมูล?
เบราว์เซอร์ ปะทะ เซิร์ฟเวอร์
ลองแก้ราคาคำสั่งซื้อ #101 (ลาเต้เย็น 65 บาท) ด้วยสามเส้นทาง แล้วดูว่าคำขอถูกหยุดที่ไหน
ตอนที่ 6เกิดอะไรขึ้นในลิ้นชักเมื่อกี้
ถ้าคุณทำครบทุกภารกิจ คุณเพิ่งเห็นฐานข้อมูลทำงานสามอย่างที่คนส่วนใหญ่ไม่เคยรู้ว่ามันทำอยู่ทุกวินาที
หนึ่ง มันออกเลขประจำตัวให้เอง และไม่ยอมให้เลขซ้ำ ลูกค้าคนใหม่ได้เลขต่อจากเลขสูงสุดที่เคยออกไป ไม่ใช่เลขที่ว่างอยู่
สอง มันปกป้องความสัมพันธ์ คำสั่งซื้อของลูกค้าเลข 99 ถูกปฏิเสธ เพราะไม่มีใครเป็นเจ้าของ และการลบสมชายถูกหยุดไว้ เพราะคำสั่งซื้อสามรายการยังชี้มาหาเขาอยู่ การลบจะสำเร็จก็ต่อเมื่อคุณบอกชัด ๆ ว่าให้ลบคำสั่งซื้อเหล่านั้นไปด้วย
สาม มันไม่นำเลขเก่ากลับมาใช้ แม้สมชายจะถูกลบไปแล้ว เลข 1 ก็จะไม่ถูกมอบให้ใครอีก
หยุดคิดสักนิด
ทำไมฐานข้อมูลถึงไม่ยอมนำเลขของคนที่ถูกลบไปแล้วกลับมาใช้ใหม่ ทั้งที่เลขนั้นว่างอยู่?
ตอนที่ 7ทำไมฐานข้อมูลต้องซ่อนอยู่หลังเซิร์ฟเวอร์
ในห้องทดลอง คุณกดปุ่มแล้วตารางเปลี่ยนทันที อาจดูเหมือนเบราว์เซอร์แก้ฐานข้อมูลได้เอง แต่ในโลกจริง ห้ามเป็นแบบนั้นเด็ดขาด เบราว์เซอร์ไม่เคยคุยกับฐานข้อมูลโดยตรง มันส่งคำขอไปที่เซิร์ฟเวอร์ แล้วเซิร์ฟเวอร์เป็นคนตัดสินว่าจะยอมทำตามหรือไม่
ในห้องทดลอง ปุ่มสามปุ่มในกล่อง “เบราว์เซอร์ ปะทะ เซิร์ฟเวอร์” จำลองเส้นทางเหล่านี้ คำสั่ง SQL ดิบจากเบราว์เซอร์ถูกปฏิเสธทันที ลูกค้าที่ขอแก้ราคาผ่านเซิร์ฟเวอร์ถูกปฏิเสธเพราะไม่มีสิทธิ์ ส่วนพนักงานผ่านการตรวจ เซิร์ฟเวอร์จึงยอมส่งคำสั่งต่อไปให้ฐานข้อมูล ซึ่งก็ยังตรวจกฎของตัวเองซ้ำอีกชั้น
ส่วนห้องทดลองในบทนี้ทำงานในเบราว์เซอร์ได้ เพราะเป็น แบบจำลองเพื่อการเรียนรู้ ข้อมูลอยู่ในหน่วยความจำของคุณคนเดียว ไม่มีใครอื่นเห็น และหายไปเมื่อรีเฟรช ซึ่งก็คือบทเรียนแรกของบทนี้นั่นเอง
SYSTEM SUMMARY
สรุปบทนี้
- 01หน้าเว็บเก็บข้อมูลไว้ชั่วคราว รีเฟรชแล้วหาย ข้อมูลที่ต้องจำต้องถูกส่งไปเก็บในฐานข้อมูลบนเซิร์ฟเวอร์
- 02ฐานข้อมูลเก็บข้อมูลเป็นตาราง แถวคือข้อมูลหนึ่งชิ้น คอลัมน์คือคุณสมบัติที่ทุกแถวต้องมี และทุกคอลัมน์มีกฎกำกับ
- 03การกระทำกับข้อมูลมีสี่แบบ คือ Create, Read, Update, Delete (CRUD) และสั่งงานด้วยภาษา SQL
- 04Primary Key คือเลขประจำตัวที่ไม่ซ้ำของแต่ละแถว Foreign Key คือคอลัมน์ที่ชี้ไปหา Primary Key ของอีกตาราง
- 05ฐานข้อมูลปฏิเสธข้อมูลที่ผิดกฎ ชี้ไปหาสิ่งที่ไม่มี หรือจะทิ้งเด็กกำพร้าไว้
- 06เบราว์เซอร์ต้องไม่คุยกับฐานข้อมูลตรง ๆ ทุกคำขอต้องผ่านเซิร์ฟเวอร์ที่ตรวจตัวตน สิทธิ์ และข้อมูลก่อน
ท้ายบท
เช็กความเข้าใจ
ตอบแล้ว 0/4
ไม่มีคะแนนเก็บ ไม่มีใครเห็นคำตอบนอกจากคุณ ทุกตัวเลือกมีเหตุผลอธิบาย ทั้งข้อที่ถูกและข้อที่ผิด
ตอนนี้คุณรู้แล้วว่าเว็บไซต์จำเราได้ เพราะมีสมุดบันทึกที่เคร่งครัดซ่อนอยู่หลังเซิร์ฟเวอร์ ในบทถัดไป เราจะดูว่าตารางหลายใบจับมือกันอย่างไร เมื่อลูกค้าหนึ่งคนมีคำสั่งซื้อหลายรายการ และคำสั่งซื้อหนึ่งรายการมีหลายเมนู และจะถามคำถามข้ามตารางพร้อมกันได้อย่างไร
ก่อนไปต่อ ลองอธิบายด้วยคำพูดของคุณเอง ระบบไม่ได้อ่านหรือให้คะแนนคำตอบ แต่การได้เรียบเรียงเป็นประโยคของตัวเอง คือวิธีที่ดีที่สุดในการรู้ว่าเราเข้าใจจริงหรือยัง
อธิบายด้วยคำพูดของคุณเอง
ข้อความนี้อยู่แค่ในหน้าจอของคุณ ไม่ถูกส่งหรือบันทึกไว้ที่ไหน และระบบไม่ได้ให้คะแนน
เส้นทางการเรียนรู้
0/5
- ถามตาราง customers แล้วดูว่าแถวไหนตอบ (ยังไม่ได้ทำ)ภาพ 1.2: กดลองคำถามให้ครบทั้ง 4 ข้อ
- แยกการกระทำในแอปเป็น CRUD (ยังไม่ได้ทำ)ภาพ 1.3: จัดกลุ่มให้ถูกครบทั้ง 6 สถานการณ์
- ตามกุญแจเชื่อมจากคำสั่งซื้อไปหาเจ้าของ (ยังไม่ได้ทำ)ภาพ 1.4: กดลองคำถามให้ครบทั้ง 3 ข้อ
- ตอบแบบทดสอบท้ายบทครบทุกข้อ (ยังไม่ได้ทำ)ตอบครบทุกข้อ ผิดได้ ไม่มีผลกับการติ๊ก
- อธิบายด้วยคำพูดของตัวเอง (ยังไม่ได้ทำ)เขียนอย่างน้อย 30 ตัวอักษร แล้วกด 'เทียบกับคำอธิบายตัวอย่าง'
รายการนี้บันทึกสิ่งที่คุณได้ลงมือทำในเบราว์เซอร์นี้ ไม่ใช่ใบรับรองว่าเข้าใจแล้ว วิธีวัดที่ดีที่สุดคือลองอธิบายให้คนอื่นฟัง ล้างบันทึกได้ที่ Machine Lens แท็บ DATABASE