ทำความรู้จัก Relational Database พื้นฐานก่อนเริ่มเชื่อมข้อมูล
เวลาเราทำโปรเจกต์เขียนเว็บ ข้อมูลมักไม่ได้เก็บอยู่ในตารางเดียวเสมอไป เราจะใช้ Relational Database (ฐานข้อมูลแบบมีความสัมพันธ์) เพื่อแยกข้อมูลเป็นส่วนๆ ให้จัดการง่ายขึ้น การเชื่อมโยงข้อมูลหลายตารางด้วย JOIN (คำสั่งเอาข้อมูลจากหลายตารางมาแสดงผลรวมกัน) จึงเป็นทักษะที่โปรแกรมเมอร์ทุกคนต้องแม่น
ลองนึกภาพว่าเราทำระบบร้านค้าออนไลน์ เราจะมีตารางเก็บข้อมูลลูกค้า และตารางเก็บข้อมูลการสั่งซื้อแยกกัน ถ้าเราอยากรู้ว่าลูกค้าคนไหนซื้ออะไรบ้าง เราต้องเอาสองตารางนี้มา เชื่อมโยง (การจับคู่ข้อมูลที่มีค่าตรงกัน) เข้าด้วยกัน การทำแบบนี้ช่วยให้เราไม่ต้องเก็บข้อมูลซ้ำซ้อนและประหยัดพื้นที่เก็บข้อมูลได้มหาศาล
หัวใจสำคัญคือการมี Primary Key (คอลัมน์ที่เป็นรหัสประจำตัวไม่ซ้ำใคร) ในตารางหลัก และ Foreign Key (คอลัมน์ที่ใช้อ้างอิงไปยังรหัสของอีกตาราง) ในตารางลูก ทั้งสองตารางต้องมีข้อมูลที่สัมพันธ์กันเพื่อใช้เป็นจุดเชื่อม ถ้าเราไม่มีตัวเชื่อมที่ตรงกัน เราก็ไม่สามารถรวมข้อมูลให้เป็นภาพเดียวกันได้
INNER JOIN คือการดึงเฉพาะข้อมูลที่ตรงกันเท่านั้น
INNER JOIN คือวิธีการเชื่อมข้อมูลที่นิยมใช้มากที่สุด มันจะดึงเฉพาะแถวที่มีค่าในคอลัมน์เชื่อมกัน ตรงกันทั้งสองฝั่ง เท่านั้น ถ้าฝั่งใดฝั่งหนึ่งไม่มีข้อมูลที่จับคู่กันได้ ข้อมูลแถวนั้นจะถูกตัดทิ้งไปทันที เปรียบเหมือนการจัดงานปาร์ตี้ที่ต้องมีทั้ง "บัตรเชิญ" และ "ชื่อในรายชื่อแขก" ถึงจะเข้างานได้
สถานการณ์ที่เหมาะกับการใช้ INNER JOIN คือตอนที่เราต้องการข้อมูลที่สมบูรณ์เท่านั้น เช่น การดึงรายชื่อสินค้าที่มียอดขายแล้ว ถ้าสินค้าตัวไหนยังไม่มีคนซื้อ เราก็ไม่จำเป็นต้องนำมาแสดงในรายงานยอดขาย การเลือกใช้คำสั่งนี้จะช่วยให้เราได้ชุดข้อมูลที่สะอาดและเจาะจงตามเงื่อนไขที่เราตั้งไว้
จุดที่มือใหม่มักพลาดคือการลืมใส่เงื่อนไขในการเชื่อม หรือใส่ชื่อคอลัมน์เชื่อมผิด ทำให้ฐานข้อมูลดึงข้อมูลมาไม่ครบหรือแสดงผลผิดพลาดเสมอ การตรวจสอบชื่อคอลัมน์ให้ตรงกันก่อนเขียนคำสั่งเป็นนิสัยที่สำคัญมากสำหรับนักพัฒนา ถ้าเราไม่แน่ใจว่าคอลัมน์ไหนเชื่อมกันได้ ให้ลองเปิดดูโครงสร้างตารางก่อนเสมอ
-- ดึงข้อมูลชื่อลูกค้าและสินค้าที่สั่งซื้อ
SELECT customers.name, orders.product_name
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
ส่วนประกอบของคำสั่งนี้คือ SELECT เพื่อเลือกคอลัมน์ที่ต้องการ FROM เพื่อระบุตารางหลัก INNER JOIN เพื่อเชื่อมตารางที่สอง และ ON เพื่อบอกว่าคอลัมน์ไหนที่ใช้จับคู่กัน ผลลัพธ์ที่ได้จะเป็นตารางที่มีชื่อลูกค้าคู่กับสินค้าที่เขาสั่งซื้อเท่านั้น หากลูกค้าคนไหนยังไม่เคยสั่งซื้อเลย ชื่อของเขาจะไม่มีทางปรากฏในรายการนี้
LEFT JOIN รักษาข้อมูลตารางหลักไว้ครบถ้วน
LEFT JOIN แตกต่างจากตัวแรกตรงที่มันจะ ยึดตารางฝั่งซ้ายเป็นหลัก เสมอ ไม่ว่าข้อมูลฝั่งขวาจะมีคู่จับหรือไม่มีก็ตาม ถ้าฝั่งขวาไม่มีข้อมูลที่ตรงกัน ฐานข้อมูลจะเติมค่าเป็น NULL (ค่าว่างหรือไม่มีข้อมูล) ให้แทน เพื่อให้เรายังเห็นข้อมูลจากตารางหลักครบทุกแถว
ลองจินตนาการถึงการทำรายชื่อลูกค้าทั้งหมดในระบบ ไม่ว่าเขาจะเคยซื้อของหรือไม่ก็ตาม เราต้องใช้ LEFT JOIN เพื่อดึงข้อมูลลูกค้าทุกคนออกมา ถ้าใครยังไม่เคยสั่งซื้อ เราก็จะเห็นชื่อเขาพร้อมกับช่องว่างในส่วนของสินค้า นี่คือวิธีที่ใช้ตรวจสอบข้อมูลที่ขาดหายไปได้อย่างดีเยี่ยม
มือใหม่มักสับสนว่าควรใช้ตอนไหน ให้จำไว้ว่าถ้าอยากเห็นข้อมูลฝั่งซ้ายทั้งหมด ให้ใช้ LEFT JOIN เสมอ แม้ว่าข้อมูลนั้นจะไม่มีความสัมพันธ์กับตารางอื่นก็ตาม การเข้าใจธรรมชาติของคำสั่งนี้จะช่วยให้เราสร้างรายงานหรือฟีเจอร์ที่ครอบคลุมได้มากกว่าแค่การดูข้อมูลที่มีการเคลื่อนไหวแล้ว
-- ดึงรายชื่อลูกค้าทุกคน แม้จะยังไม่เคยสั่งซื้อของ
SELECT customers.name, orders.product_name
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id;
คำสั่งนี้ทำงานโดยดึง name จากตาราง customers ทั้งหมดออกมา หาก customer_id ในตาราง orders ไม่ตรงกับ id ของลูกค้าคนนั้น ผลลัพธ์ในคอลัมน์ product_name จะแสดงเป็น NULL ทำให้เราทราบทันทีว่าลูกค้าคนนี้ยังไม่มีการสั่งซื้อเกิดขึ้นในระบบ
ข้อควรระวังและเทคนิคการเขียนให้ทำงานได้เร็ว
การเขียน JOIN เยอะเกินไปในหนึ่งคำสั่งอาจทำให้ Query (คำสั่งที่ใช้ดึงข้อมูล) ทำงานช้าลงได้ โดยเฉพาะเมื่อตารางมีข้อมูลหลักล้านแถว เราควรเลือกดึงเฉพาะคอลัมน์ที่จำเป็นแทนการใช้ SELECT * (ดึงทุกคอลัมน์) เพื่อลดภาระของฐานข้อมูลและทำให้แอปพลิเคชันทำงานได้ลื่นไหล
อีกเรื่องที่สำคัญคือการทำ Index (ดัชนีหรือตัวช่วยค้นหาข้อมูล) บนคอลัมน์ที่นำมาใช้เชื่อมกัน การมี Index จะช่วยให้ฐานข้อมูลไม่ต้องไล่หาข้อมูลทีละแถว แต่สามารถกระโดดไปหาจุดที่ต้องการได้ทันทีเปรียบเหมือนการเปิดสารบัญท้ายเล่มหนังสือเพื่อไปหาหน้าเนื้อหาที่ต้องการแทนการเปิดอ่านตั้งแต่หน้าแรก
สุดท้ายคือการตั้งชื่อ Alias (ชื่อย่อของตาราง) ให้สั้นและสื่อความหมาย เช่น ใช้ c แทน customers หรือ o แทน orders จะช่วยให้โค้ดอ่านง่ายขึ้นมากและลดโอกาสพิมพ์ชื่อตารางยาวๆ ผิดพลาด นี่คือแนวปฏิบัติที่ดีที่โปรแกรมเมอร์มืออาชีพทุกคนทำกันเป็นปกติ
ความแตกต่างที่ต้องจำก่อนเลือกใช้งาน
ความแตกต่างหลักคือ INNER JOIN เน้นความสัมพันธ์ที่สมบูรณ์ ส่วน LEFT JOIN เน้นความครบถ้วนของข้อมูลฝั่งหลัก หากเราต้องการรายงานยอดขายแบบละเอียด การใช้ INNER JOIN จะให้ข้อมูลที่ถูกต้อง แต่ถ้าต้องการวิเคราะห์พฤติกรรมลูกค้าที่ยังไม่ซื้อสินค้า LEFT JOIN คือคำตอบ
ลองนึกภาพการทำระบบสมาชิก ถ้าเราใช้ INNER JOIN แล้วลูกค้าใหม่ที่เพิ่งสมัครแต่ยังไม่ได้สั่งซื้อหายไปจากรายการ มันจะทำให้ทีมการตลาดทำงานยากขึ้นมาก การเลือกใช้คำสั่งให้ถูกกับโจทย์จึงไม่ใช่แค่เรื่องของเทคนิค แต่เป็นเรื่องของการเข้าใจความต้องการทางธุรกิจของโปรเจกต์ที่เรากำลังทำอยู่
โปรแกรมเมอร์ที่เก่งไม่ได้วัดกันที่จำคำสั่งได้เยอะ แต่คือคนที่รู้ว่าเมื่อไหร่ควรใช้เครื่องมือไหนเพื่อแก้ปัญหาให้ตรงจุด หากไม่แน่ใจให้ลองเขียนคำสั่งแล้วรันดูผลลัพธ์จริงในเครื่องตัวเองก่อนเสมอ การทดลองด้วยข้อมูลจำลองเป็นวิธีเรียนรู้ที่เร็วที่สุดและไม่มีวันพัง เพราะถ้าผิดเราก็แค่แก้ไขและรันใหม่
สรุป: การนำไปใช้จริงในโปรเจกต์ของคุณ
ในการทำงานจริง คุณมักจะเจอสถานการณ์ที่ต้องรวมข้อมูลจาก 3-4 ตารางพร้อมกัน เช่น ดึงข้อมูล Order (รายการสั่งซื้อ) เชื่อมกับ Customer (ลูกค้า) และ Product (สินค้า) เพื่อทำใบเสร็จรับเงิน การเข้าใจพื้นฐาน INNER JOIN และ LEFT JOIN จะทำให้คุณเชื่อมข้อมูลเหล่านี้ได้อย่างมั่นใจ
หัวใจสำคัญคือการวางแผนโครงสร้างตารางให้ดีตั้งแต่วันแรก การเลือกใช้ Primary Key ให้ถูกต้องจะทำให้การทำ JOIN ง่ายขึ้นหลายเท่าตัว หากคุณกำลังฝึกทำโปรเจกต์แรก ลองสร้างตารางลูกค้าและตารางสินค้า แล้วฝึกทำ JOIN เพื่อดึงข้อมูลมาแสดงผลในหน้าเว็บด้วยตัวเอง
สุดท้ายนี้ อย่ากลัวที่จะทำผิดพลาดในการเขียนคำสั่ง Query เพราะแม้แต่โปรแกรมเมอร์อาวุโสก็ยังต้องเปิดเอกสารอ้างอิงอยู่บ่อยครั้ง สิ่งสำคัญคือการหมั่นฝึกฝนและทำความเข้าใจผลลัพธ์ที่ได้จากการรันโค้ดจริง แล้วคุณจะก้าวข้ามจากคนหัดเขียนโค้ดไปสู่มืออาชีพที่ใช้งานฐานข้อมูลได้อย่างคล่องแคล่วแน่นอน