- 26
- มีนาคม
ถ้าคุณเคยทำงานกับ API, ระบบ ERP หรือแม้แต่ตั้งค่า Config ต่างๆ คุณน่าจะเคยเห็น JSON มาบ้างแล้ว แต่เมื่อเริ่มใช้ PostgreSQL จะพบว่ามี Data Type อยู่ 2 ตัวที่ชื่อคล้ายกันมาก คือ JSON กับ JSONB — บทความนี้จะอธิบายให้เข้าใจง่ายว่าทั้งสองคืออะไร ต่างกันอย่างไร ใช้ตัวไหนดี และ PostgreSQL รองรับตั้งแต่เวอร์ชันไหน
JSON คืออะไร?
JSON (JavaScript Object Notation) คือรูปแบบการจัดเก็บและแลกเปลี่ยนข้อมูลที่เป็นข้อความ (Text-based) อ่านง่ายทั้งคนและเครื่อง ถูกออกแบบมาให้เป็น "ภาษากลาง" ในการส่งข้อมูลระหว่างระบบต่างๆ
ตัวอย่าง JSON
{
"employee_id": "EMP-001",
"name": "สมชาย ใจดี",
"department": "บัญชี",
"skills": ["Excel", "SAP", "ERP"],
"active": true
}
JSON ใช้โครงสร้าง Key-Value Pair (คู่ชื่อ-ค่า) ที่ซ้อนกันได้หลายระดับ รองรับ Data Type พื้นฐาน 6 ชนิด:
| Data Type | ตัวอย่าง | อธิบาย |
|---|---|---|
| String | "สมชาย" |
ข้อความ ใส่ในเครื่องหมายคำพูดคู่ |
| Number | 42, 3.14 |
ตัวเลข (จำนวนเต็มหรือทศนิยม) |
| Boolean | true, false |
ค่าจริง/เท็จ |
| Array | ["a", "b", "c"] |
ลิสต์ข้อมูลหลายค่า |
| Object | {"key": "value"} |
ข้อมูลซ้อนกัน (Nested) |
| Null | null |
ไม่มีค่า |
JSONB คืออะไร?
JSONB (JSON Binary) คือรูปแบบการเก็บข้อมูล JSON ที่ถูกแปลงเป็น Binary Format ก่อนบันทึกลงฐานข้อมูล — ผลลัพธ์คือข้อมูลเดียวกันกับ JSON แต่เก็บในรูปแบบที่ ค้นหาและประมวลผลได้เร็วกว่ามาก
เปรียบเทียบง่ายๆ: JSON เหมือนเก็บเอกสารเป็น "กระดาษข้อความ" — อ่านได้ แต่ค้นหาช้า ส่วน JSONB เหมือนเก็บเอกสารใน "ระบบจัดเก็บดิจิทัล" ที่มี Index — ค้นหาเจอทันที
JSON กับ JSONB ต่างกันอย่างไร?
นี่คือตารางเปรียบเทียบที่สำคัญที่สุด:
| คุณสมบัติ | JSON | JSONB |
|---|---|---|
| วิธีเก็บข้อมูล | เก็บเป็น Text ตามที่ใส่มา | แปลงเป็น Binary ก่อนเก็บ |
| ความเร็วในการเขียน | เร็วกว่า (ไม่ต้องแปลง) | ช้ากว่าเล็กน้อย (ต้อง Parse) |
| ความเร็วในการอ่าน/ค้นหา | ช้า (ต้อง Parse ทุกครั้ง) | เร็วมาก (เข้าถึง Key ได้ตรง) |
| รองรับ Index | ไม่รองรับ | รองรับ GIN Index |
| รักษาลำดับ Key | เก็บตามลำดับที่ใส่ | ไม่รักษาลำดับ (จัดเรียงใหม่) |
| Key ซ้ำ (Duplicate Keys) | เก็บได้ทั้งหมด | เก็บเฉพาะค่าสุดท้าย |
| ช่องว่าง (Whitespace) | เก็บตามที่ใส่มา | ลบช่องว่างที่ไม่จำเป็นออก |
| พื้นที่จัดเก็บ | ตามขนาดข้อความ | อาจใหญ่กว่าเล็กน้อย (มี Metadata) |
| Operator พิเศษ | จำกัด | มีครบ (@>, ?, ?|, ?&) |
ใช้ JSON และ JSONB ทำอะไรได้บ้าง?
ในระบบ Saeree ERP และระบบสารสนเทศขององค์กรทั่วไป JSON/JSONB ถูกใช้ในหลายจุด:
| Use Case | ตัวอย่างการใช้งาน | แนะนำ |
|---|---|---|
| เก็บ Config/Setting | ตั้งค่า Workflow อนุมัติ, สิทธิ์ผู้ใช้, รูปแบบรายงาน | JSONB |
| เก็บ API Response | ข้อมูลจาก GFMIS, ระบบภาษี, ธนาคาร | JSONB |
| Audit Log | บันทึกข้อมูลก่อน-หลังแก้ไข (Before/After) | JSONB |
| Custom Fields | ฟิลด์เพิ่มเติมที่แต่ละองค์กรกำหนดเอง | JSONB |
| เก็บ Log ดิบ (Raw Log) | เก็บข้อมูลดิบที่ต้องรักษารูปแบบเดิม | JSON |
กฎง่ายๆ: ถ้าต้องค้นหา, กรอง, หรือ Query ข้อมูลข้างใน → ใช้ JSONB เสมอ | ถ้าแค่เก็บแล้วอ่านทั้งก้อนออกมา → ใช้ JSON ก็พอ
ตัวอย่าง SQL จริงบน PostgreSQL
1. สร้างตารางที่มีคอลัมน์ JSONB
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
profile JSONB
);
-- ใส่ข้อมูล
INSERT INTO employees (name, profile) VALUES
('สมชาย ใจดี', '{
"department": "บัญชี",
"position": "นักบัญชี",
"skills": ["Excel", "SAP", "ERP"],
"salary": 35000,
"active": true
}'),
('สมหญิง รักงาน', '{
"department": "พัสดุ",
"position": "เจ้าหน้าที่พัสดุ",
"skills": ["Inventory", "ERP"],
"salary": 30000,
"active": true
}');
2. ดึงค่าจาก JSONB
-- ดึงชื่อแผนก (ได้ JSON value)
SELECT name, profile->'department' AS dept
FROM employees;
-- ดึงชื่อแผนกเป็น Text (ไม่มีเครื่องหมายคำพูด)
SELECT name, profile->>'department' AS dept
FROM employees;
Operator สำคัญ:
->ดึงค่าเป็น JSON (ใช้ต่อ chain ได้)->>ดึงค่าเป็น Text#>ดึงค่าจาก Path เป็น JSON#>>ดึงค่าจาก Path เป็น Text@>ตรวจว่า JSONB มี Key-Value ตรงกันไหม (Contains)?ตรวจว่า JSONB มี Key นี้ไหม
3. ค้นหาข้อมูลใน JSONB
-- หาพนักงานแผนกบัญชี
SELECT name FROM employees
WHERE profile->>'department' = 'บัญชี';
-- หาพนักงานที่มี Skill "ERP"
SELECT name FROM employees
WHERE profile @> '{"skills": ["ERP"]}';
-- หาพนักงานที่เงินเดือนมากกว่า 32,000
SELECT name, (profile->>'salary')::int AS salary
FROM employees
WHERE (profile->>'salary')::int > 32000;
4. อัปเดตค่าใน JSONB
-- เปลี่ยนแผนก
UPDATE employees
SET profile = jsonb_set(profile, '{department}', '"การเงิน"')
WHERE name = 'สมชาย ใจดี';
-- เพิ่ม Key ใหม่
UPDATE employees
SET profile = profile || '{"phone": "02-347-7730"}'
WHERE name = 'สมชาย ใจดี';
-- ลบ Key ออก
UPDATE employees
SET profile = profile - 'phone'
WHERE name = 'สมชาย ใจดี';
5. สร้าง Index สำหรับ JSONB
-- GIN Index — ค้นหาทุก Key ได้เร็ว
CREATE INDEX idx_profile ON employees USING GIN (profile);
-- GIN Index แบบ jsonb_path_ops — เร็วกว่า แต่รองรับแค่ @>
CREATE INDEX idx_profile_path ON employees
USING GIN (profile jsonb_path_ops);
-- B-Tree Index เฉพาะ Key — เร็วที่สุดสำหรับ Key ที่ใช้บ่อย
CREATE INDEX idx_department ON employees
((profile->>'department'));
PostgreSQL รองรับ JSON/JSONB ตั้งแต่เวอร์ชันไหน?
PostgreSQL เพิ่มการรองรับ JSON มาตั้งแต่หลายปีก่อน และพัฒนาขึ้นเรื่อยๆ ในทุกเวอร์ชัน:
| เวอร์ชัน | ปีที่ออก | ความสามารถ JSON/JSONB ที่เพิ่มเข้ามา |
|---|---|---|
| 9.2 | 2012 | เพิ่ม JSON Data Type เป็นครั้งแรก — เก็บและ Validate JSON ได้ |
| 9.3 | 2013 | เพิ่ม Operator ->, ->> และฟังก์ชัน json_each(), json_array_elements() |
| 9.4 | 2014 | เพิ่ม JSONB Data Type — Binary storage, GIN Index, Operator @>, ?, || |
| 9.5 | 2016 | เพิ่ม jsonb_set(), || สำหรับ merge, Operator - สำหรับลบ Key |
| 9.6 | 2016 | เพิ่ม jsonb_insert(), jsonb_pretty() |
| 12 | 2019 | เพิ่ม SQL/JSON Path Language — ค้นหาด้วย jsonpath เช่น $.skills[*] |
| 14 | 2021 | เพิ่ม Subscripting — เข้าถึง JSONB ด้วย profile['department'] แทน -> |
| 16 | 2023 | เพิ่ม SQL/JSON Constructors ตามมาตรฐาน SQL:2016 — JSON_ARRAY(), JSON_OBJECT() |
| 17 | 2024 | เพิ่ม JSON_TABLE() — แปลง JSON เป็นตารางได้โดยตรง |
คำแนะนำ: หากจะใช้ JSONB อย่างเต็มประสิทธิภาพ ควรใช้ PostgreSQL 12 ขึ้นไป เพราะมี SQL/JSON Path Language ที่ทำให้ Query ข้อมูล JSON ได้สะดวกและมีประสิทธิภาพมากขึ้น — Saeree ERP ใช้ PostgreSQL มากว่า 20 ปีและแนะนำเวอร์ชัน 14+ สำหรับการติดตั้งใหม่
เปรียบเทียบกับฐานข้อมูลอื่น
ไม่ใช่แค่ PostgreSQL ที่รองรับ JSON — แต่ระดับการรองรับต่างกันมาก:
| ฐานข้อมูล | JSON Support | Index | หมายเหตุ |
|---|---|---|---|
| PostgreSQL | JSON + JSONB | GIN, GiST, B-Tree | ครบที่สุด + SQL/JSON Path |
| MySQL 8.0+ | JSON (Binary) | Multi-Valued Index | รองรับดี แต่ Operator น้อยกว่า |
| Oracle 21c+ | JSON + JSON Duality View | Search Index | ดีมาก แต่ค่าลิขสิทธิ์แพง |
| SQL Server | NVARCHAR + JSON Functions | Computed Column | ไม่มี Native JSON Type จนกว่า 2025 Preview |
| MongoDB | BSON (Native) | ครบ | Document DB — ไม่ใช่ Relational |
ข้อควรระวังในการใช้ JSONB
แม้ JSONB จะดีมาก แต่ก็ไม่ควรใช้ทุกที่ — ต้องเข้าใจข้อจำกัด:
- อย่าใช้แทนคอลัมน์ปกติ — ถ้าข้อมูลมีโครงสร้างชัดเจน (เช่น ชื่อ, อีเมล, วันที่) ควรใช้คอลัมน์ปกติที่มี Type ชัดเจน เพราะ ตรวจสอบความถูกต้องได้ดีกว่า
- ระวังขนาดข้อมูล — JSONB ที่มีขนาดใหญ่มากอาจทำให้ การ Backup ช้าลง
- ไม่มี Foreign Key — ไม่สามารถสร้าง FK Constraint ไปยัง Key ภายใน JSONB ได้
- Update ทีละ Key — การแก้ไข JSONB จริงๆ แล้วเป็นการเขียนทับทั้ง Column (ไม่ใช่ In-place Update)
JSONB ใน PostgreSQL ทำให้เราได้สิ่งที่ดีที่สุดจากสองโลก — ความยืดหยุ่นของ NoSQL ผสมกับความน่าเชื่อถือของ Relational Database ใน Saeree ERP เราใช้ JSONB เก็บ Workflow Configuration, Audit Log และ Custom Fields ทำให้ระบบยืดหยุ่นโดยไม่ต้องแก้โครงสร้างตาราง
- ไพฑูรย์ บุตรี, ผู้เชี่ยวชาญด้านระบบเซิร์ฟเวอร์ Grand Linux Solution
สรุป — JSON vs JSONB เลือกตัวไหนดี?
| สถานการณ์ | เลือก | เหตุผล |
|---|---|---|
| ต้อง Query/ค้นหาข้อมูลข้างใน | JSONB | รองรับ Index, Operator ครบ, เร็ว |
| เก็บ Config, Setting, Metadata | JSONB | แก้ไขค่าแต่ละ Key ได้สะดวก |
| เก็บ Log/Archive ที่ต้องรักษารูปแบบ | JSON | เก็บตามที่ใส่มา ไม่เปลี่ยนลำดับ Key |
| ส่วนใหญ่เขียนเยอะ อ่านน้อย | JSON | เขียนเร็วกว่า (ไม่ต้อง Parse) |
| ไม่แน่ใจ / ส่วนใหญ่ของงาน | JSONB | เลือก JSONB เป็น Default — ยืดหยุ่นและเร็วกว่าในทุกสถานการณ์ที่ต้อง Query |
หากคุณสนใจระบบ ERP ที่ใช้ PostgreSQL เป็นฐานข้อมูลหลักและใช้ประโยชน์จาก JSONB อย่างเต็มที่ สามารถนัดหมาย Demo หรือติดต่อทีมที่ปรึกษา Saeree ERP ได้เลย
