13 คะแนน โดย GN⁺ 2023-12-07 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • มีการเขียนฟังก์ชัน JSON เดิมของ SQLite ใหม่ ทำให้ทำงานได้เร็วขึ้นหลายเท่าตามรูปแบบการใช้งาน
  • เดิมฟังก์ชัน JSON ทำงานเป็น 3 ขั้นตอน
    1. แปลง JSON เป็นฟอร์แมตไบนารีภายในที่โค้ด C จัดการได้ง่าย
    2. ทำงานตามที่ร้องขอ เช่น ค้นหาฟิลด์เฉพาะหรือแก้ไข JSON
    3. หากงานนั้นมีการเปลี่ยนแปลง JSON ก็จะแปลงฟอร์แมตไบนารีภายในกลับเป็นสตริง JSON ตาม RFC-8279 เพื่อส่งออกหรือจัดเก็บ
  • นอกเหนือจากขั้นตอนที่ 2 แล้ว ขั้นตอนที่ 1 และ 3 ถือเป็น overhead
  • SQLite ใช้ JSON ในรูปแบบไบนารีภายในที่มี pointer จำนวนมาก ซึ่งเหมาะกับโปรแกรม C แต่ทำ serialization ได้ยาก
  • ด้วยการเขียน JSONB ใหม่ จึงเปลี่ยนการแทนค่าไบนารีภายในของ JSON นี้ให้เป็นอาร์เรย์ไบต์ต่อเนื่องที่สามารถอ่านหรือเขียนเป็น SQL BLOB ได้
  • วิธีนี้ทำให้สามารถเก็บรูปแบบ JSON ที่ใช้ภายในลงในฐานข้อมูลแทน JSON แบบข้อความได้ จึงตัด overhead ของขั้นตอนที่ 1 และ 3 ออกไปได้

สิ่งที่เปลี่ยนไป

  • ฟังก์ชันเดิมทั้งหมดยังคงอยู่เหมือนเดิม มีเพียงการเพิ่มความสามารถใหม่เท่านั้น
  • ตอนนี้ฟังก์ชัน JSON ทุกตัวที่รับ JSON แบบข้อความเป็นอินพุต จะรับเนื้อหาไบนารี JSONB สำหรับพารามิเตอร์เดียวกันได้ด้วย
    • ไม่จำเป็นต้องบอกฟังก์ชันว่าจะรับข้อความหรือข้อมูลไบนารี เพราะฟังก์ชันจะตรวจสอบและตัดสินใจเอง
  • ตอนนี้ฟังก์ชัน JSON ที่ส่งออก JSON มีให้ 2 เวอร์ชัน
    • ฟังก์ชัน "json_" แบบเดิมยังทำงานเหมือนก่อน
    • มีฟังก์ชัน "jsonb_" ที่คืนค่าเป็น JSONB แทน JSON แบบข้อความ ทำให้ข้ามขั้นตอนที่ 3 ไปได้ในการประมวลผลทั่วไป
  • หากไม่เปลี่ยนแอปพลิเคชัน ความเร็วจะเพิ่มขึ้นเล็กน้อย (1%) แต่ทุกอย่างยังคงทำงานเหมือนเดิม
  • แต่หากแก้แอปพลิเคชันให้เริ่มเก็บ JSONB แทน JSON แบบข้อความ อย่างน้อยในงานที่ใช้ JSON หนัก ๆ อาจเห็นประสิทธิภาพเพิ่มขึ้น 3 เท่า
  • นอกจากนี้ JSONB ยังมีขนาดเล็กกว่า JSON แบบข้อความเล็กน้อยในกรณีส่วนใหญ่ (เล็กกว่าประมาณ 5% หรือ 10%) ดังนั้นหากมีการใช้ JSON จำนวนมาก ก็อาจเห็นขนาดฐานข้อมูลลดลงเล็กน้อย

1 ความคิดเห็น

 
GN⁺ 2023-12-07
ความเห็นบน Hacker News
  • มีความสับสนเกี่ยวกับ JSONB อยู่มาก

    • ในระดับการใช้งานของแอปพลิเคชัน JSONB ถูกใช้ในลักษณะที่คล้ายกับชนิดข้อมูล JSON มาก
    • แอปพลิเคชันยังคงอ่านและเขียนสตริง JSON แต่จะไม่เห็นเนื้อหา JSONB จริง
    • ฟังก์ชัน SQL ชุดเดียวกันสามารถใช้ได้โดยมีคำนำหน้า jsonb_
    • ชนิดข้อมูล JSON จะถูกเก็บบนดิสก์เป็น JSON แต่ JSONB จะถูกเก็บเป็นฟอร์แมตไบนารีพิเศษ
    • ชนิดข้อมูล JSON ต้องพาร์ส JSON ทั้งหมดก่อนจึงจะทำงานได้ แต่ JSONB สามารถข้ามขั้นตอนการพาร์สและทำงานกับฟอร์แมตบนดิสก์ได้โดยตรง
    • ถ้าใน SQLite คุณเพียงแค่อ่านและเขียน JSON blob ทั้งก้อน ชนิดข้อมูล JSON ก็เหมาะสม แต่ถ้าคุณใช้ SQL เพื่อคิวรีหรือจัดการข้อมูล JSONB จะเหมาะกว่า
  • JSONB เป็นฟอร์แมตที่มีใน Postgres และมักแนะนำให้ใช้เพราะมีประสิทธิภาพในการอ่านดีกว่า JSON ปกติ

  • ใช้เวลาหลายปีกว่าจะเข้าใจเป้าหมายของ document store และมันยอดเยี่ยมมากสำหรับการสร้าง POC (Proof of Concept)

    • การเพิ่มความสามารถด้าน JSON จะช่วยให้ SQLite เหมาะจะเป็น document store มากขึ้น
    • สามารถ serialize และ deserialize ข้อความ Protobuf เพื่อให้ได้การรองรับชนิดข้อมูลแบบครบถ้วน และหากทำคอลัมน์นี้เป็น JSONB ก็จะสามารถกรองข้อมูลในคอลัมน์นี้ได้โดยไม่ต้องแยกข้อมูลที่ค้นหาได้ออกไปเก็บในคอลัมน์อื่น
  • มีความสงสัยเกี่ยวกับกระบวนการออกรุ่นของ SQLite

    • รุ่นล่าสุดคือ 3.44 และ JSONB รวมอยู่ในสแนปช็อตก่อนรีลีส
    • อยากใช้ฟีเจอร์นี้ใน D1 ของ Cloudflare และบน Fly.io แต่เวอร์ชัน SQLite อาจยังไม่เปิดเผยหรืออาจมีการปรับแต่งเอง
    • การเปลี่ยนแปลง API อาจทำให้คำมั่นของ Cloudflare ที่ว่าจะสามารถนำเข้าไฟล์ dump/query ที่เข้ากันได้กับ SQLite ใช้ไม่ได้อีก
  • สามารถลองใช้ JSONB ได้ในสแนปช็อตก่อนรีลีสหรือใน playground

  • แนวคิดหลักของสเปก JSONB คือแต่ละองค์ประกอบจะเริ่มต้นด้วย header ที่มีขนาดและชนิดข้อมูลอยู่ในนั้น

    • มีการเสนอว่าการเพิ่มตัวบอกขนาดลงในสเปก JSON อาจช่วยลดหน่วยความจำที่ต้องใช้ในการประมวลผล JSON ได้
  • คุ้นเคยกับ BSON ของ MongoDB แต่ไม่คุ้นกับ JSONB

  • JSONB ส่งผลต่อประสิทธิภาพ

  • อยากให้มีวิธีบีบอัดข้อมูล JSON ข้ามหลายแถวได้

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

    • ตัวอย่างเช่น ในการ insert แบบเป็นชุดจาก Python การเรียก insert ต่อหนึ่งแถวมี overhead ที่สังเกตได้ชัด
    • JSONB สามารถปรับปรุงประสิทธิภาพได้ด้วยการใช้ CTE (Common Table Expressions)
    • json_each สามารถรับพารามิเตอร์ที่ bind จากแอปพลิเคชันเป็น JSONB BLOB ได้