ทำความเข้าใจ NULL คืออะไรและทำไมต้องรู้
เวลาที่เราเขียนโปรแกรมจัดเก็บข้อมูลลงใน ฐานข้อมูล (แหล่งเก็บข้อมูลที่จัดระเบียบไว้ให้ค้นหาได้ง่าย) เรามักจะเจอสถานะหนึ่งที่เรียกว่า NULL ซึ่งมือใหม่หลายคนมักจะเข้าใจผิดว่ามันคือเลขศูนย์หรือค่าว่าง
ถ้าเปรียบเทียบให้เห็นภาพ NULL เหมือนกับ "ช่องที่ยังไม่ได้กรอกข้อมูล" ในแบบฟอร์มกระดาษ ส่วนเลขศูนย์หรือค่าว่างคือข้อมูลประเภทหนึ่งที่มีอยู่จริง เหมือนเราตั้งใจเขียนเลข 0 ลงไป หรือเว้นวรรคเอาไว้
การเข้าใจเรื่องนี้สำคัญมาก เพราะถ้าเราจัดการกับ NULL ไม่ถูกต้อง ตอนที่เราเขียน Query (คำสั่งดึงหรือจัดการข้อมูล) เพื่อนำข้อมูลไปใช้งาน โปรแกรมของเราอาจจะพังหรือแสดงผลลัพธ์ผิดพลาดได้ทันที
ความแตกต่างระหว่างค่าว่างและ NULL
หลายคนชอบสับสนระหว่าง NULL กับ ค่าว่าง (Empty String) ซึ่งในมุมของคอมพิวเตอร์มันต่างกันอย่างสิ้นเชิง NULL หมายถึง "ไม่มีค่า" หรือ "ไม่ทราบค่า" ในขณะที่ค่าว่างคือข้อมูลประเภทข้อความที่มีความยาวเท่ากับศูนย์
ลองนึกภาพว่าคุณกำลังทำระบบสมาชิก ถ้าช่องเบอร์โทรศัพท์เป็น NULL แปลว่าผู้ใช้ยังไม่ได้กรอกอะไรเลยหรือเรายังไม่รู้เบอร์เขา แต่ถ้าเป็นค่าว่าง แปลว่าผู้ใช้ตั้งใจกดปุ่มเว้นวรรคหรือไม่มีเบอร์โทรศัพท์จริงๆ
ถ้าเราเขียนโปรแกรมไปเช็คเงื่อนไขผิดวิธี เราอาจจะมองข้ามข้อมูลสำคัญไปได้เลย การแยกแยะสองอย่างนี้ให้ขาดเป็นทักษะพื้นฐานที่โปรแกรมเมอร์ทุกคนต้องแม่นยำก่อนเริ่มทำโปรเจกต์จริง
-- สร้างตารางทดสอบข้อมูล
CREATE TABLE users (
id INT,
name VARCHAR(50),
phone VARCHAR(20)
);
-- ใส่ข้อมูลที่มีค่าเป็น NULL และค่าว่าง
INSERT INTO users VALUES (1, 'Somchai', NULL);
INSERT INTO users VALUES (2, 'Somsak', '');
-- ดึงข้อมูลออกมาดู
SELECT * FROM users;
ในตัวอย่างนี้ เราสร้างตารางขึ้นมาแล้วใส่ข้อมูลสองแบบ คือ NULL ในแถวแรก และค่าว่าง '' ในแถวที่สอง
ผลลัพธ์ที่ควรเห็นคือแถวแรกในคอลัมน์ phone จะแสดงสถานะว่าเป็น NULL ส่วนแถวที่สองจะดูเหมือนช่องว่างเปล่าๆ แต่จริงๆ แล้วมันคือค่าว่างที่มีตัวตนอยู่ครับ
การกรองข้อมูลด้วย IS NULL และ IS NOT NULL
เวลาเราต้องการค้นหาข้อมูลที่ไม่มีค่า เราจะใช้เครื่องหมายเท่ากับ = แบบปกติไม่ได้ เพราะ NULL ไม่เท่ากับอะไรเลยแม้แต่ตัวมันเอง เราจึงต้องใช้คำสั่ง IS NULL แทน
ในทางกลับกัน ถ้าเราอยากได้ข้อมูลที่มีค่าจริงๆ เราต้องใช้ IS NOT NULL เพื่อคัดกรองเอาเฉพาะแถวที่มีข้อมูลถูกกรอกเข้ามาแล้วเท่านั้น วิธีนี้ช่วยให้เราดึงเฉพาะข้อมูลที่จำเป็นไปใช้ต่อได้
จุดที่มือใหม่พลาดบ่อยคือการเขียนว่า WHERE phone = NULL ซึ่งคำสั่งนี้จะรันผ่านแต่ไม่ให้ผลลัพธ์อะไรเลย เพราะคอมพิวเตอร์ไม่เข้าใจว่าค่าที่ไม่รู้จักจะเท่ากับค่าที่ไม่รู้จักได้อย่างไร
-- ค้นหาคนที่มีเบอร์โทรศัพท์เป็น NULL
SELECT * FROM users WHERE phone IS NULL;
-- ค้นหาคนที่มีเบอร์โทรศัพท์ (ไม่ใช่ NULL)
SELECT * FROM users WHERE phone IS NOT NULL;
บรรทัดแรกคือการสั่งให้ดึงข้อมูลเฉพาะแถวที่ช่อง phone ยังไม่มีการระบุค่าใดๆ ลงไปเลย
บรรทัดที่สองคือการสั่งให้ดึงข้อมูลที่ช่อง phone มีการกรอกข้อมูลเข้ามาแล้ว โดยผลลัพธ์จะแสดงเฉพาะรายชื่อที่มีเบอร์โทรศัพท์จริงๆ ออกมาให้เราเห็นครับ
การใช้ฟังก์ชัน IFNULL เพื่อจัดการค่าว่าง
บางครั้งเราไม่อยากให้หน้าจอแสดงคำว่า NULL ออกมาให้ผู้ใช้งานเห็น เพราะมันดูไม่เป็นมิตร เราจึงใช้ ฟังก์ชัน (ชุดคำสั่งสำเร็จรูป) ที่ชื่อว่า IFNULL() เข้ามาช่วย
หลักการทำงานของมันง่ายมาก คือถ้าข้อมูลเป็น NULL ให้แสดงค่าที่เรากำหนดแทน แต่ถ้าข้อมูลมีค่าอยู่แล้วก็ให้แสดงค่าเดิมออกมา วิธีนี้ช่วยให้โปรแกรมเราดูสมบูรณ์และใช้งานง่ายขึ้น
สมมติว่าคุณทำเว็บแสดงโปรไฟล์ผู้ใช้ ถ้าผู้ใช้ไม่ได้ใส่ชื่อเล่น คุณอาจจะใช้ IFNULL(nickname, 'ไม่มีชื่อเล่น') เพื่อให้แสดงคำว่าไม่มีชื่อเล่นแทนที่จะปล่อยให้เป็นช่องว่างเปล่าๆ
-- ถ้า phone เป็น NULL ให้แสดงว่า 'ไม่ได้ระบุ'
SELECT name, IFNULL(phone, 'ไม่ได้ระบุ') AS contact FROM users;
ในคำสั่งนี้เราเลือกคอลัมน์ name ออกมาคู่กับคอลัมน์ phone แต่เราครอบด้วย IFNULL ไว้
ผลลัพธ์ที่ได้คือ ถ้าคนไหน phone เป็น NULL มันจะเปลี่ยนไปโชว์คำว่า 'ไม่ได้ระบุ' แทน ทำให้รายงานข้อมูลดูสะอาดตาขึ้นมาก
การใช้ฟังก์ชัน COALESCE จัดการหลายค่า
นอกจาก IFNULL แล้วยังมีอีกฟังก์ชันที่ทรงพลังกว่าคือ COALESCE() ซึ่งช่วยให้เราตรวจสอบค่าได้หลายตัวพร้อมกัน โดยมันจะเลือกค่าแรกที่ "ไม่เป็น NULL" มาแสดงผลให้เราทันที
มันเหมาะมากสำหรับการทำระบบสำรองข้อมูล เช่น ถ้าเรามีเบอร์โทรศัพท์มือถือ เบอร์บ้าน และเบอร์ที่ทำงาน เราสามารถใช้ COALESCE เพื่อไล่เช็คว่ามีเบอร์ไหนที่ใช้งานได้บ้าง
ฟังก์ชันนี้ช่วยลดความซับซ้อนของโค้ดลงไปได้เยอะมาก แทนที่เราจะต้องเขียนเงื่อนไข IF ซ้อนกันหลายชั้น เราสามารถยุบรวมมาเขียนในบรรทัดเดียวได้เลย
-- เลือกเบอร์ที่ใช้งานได้เบอร์แรกที่เจอ
SELECT COALESCE(mobile, home_phone, work_phone, 'ไม่มีเบอร์ติดต่อ') AS contact FROM users;
บรรทัดนี้คือการสั่งให้ฐานข้อมูลไล่เช็คจาก mobile ไปจนถึง work_phone ตามลำดับ
ผลลัพธ์ที่ได้คือ ระบบจะหยิบเบอร์แรกที่หาเจอมาโชว์ ถ้าทุกช่องเป็น NULL หมด มันก็จะแสดงคำว่า 'ไม่มีเบอร์ติดต่อ' ตามที่เรากำหนดไว้ตอนท้ายครับ
สรุปการนำไปใช้จริงในงานเขียนโปรแกรม
การจัดการกับ NULL เป็นเรื่องที่โปรแกรมเมอร์มืออาชีพต้องให้ความสำคัญ เพราะข้อมูลในโลกจริงมักจะไม่สมบูรณ์เสมอไป การวางแผนรับมือตั้งแต่ขั้นตอนการออกแบบฐานข้อมูลจะช่วยลดบั๊ก (ข้อผิดพลาดของโปรแกรม) ได้มหาศาล
ลองนึกภาพตอนคุณกำลังเขียนระบบสมัครสมาชิก ถ้าคุณเผลอให้ค่า NULL ไปคำนวณเงินหรือแสดงผลโดยไม่ตรวจสอบก่อน โปรแกรมอาจจะแจ้งเตือนว่าเกิดข้อผิดพลาดและปิดตัวลงกลางคัน ซึ่งสร้างประสบการณ์ที่แย่ให้กับผู้ใช้งาน
จงฝึกใช้ IS NULL และฟังก์ชันจัดการค่าอย่าง COALESCE ให้เป็นนิสัย เพราะเมื่อคุณต้องทำงานกับข้อมูลจำนวนมากหรือทำระบบที่ซับซ้อนขึ้น ทักษะการจัดการสถานะข้อมูลเหล่านี้จะกลายเป็นอาวุธสำคัญที่ทำให้โค้ดของคุณมีความเสถียรและน่าเชื่อถือมากขึ้นครับ