VIEW คืออะไรและทำไมต้องใช้
เวลาเราเขียนโปรแกรมดึงข้อมูลจากฐานข้อมูล บางครั้งคำสั่ง Query (คำสั่งถามข้อมูลจากฐานข้อมูล) ของเรามันยาวและซับซ้อนมาก ถ้าเราต้องเขียนคำสั่งเดิมซ้ำๆ ในหลายที่ของโปรแกรม มันจะทำให้โค้ดดูรกและจัดการยาก PostgreSQL VIEW (ตารางจำลอง) จึงเข้ามาช่วยแก้ปัญหานี้ โดยมันเปรียบเสมือนการบันทึกคำสั่งดึงข้อมูลไว้เป็นชื่อเฉพาะชื่อหนึ่ง
ลองจินตนาการว่าคุณทำงานในห้องสมุดที่มีหนังสือเป็นหมื่นเล่ม แทนที่คุณจะต้องเดินไปไล่ดูชั้นวางหนังสือเองทุกครั้ง คุณก็แค่ทำ "รายการหนังสือแนะนำ" แปะไว้ที่หน้าห้อง รายการนี้ไม่ใช่ตารางเก็บหนังสือจริงๆ แต่มันเป็นเพียงกระดาษที่บอกว่าข้อมูลชุดนี้อยู่ที่ไหนและต้องไปดึงมาอย่างไร การใช้ VIEW ก็เหมือนกัน มันเป็น Virtual Table (ตารางเสมือน) ที่ไม่ได้เก็บข้อมูลไว้จริงในเครื่อง แต่มันจะวิ่งไปดึงข้อมูลสดๆ จากตารางหลักทุกครั้งที่เราเรียกใช้
ประโยชน์ที่สำคัญที่สุดคือความสะดวกและการรักษาความปลอดภัย ถ้าเราต้องการให้คนในทีมเห็นแค่ชื่อและอีเมลลูกค้า แต่ไม่ต้องการให้เห็นรหัสผ่าน เราก็สร้าง VIEW ขึ้นมาเพื่อเลือกโชว์เฉพาะคอลัมน์ที่จำเป็นได้ วิธีนี้ช่วยลดความผิดพลาดในการเขียน Query ซ้ำซ้อนและทำให้โค้ดในโปรเจกต์ของคุณดูสะอาดตาขึ้นมากสำหรับมือใหม่ที่กำลังหัดเขียนโปรแกรม
-- สร้าง VIEW เพื่อดึงข้อมูลลูกค้าเฉพาะชื่อและอีเมล
CREATE VIEW customer_contact_info AS
SELECT name, email
FROM users;
-- เรียกใช้งาน VIEW เหมือนกับการดึงข้อมูลจากตารางปกติ
SELECT * FROM customer_contact_info;
บรรทัดที่ 2 คือการสร้าง VIEW โดยตั้งชื่อว่า customer_contact_info บรรทัดที่ 3-4 คือคำสั่งดึงข้อมูลที่เราบันทึกไว้ ส่วนบรรทัดที่ 7 คือการเรียกใช้ข้อมูลผ่านชื่อ VIEW แทนการเขียน Query ยาวๆ ผลลัพธ์ที่ได้คือตารางที่มีข้อมูลสองคอลัมน์คือ name และ email ของผู้ใช้ทุกคนในระบบ
วิธีสร้างและจัดการ VIEW เบื้องต้น
การสร้าง VIEW นั้นง่ายมากและใช้คำสั่ง SQL (ภาษาสำหรับจัดการฐานข้อมูล) พื้นฐานที่คุณคุ้นเคยอยู่แล้ว ขั้นตอนแรกคือการออกแบบ Query ที่ต้องการให้เสร็จสมบูรณ์ก่อน จากนั้นค่อยใช้คำสั่ง CREATE VIEW ครอบเอาไว้ สิ่งที่ต้องระวังคือคุณไม่ควรใส่ข้อมูลที่เปลี่ยนแปลงตลอดเวลาหรือคำสั่งที่กินทรัพยากรเครื่องสูงเกินไปใน VIEW เพราะมันจะทำงานทุกครั้งที่เรียกใช้งาน
หากวันหนึ่งโครงสร้างฐานข้อมูลเปลี่ยนไป หรือคุณต้องการเพิ่มเงื่อนไขการกรองข้อมูลใหม่ คุณไม่จำเป็นต้องลบแล้วสร้างใหม่เสมอไป คุณสามารถใช้คำสั่ง CREATE OR REPLACE VIEW เพื่อแก้ไขโครงสร้างเดิมได้ทันที นี่คือวิธีที่มืออาชีพใช้ในการพัฒนาซอฟต์แวร์เพื่อให้โปรแกรมทำงานได้อย่างต่อเนื่องโดยไม่ต้องหยุดระบบ (Down time)
ข้อควรจำสำหรับโปรแกรมเมอร์มือใหม่คือ VIEW จะไม่มีการเก็บข้อมูลจริง ดังนั้นถ้าตารางหลักมีการอัปเดตข้อมูล VIEW ก็จะเห็นข้อมูลใหม่ทันทีแบบ Real-time (ข้อมูลอัปเดตตามเวลาจริง) แต่มันก็แลกมาด้วยความเร็วที่เท่ากับการรัน Query ปกติ หากฐานข้อมูลคุณมีขนาดใหญ่มาก การเรียกใช้ VIEW อาจจะทำให้โปรแกรมตอบสนองช้าลงได้
- เขียนคำสั่ง SELECT ให้ได้ข้อมูลที่ต้องการตรวจสอบให้แน่ใจว่าผลลัพธ์ถูกต้อง
- ใช้คำสั่ง CREATE VIEW ตามด้วยชื่อ VIEW ที่สื่อความหมายเพื่อบันทึกคำสั่ง
- ทดสอบเรียกใช้ข้อมูลผ่าน SELECT * FROM [ชื่อ VIEW] เพื่อยืนยันว่าข้อมูลแสดงผลปกติ
ทำความรู้จักกับ Materialized View
เมื่อฐานข้อมูลของคุณเริ่มใหญ่ขึ้นจนถึงหลักล้าน Row (แถวข้อมูล) การใช้ VIEW ปกติจะเริ่มมีปัญหาเรื่องความเร็ว เพราะมันต้องคำนวณใหม่ทุกครั้งที่เรียก Materialized View (ตารางเสมือนที่เก็บผลลัพธ์ไว้) จึงถูกนำมาใช้เพื่อแก้ปัญหานี้ มันต่างจาก VIEW ปกติตรงที่มันจะ "บันทึกผลลัพธ์" ลงในดิสก์จริงๆ เหมือนกับตารางปกติหนึ่งใบ
ลองเปรียบเทียบว่า VIEW ปกติเหมือนการสั่งอาหารตามสั่งที่ต้องรอเชฟทำใหม่ทุกจาน ส่วน Materialized View เหมือนการทำอาหารใส่กล่องไว้ในตู้แช่ เมื่อลูกค้าสั่งคุณก็แค่หยิบออกมาอุ่นแล้วเสิร์ฟได้เลย วิธีนี้ทำให้การดึงข้อมูลที่ซับซ้อนและใช้เวลานานกลายเป็นเรื่องที่เร็วมากในระดับมิลลิวินาที
แต่การแลกมาด้วยความเร็วก็มีข้อเสีย คือข้อมูลใน Materialized View จะไม่เป็นปัจจุบันเสมอไป หากตารางหลักมีการแก้ไขหรือเพิ่มข้อมูล ตัว Materialized View จะยังคงเป็นข้อมูลเก่าจนกว่าคุณจะสั่ง Refresh (การสั่งอัปเดตข้อมูลใหม่) ให้มัน ดังนั้นมันจึงเหมาะกับงานประเภทรายงานสรุปยอดขายรายวัน หรือสถิติที่ไม่ได้ต้องการความสดใหม่แบบวินาทีต่อวินาที
-- สร้าง Materialized View สำหรับสรุปยอดขายรวม
CREATE MATERIALIZED VIEW monthly_sales_summary AS
SELECT product_id, SUM(amount) as total_sales
FROM orders
GROUP BY product_id;
บรรทัดที่ 2 คือคำสั่งสร้าง Materialized View บรรทัดที่ 3-5 คือการทำคำสั่งรวมกลุ่มข้อมูลยอดขายตามสินค้า ผลลัพธ์ที่ได้คือตารางใหม่ที่เก็บผลรวมไว้แล้ว เมื่อคุณรันคำสั่ง SELECT * FROM monthly_sales_summary ระบบจะแสดงผลลัพธ์ที่คำนวณเสร็จแล้วทันทีโดยไม่ต้องไปไล่รวมยอดจากตาราง orders อีกรอบ
การอัปเดตข้อมูลใน Materialized View
การทำให้ข้อมูลใน Materialized View เป็นปัจจุบันเรียกว่าการทำ Refresh ข้อมูล คุณต้องเขียนโปรแกรมหรือตั้งเวลาให้ระบบสั่ง REFRESH MATERIALIZED VIEW เป็นระยะๆ เช่น ทุก 1 ชั่วโมงหรือทุกเที่ยงคืน หากคุณเป็นมือใหม่ ให้เริ่มจากการทดลองสั่ง Refresh ด้วยตัวเองผ่าน Terminal (หน้าต่างพิมพ์คำสั่ง) ก่อนจะก้าวไปถึงการตั้งเวลาอัตโนมัติ
จุดที่มือใหม่มักพลาดคือการลืม Refresh ข้อมูล ทำให้ผู้ใช้งานเห็นตัวเลขที่คลาดเคลื่อนไปจากความเป็นจริง ดังนั้นการเลือกใช้ Materialized View ต้องพิจารณาว่าระบบของคุณรับได้ไหมหากข้อมูลจะ "เก่า" ไปสักพักหนึ่ง ถ้าเป็นแอปธนาคารที่ต้องการความถูกต้องแม่นยำสูงสุด ห้ามใช้สิ่งนี้กับส่วนที่เกี่ยวกับการโอนเงินเด็ดขาด
อีกเทคนิคหนึ่งคือการใช้ REFRESH MATERIALIZED VIEW CONCURRENTLY (การสั่งอัปเดตโดยไม่ล็อกตาราง) คำสั่งนี้จะช่วยให้ระบบยังคงอ่านข้อมูลจาก Materialized View ได้ตามปกติในระหว่างที่มันกำลังคำนวณข้อมูลใหม่ วิธีนี้ช่วยลดปัญหาการค้างของหน้าจอผู้ใช้งานในขณะที่ฐานข้อมูลกำลังทำงานหนักหลังบ้าน
-- สั่งอัปเดตข้อมูลใน Materialized View ใหม่
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales_summary;
บรรทัดที่ 2 คือคำสั่งสั่งให้ฐานข้อมูลไปอ่านค่าจากตารางหลักมาคำนวณใหม่และเขียนทับข้อมูลเดิม คำว่า CONCURRENTLY จะช่วยให้ผู้ใช้อื่นยังคงดึงข้อมูลเก่าได้ในระหว่างที่กระบวนการอัปเดตกำลังทำงาน ผลลัพธ์คือตารางนี้จะมีข้อมูลล่าสุดโดยที่ระบบไม่หยุดชะงัก
เปรียบเทียบชัดๆ เมื่อไหร่ควรใช้แบบไหน
การเลือกใช้ระหว่าง VIEW กับ Materialized View ขึ้นอยู่กับว่าคุณให้ความสำคัญกับอะไรมากกว่ากัน ระหว่าง "ความสดของข้อมูล" หรือ "ความเร็วในการดึงข้อมูล" หากคุณต้องการข้อมูลที่แม่นยำแบบวินาทีต่อวินาที เช่น ระบบจองตั๋วเครื่องบิน ให้เลือกใช้ VIEW ปกติเสมอ เพราะมันไม่มีทางที่ข้อมูลจะตกหล่น
ถ้าโปรเจกต์ของคุณเป็นระบบวิเคราะห์ข้อมูล (Dashboard) ที่มีการคำนวณสถิติซับซ้อนจากข้อมูลล้านแถว การใช้ VIEW ปกติจะทำให้หน้าเว็บหมุนติ้วอยู่นานมาก ในกรณีนี้ Materialized View คือผู้ช่วยชีวิต ที่จะทำให้หน้าเว็บของคุณโหลดเร็วขึ้นอย่างเห็นได้ชัดจนผู้ใช้งานประทับใจ
สรุปง่ายๆ สำหรับมือใหม่: เริ่มต้นด้วย VIEW ปกติก่อนเสมอเพราะมันดูแลง่ายและไม่มีปัญหาเรื่องข้อมูลเก่า เมื่อโปรเจกต์ของคุณเริ่มใหญ่ขึ้นและพบว่า Query เริ่มทำงานช้าเกินไปจนรับไม่ได้ ค่อยขยับมาใช้ Materialized View แล้วค่อยหาวิธีตั้งเวลาอัปเดตข้อมูลให้เหมาะสมกับความต้องการของธุรกิจ
- VIEW: เหมาะกับข้อมูลที่ต้องสดใหม่เสมอ หรือข้อมูลที่ไม่ซับซ้อนมาก
- Materialized View: เหมาะกับการคำนวณหนักๆ ข้อมูลล้านแถว ที่รับได้กับข้อมูลที่ล่าช้าบ้าง
- การเลือกใช้: ให้เริ่มจากความง่ายก่อน แล้วค่อยเพิ่มประสิทธิภาพเมื่อถึงเวลาที่จำเป็น
สรุป: การนำไปใช้จริงในโปรเจกต์แรกของคุณ
สมมติว่าคุณกำลังทำโปรเจกต์แอปพลิเคชันร้านค้าออนไลน์ สิ่งแรกที่ควรทำคือใช้ VIEW สร้างหน้าแสดงรายการสินค้าที่กรองเฉพาะสินค้าที่ยังมีสต็อกเหลืออยู่ วิธีนี้จะช่วยให้โค้ดฝั่ง Backend (ส่วนที่ทำงานหลังบ้าน) ของคุณดูสั้นลงและอ่านง่ายขึ้นมาก ไม่ต้องคอยเขียนเงื่อนไข WHERE status = 'active' ซ้ำๆ ในทุกที่ที่เรียกดูสินค้า
เมื่อร้านค้าของคุณมียอดขายมากขึ้นจนมีออเดอร์เป็นแสนรายการ และคุณต้องการทำหน้าสถิติสรุปยอดขายรายเดือนให้เจ้าของร้านดู นี่คือจังหวะที่คุณต้องใช้ Materialized View เข้ามาช่วย คุณอาจเขียนคำสั่ง Refresh ข้อมูลนี้ไว้ในตอนเช้ามืดของทุกวัน เพื่อให้เจ้าของร้านเปิดดูสถิติในตอนเช้าได้อย่างรวดเร็วโดยไม่ต้องรอระบบคำนวณใหม่ทุกครั้งที่กดดู
การเข้าใจเรื่องนี้จะทำให้คุณดูเป็นโปรแกรมเมอร์ที่มีความเข้าใจเรื่องประสิทธิภาพของระบบ (Performance) มากกว่าแค่คนเขียนโค้ดให้รันผ่าน จงฝึกใช้เครื่องมือเหล่านี้ตั้งแต่ตอนทำ Portfolio (แฟ้มสะสมงาน) ของคุณ แล้วคุณจะพบว่าการจัดการฐานข้อมูลขนาดใหญ่ไม่ใช่เรื่องน่ากลัวอีกต่อไป ขอให้สนุกกับการเขียนโค้ดและพัฒนาตัวเองต่อไปครับ