หากคุณทำงานกับข้อมูลที่มีโครงสร้างไม่แน่นอน หรือต้องการความยืดหยุ่นสูง (Schemaless) คุณคงหนีไม่พ้นการใช้ข้อมูลรูปแบบ JSON ในระบบฐานข้อมูล โดยเฉพาะใน PostgreSQL ที่โดดเด่นมากเรื่องการจัดการข้อมูลประเภทนี้ ซึ่งมีการแบ่งออกเป็นสองประเภทหลักคือ JSON และ JSONB
JSON (Plain JSON)
JSON ในฐานข้อมูลแบบดั้งเดิมจะเก็บข้อมูลในรูปแบบ Text (ข้อความ) ตรง ๆ ตามที่คุณส่งเข้าไป
- การเก็บข้อมูล: เก็บแบบ “สำเนาถูกต้อง” คือส่งมายังไง เก็บไว้อย่างนั้น รวมถึงช่องว่าง (Whitespace) และลำดับของ Key
- ความเร็วในการบันทึก: เร็ว เพราะไม่ต้องประมวลผลอะไร แค่รับข้อความมาแล้วบันทึกลงดิสก์
- ความเร็วในการเรียกใช้: ช้า เพราะทุกครั้งที่ Query ระบบต้อง Parse (แปลง) ข้อความใหม่ทั้งหมดเพื่อหาข้อมูลข้างใน
JSONB (JSON Binary)
JSONB คือการนำข้อมูล JSON มาแปลงให้อยู่ในรูปแบบ Binary ก่อนจะบันทึกลงฐานข้อมูล
- การเก็บข้อมูล: ข้อมูลจะถูกถอดรหัสและจัดเรียงใหม่ (Hierarchy) โดยตัดช่องว่างที่เกินจำเป็นออก และไม่รับประกันลำดับของ Key
- ความเร็วในการบันทึก: ช้ากว่า เล็กน้อย เพราะต้องใช้เวลาในการแปลงข้อมูลเป็น Binary ก่อนเก็บ
- ความเร็วในการเรียกใช้: เร็วมาก เพราะข้อมูลถูกย่อยมาแล้ว ทำให้การค้นหาทำได้ทันที และที่สำคัญคือ รองรับการทำ Index (GIN Index) ซึ่งช่วยให้การค้นหาข้อมูลมหาศาลทำได้ในเสี้ยววินาที
ตารางเปรียบเทียบความแตกต่าง
| คุณสมบัติ | JSON | JSONB |
| รูปแบบการเก็บ | Text (ข้อความต้นฉบับ) | Binary (ประมวลผลแล้ว) |
| ความเร็วในการ Write | เร็ว | ช้ากว่า (มี Overhead) |
| ความเร็วในการ Read | ช้า | เร็วมาก |
| พื้นที่ที่ใช้ | น้อยกว่า (ถ้าไม่มีช่องว่างเยอะ) | มากกว่าเล็กน้อย |
| การทำ Indexing | ไม่รองรับ (ยกเว้น Functional Index) | รองรับ (GIN Index) |
| ลำดับของ Key | คงเดิมตามที่ส่งมา | ไม่คงเดิม |
ควรเลือกใช้ตัวไหนดี ?
กฎเหล็กส่วนใหญ่คือ: ใช้ JSONB เป็นหลัก
- เลือก JSONB เมื่อ:
- คุณต้องการประสิทธิภาพในการ Query สูง
- คุณต้องการค้นหาข้อมูลภายใน Object หรือ Array บ่อย ๆ
- คุณต้องการใช้ Index เพื่อเพิ่มความเร็ว
- เลือก JSON เมื่อ:
- คุณต้องการเก็บ Log ที่ต้องหน้าตาเหมือนต้นฉบับ 100% (รวมถึงลำดับ Key)
- คุณแค่เขียนข้อมูลลงไปเฉย ๆ โดยแทบจะไม่ได้ Query เจาะจงฟิลด์ข้างในเลย (Write-heavy, No-read)
ตัวอย่างการใช้งานเบื้องต้น (PostgreSQL)
การสร้าง Table ที่มีทั้งสองแบบ
CREATE TABLE users (id serial PRIMARY KEY, profile json, -- เก็บแบบ Text metadata jsonb -- เก็บแบบ Binary (แนะนำ)) ;
การ Query ข้อมูลภายใน
-- ค้นหา user ที่มีชื่อใน metadata เป็น 'Gemini' โดยใช้ JSONB
SELECT * FROM users WHERE metadata @> '{"name": "Gemini"}';
สรุป: แม้ JSONB จะใช้เวลาเขียนมากกว่านิดหน่อยและกินพื้นที่มากกว่าเล็กน้อย แต่ความสามารถในการทำ Indexing และความเร็วในการดึงข้อมูล ทำให้มันเป็นตัวเลือกที่เหนือกว่าเกือบทุกกรณีในโปรเจกต์สมัยใหม่ครับ
อ่านเพิ่มเติม