🔵 PostgreSQL

เจาะลึก PostgreSQL JSONB: เก็บข้อมูล NoSQL และเทคนิคการ Query ข้อมูลให้ไว

9 นาที 17 views บันทึกเป็น PDF
เจาะลึก PostgreSQL JSONB: เก็บข้อมูล NoSQL และเทคนิคการ Query ข้อมูลให้ไว

อยากเก็บข้อมูลยืดหยุ่นในฐานข้อมูลใช่ไหม? มาเรียนรู้การใช้ JSONB ใน PostgreSQL เพื่อเก็บข้อมูลแบบ NoSQL พร้อมวิธีใช้ Operator (->, ->>, @>) ดึงข้อมูลและค้นหาให้เร็วทันใจ

ทำความรู้จัก JSONB ใน PostgreSQL

เวลาเราเก็บข้อมูลในฐานข้อมูลปกติ เรามักจะแบ่งเป็นคอลัมน์ชัดเจน เช่น ชื่อ นามสกุล หรืออายุ แต่บางครั้งข้อมูลที่เราต้องเก็บมันเปลี่ยนไปมาตลอดเวลา เช่น รายละเอียดสินค้าที่บางชิ้นมีสี บางชิ้นมีขนาด หรือบางชิ้นมีวัสดุต่างกัน การสร้างคอลัมน์แยกทุกอย่างจะทำให้ตารางดูรกและจัดการยาก PostgreSQL JSONB (รูปแบบการเก็บข้อมูลแบบ JSON ที่ประมวลผลได้รวดเร็ว) จึงเข้ามาแก้ปัญหานี้

ลองนึกภาพว่าเรามีกล่องเก็บของแบบช่องเล็กๆ กับกล่องเก็บของแบบอเนกประสงค์ JSONB เปรียบเสมือนกล่องอเนกประสงค์ที่เราโยนของลงไปได้ทุกอย่างโดยไม่ต้องจัดระเบียบเป๊ะๆ ตั้งแต่แรก ข้อมูลประเภทนี้เรียกว่า NoSQL (การเก็บข้อมูลที่ไม่ต้องมีโครงสร้างตายตัวเหมือนตารางปกติ) ซึ่งยืดหยุ่นมากสำหรับโปรเจกต์ที่ยังไม่รู้ว่าอนาคตจะเก็บอะไรเพิ่มบ้าง

เหตุผลที่มือใหม่ควรใช้ JSONB ไม่ใช่แค่เพราะความยืดหยุ่น แต่เป็นเพราะมันเก็บข้อมูลในรูปแบบที่คอมพิวเตอร์อ่านง่ายและเร็ว ต่างจาก JSON แบบธรรมดาที่เก็บเป็นข้อความดิบๆ JSONB จะถูกแปลงเป็นรูปแบบไบนารี (ข้อมูลเลขฐานสอง) ก่อนเก็บ ทำให้ตอนเราจะค้นหาข้อมูลข้างใน มันทำได้ไวมากจนแทบไม่ต่างจากการ Query (คำสั่งถามข้อมูลจากฐานข้อมูล) ข้อมูลในคอลัมน์ปกติเลย

เตรียมตารางสำหรับเก็บข้อมูล JSONB

การใช้งานจริงเริ่มจากการสร้างตารางที่รองรับข้อมูลแบบ JSONB การประกาศชนิดข้อมูลให้เป็น jsonb ทำได้เหมือนกับการประกาศ text หรือ int (เลขจำนวนเต็ม) ปกติเลย ข้อดีคือเราสามารถผสมผสานการเก็บข้อมูลแบบตารางทั่วไป กับข้อมูลที่ยืดหยุ่นไว้ในตารางเดียวกันได้

ขั้นตอนการสร้างตารางมีดังนี้:

  1. สร้างตารางด้วยคำสั่ง CREATE TABLE (คำสั่งสร้างตารางใหม่)
  2. กำหนดคอลัมน์ชื่อ data ให้เป็นประเภท jsonb
  3. เพิ่มข้อมูลเข้าไปด้วยคำสั่ง INSERT (คำสั่งเพิ่มข้อมูลใหม่)
-- สร้างตารางเก็บข้อมูลสินค้า
CREATE TABLE products (
    id serial PRIMARY KEY,
    name text,
    attributes jsonb
);

-- เพิ่มข้อมูลสินค้าลงไป
INSERT INTO products (name, attributes) 
VALUES ('Laptop', '{"color": "silver", "ram": "16GB", "cpu": "i7"}');

บรรทัดแรกเป็นการสร้างตารางชื่อ products โดยมี id เป็นตัวระบุข้อมูลไม่ซ้ำกัน คอลัมน์ attributes ถูกกำหนดให้เป็น jsonb เพื่อเก็บรายละเอียดที่ไม่ตายตัว บรรทัดสุดท้ายเป็นการเพิ่มข้อมูลโดยใส่ข้อมูลแบบ JSON เข้าไปในคอลัมน์ attributes ได้เลย

ผลลัพธ์ที่ควรเห็นคือข้อความแจ้งเตือน INSERT 0 1 ซึ่งแปลว่าระบบเพิ่มข้อมูลลงไปเรียบร้อยแล้ว 1 แถว ถ้าเราลองใช้คำสั่ง SELECT * FROM products; เราจะเห็นข้อมูลที่เก็บอยู่ในรูปแบบ JSON ครบถ้วนตามที่เราใส่เข้าไป

การดึงข้อมูลภายในด้วย Operator

เมื่อเราเก็บข้อมูลเข้าไปแล้ว สิ่งที่ต้องทำต่อคือการดึงเฉพาะส่วนที่ต้องการออกมา PostgreSQL มี Operator (สัญลักษณ์พิเศษที่ใช้สั่งงาน) ที่ทรงพลังมากในการเจาะเข้าไปใน JSONB เพื่อหาค่าที่ซ่อนอยู่ข้างใน ทำให้เราไม่ต้องดึงข้อมูลทั้งก้อนออกมาประมวลผลข้างนอก

ตัวแรกคือ -> ซึ่งใช้ดึงค่าออกมาเป็นประเภท JSON เช่น ถ้าเราอยากได้ข้อมูล color จากสินค้า เราก็แค่ระบุชื่อคอลัมน์ตามด้วยสัญลักษณ์นี้ อีกตัวคือ ->> ซึ่งคล้ายกันแต่จะดึงออกมาเป็นข้อความธรรมดา (Text) ซึ่งมักจะใช้ง่ายกว่าในการเขียนโปรแกรมต่อ

การเข้าใจความต่างของสองตัวนี้สำคัญมาก เพราะถ้าเราดึงออกมาเป็น JSON มันจะยังติดเครื่องหมายคำพูดหรือโครงสร้างอยู่ แต่ถ้าดึงเป็น Text เราจะได้ค่าข้างในออกมาใช้งานได้ทันที เช่น เอาไปเปรียบเทียบในเงื่อนไข WHERE (เงื่อนไขกรองข้อมูล) ของเรา

-- ดึงค่าสีออกมาเป็นข้อความ
SELECT attributes->>'color' FROM products WHERE name = 'Laptop';

คำสั่งนี้ใช้ ->> เพื่อดึงค่าของ color ออกมาโดยเฉพาะจากคอลัมน์ attributes โดยเลือกเฉพาะแถวที่ name เป็น Laptop เท่านั้น สัญลักษณ์ ->> จะทำให้ผลลัพธ์ที่ได้ออกมาเป็นข้อความ silver ตรงๆ

ผลลัพธ์ที่ควรเห็นคือ silver แสดงขึ้นมาบนหน้าจอ ถ้าใช้ -> แทน ผลลัพธ์จะออกมาเป็น "silver" ซึ่งมีเครื่องหมายคำพูดติดมาด้วย มือใหม่มักพลาดตรงนี้จนทำให้เอาไปเปรียบเทียบเงื่อนไขต่อไม่ได้

ค้นหาข้อมูลแบบเจาะลึกด้วย @>

ถ้าเราอยากหาว่า สินค้าตัวไหนบ้างที่มี ram เป็น 16GB เราไม่จำเป็นต้องเขียนโค้ดซับซ้อน เราสามารถใช้ Operator พิเศษที่ชื่อว่า @> (Containment Operator) ซึ่งหมายถึง "ประกอบด้วย" ได้ทันที มันช่วยให้เราค้นหาจากข้อมูลที่ซ้อนอยู่ข้างในได้แม่นยำและรวดเร็ว

การใช้ @> คือการถามฐานข้อมูลว่า "มีโครงสร้าง JSON นี้อยู่ข้างในใช่ไหม" วิธีนี้มีประสิทธิภาพสูงกว่าการดึงข้อมูลออกมาตรวจสอบทีละบรรทัดด้วยโปรแกรม เพราะตัวฐานข้อมูลเองจะจัดการค้นหาให้ตั้งแต่วินาทีที่ Query เข้าไปถึง

ข้อควรระวังคือเรื่องรูปแบบของ JSON ที่เราใช้ค้นหา ต้องเขียนให้ถูกต้องตามมาตรฐาน JSON ทุกประการ เช่น ต้องใช้เครื่องหมายคำพูดคู่เท่านั้น ห้ามใช้เครื่องหมายคำพูดเดี่ยวเด็ดขาด เพราะถ้าพลาดแม้แต่นิดเดียว ฐานข้อมูลจะแจ้งเตือนว่าคำสั่งผิดพลาดทันที

-- ค้นหาสินค้าที่มี ram เป็น 16GB
SELECT name FROM products WHERE attributes @> '{"ram": "16GB"}';

คำสั่งนี้เป็นการกรองแถวข้อมูลในตาราง products โดยดูว่าคอลัมน์ attributes มีส่วนประกอบของ {"ram": "16GB"} อยู่หรือไม่ ถ้าเจอข้อมูลไหนที่มีคีย์ ram และค่าเป็น 16GB มันจะส่งชื่อสินค้าตัวนั้นกลับมาให้เรา

ผลลัพธ์ที่ควรเห็นคือชื่อ Laptop ปรากฏขึ้นมา หากไม่มีสินค้าตัวไหนตรงกับเงื่อนไข ผลลัพธ์จะเป็นช่องว่างเปล่าๆ ซึ่งหมายความว่าไม่มีข้อมูลที่ตรงตามเงื่อนไขที่เรากำหนด

เพิ่มความเร็วด้วย GIN Index

เมื่อข้อมูลในตารางเริ่มมีเยอะขึ้น การค้นหาข้อมูลภายใน JSONB อาจจะเริ่มช้าลง PostgreSQL จึงมีฟีเจอร์ Index (ตัวช่วยดัชนีเหมือนสารบัญหนังสือ) ที่ออกแบบมาเพื่อ JSONB โดยเฉพาะ เรียกว่า GIN Index (Generalized Inverted Index) ซึ่งจะช่วยให้การค้นหาเร็วขึ้นมหาศาล

คิดซะว่าข้อมูลในตารางคือหนังสือเล่มหนา ถ้าเราไม่มีสารบัญ เราต้องเปิดอ่านทุกหน้าเพื่อหาคำที่ต้องการ แต่ถ้าเราทำ GIN Index ก็เหมือนเราสร้างสารบัญท้ายเล่มที่บันทึกไว้ว่าคำนี้อยู่หน้าไหนบ้าง ทำให้เรากระโดดไปเจอข้อมูลได้ทันทีโดยไม่ต้องไล่อ่านทีละบรรทัด

การสร้าง GIN Index ควรทำเฉพาะตอนที่ข้อมูลเริ่มเยอะขึ้นแล้วจริงๆ เพราะการทำ Index จะกินพื้นที่หน่วยความจำและทำให้การเพิ่มข้อมูลใหม่ช้าลงเล็กน้อย เนื่องจากฐานข้อมูลต้องคอยอัปเดตสารบัญทุกครั้งที่มีการเปลี่ยนข้อมูล แต่สำหรับโปรเจกต์ทั่วไปที่เน้นอ่านข้อมูลมากกว่าเขียน นี่คือสิ่งที่คุ้มค่ามาก

-- สร้างดัชนีช่วยค้นหาให้เร็วขึ้น
CREATE INDEX idx_products_attributes ON products USING GIN (attributes);

บรรทัดนี้คือการสั่งให้สร้าง Index ชื่อ idx_products_attributes บนตาราง products โดยบอกให้ใช้เทคนิค GIN กับคอลัมน์ attributes เพื่อให้การค้นหาด้วย @> เร็วขึ้นอย่างเห็นได้ชัดในข้อมูลระดับหลักหมื่นหรือหลักแสนแถว

ผลลัพธ์ที่ควรเห็นคือ CREATE INDEX แสดงว่าระบบสร้างดัชนีเสร็จแล้ว หลังจากนี้การทำ SELECT ด้วยเงื่อนไข WHERE attributes @> '...' จะทำงานไวขึ้นมากโดยที่เราไม่ต้องเปลี่ยนโค้ดส่วนอื่นเลย

สรุป: การนำไปใช้จริงในงานโปรแกรมเมอร์

การใช้ JSONB ไม่ได้แปลว่าเราต้องทิ้งฐานข้อมูลแบบตารางไปเลย แต่เป็นการเพิ่มอาวุธในมือให้เราเลือกใช้ได้เหมาะสมกับงานมากขึ้น ตัวอย่างเช่น การทำระบบ User Profile (ข้อมูลส่วนตัวของผู้ใช้) ที่บางคนอาจจะมีแค่ชื่อกับอีเมล แต่บางคนอาจจะมีช่องทางโซเชียลมีเดียหลายช่องทางที่ไม่เหมือนกัน

มือใหม่ที่กำลังฝึกทำโปรเจกต์ พอร์ตโฟลิโอ ควรเริ่มจากการเก็บข้อมูลปกติก่อน แล้วลองเปลี่ยนข้อมูลที่เปลี่ยนบ่อยหรือมีโครงสร้างไม่แน่นอนมาเก็บใน JSONB คุณจะพบว่ามันช่วยลดเวลาการแก้โครงสร้างตาราง (Migration) ไปได้เยอะมาก ทำให้คุณมีเวลาไปโฟกัสกับการเขียนฟีเจอร์ให้ผู้ใช้ได้ใช้งานจริง

จดจำไว้ว่าเครื่องมือที่ดีที่สุดคือเครื่องมือที่แก้ปัญหาได้ตรงจุด ถ้าข้อมูลของคุณมีความสัมพันธ์ชัดเจนและคงที่ การเก็บในคอลัมน์ปกติยังคงเป็นทางเลือกที่ดีที่สุด แต่ถ้างานของคุณต้องการความยืดหยุ่นสูง JSONB คือเพื่อนแท้ที่จะช่วยให้คุณทำงานได้ไวและมีประสิทธิภาพมากขึ้นในฐานะโปรแกรมเมอร์มืออาชีพ

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

จัดการ PostgreSQL เบื้องต้น: การคุมสิทธิ์ User, การ Backup และ Restore ข้อมูลบน Windows
PostgreSQL

จัดการ PostgreSQL เบื้องต้น: การคุมสิทธิ์ User, การ Backup และ Restore ข้อมูลบน Windows

มือใหม่ต้องรู้! วิธีจัดการสิทธิ์ผู้ใช้งาน (Role) และการสำรองข้อมูล (Backup) ใน PostgreSQL ให้ปลอดภัย พร้อมวิธี Restore ข้อมูลกลับมาใช้ได้จริงผ่าน Command Line

4 weeks ago 8 นาที
26 views
เจาะลึก PostgreSQL Triggers: วิธีเขียนคำสั่งทำงานอัตโนมัติเมื่อข้อมูลเปลี่ยน
PostgreSQL

เจาะลึก PostgreSQL Triggers: วิธีเขียนคำสั่งทำงานอัตโนมัติเมื่อข้อมูลเปลี่ยน

อยากให้ฐานข้อมูลทำงานอัตโนมัติเมื่อมีการเพิ่มหรือแก้ไขข้อมูลไหม? มาเรียนรู้การใช้ PostgreSQL Triggers (ตัวสั่งการอัตโนมัติ) ทั้ง BEFORE และ AFTER เพื่อลดงานซ้ำซ้อน

4 weeks ago 8 นาที
20 views
เจาะลึก PostgreSQL PL/pgSQL: เขียนฟังก์ชันและ Stored Procedures ฉบับมือใหม่
PostgreSQL

เจาะลึก PostgreSQL PL/pgSQL: เขียนฟังก์ชันและ Stored Procedures ฉบับมือใหม่

เรียนรู้วิธีเขียนโปรแกรมในฐานข้อมูลด้วย PL/pgSQL ทั้งการสร้างฟังก์ชัน การใช้ตัวแปร และการทำ Loop เพื่อให้งานจัดการข้อมูลของคุณเร็วและเป็นระเบียบยิ่งขึ้น

4 weeks ago 8 นาที
19 views