PostgreSQL แนะนำเพียงJSONBและมันมีอยู่แล้วได้รับความนิยมในข่าวแฮ็กเกอร์ มันจะดีถ้ามีใครสามารถอธิบายได้ว่ามันแตกต่างจาก Hstore และ JSON ก่อนหน้านี้ใน PostgreSQL อะไรคือข้อดีและข้อ จำกัด ของมันและเมื่อมีคนควรพิจารณาใช้มัน?
PostgreSQL แนะนำเพียงJSONBและมันมีอยู่แล้วได้รับความนิยมในข่าวแฮ็กเกอร์ มันจะดีถ้ามีใครสามารถอธิบายได้ว่ามันแตกต่างจาก Hstore และ JSON ก่อนหน้านี้ใน PostgreSQL อะไรคือข้อดีและข้อ จำกัด ของมันและเมื่อมีคนควรพิจารณาใช้มัน?
คำตอบ:
ก่อนอื่นhstore
เป็นโมดูล contrib ซึ่งอนุญาตให้คุณเก็บคู่ key => value เท่านั้นโดยที่คีย์และค่าสามารถเป็นtext
s เท่านั้น(อย่างไรก็ตามค่าสามารถเป็น sql NULL
ได้เช่นกัน)
ทั้งjson
& jsonb
อนุญาตให้คุณเก็บค่า JSON ที่ถูกต้อง(กำหนดไว้ในข้อมูลจำเพาะ )
F.ex. เหล่านี้เป็นตัวแทน JSON ที่ถูกต้อง: null
, true
, [1,false,"string",{"foo":"bar"}]
, {"foo":"bar","baz":[null]}
- hstore
เป็นเพียงส่วนย่อยเล็ก ๆ น้อย ๆ เมื่อเทียบกับสิ่งที่มีความสามารถ JSON ( แต่ถ้าคุณต้องการเพียงเซตนี้ก็ปรับ)
ข้อแตกต่างระหว่างjson
& jsonb
คือที่เก็บข้อมูล:
json
จะถูกจัดเก็บในรูปแบบข้อความธรรมดาในขณะที่jsonb
ถูกเก็บไว้ในการเป็นตัวแทนไบนารีมี 3 ผลกระทบที่สำคัญของสิ่งนี้:
jsonb
มักจะใช้พื้นที่ดิสก์ในการจัดเก็บมากกว่า json
(บางครั้งไม่)jsonb
ใช้เวลาในการสร้างมากขึ้นจากการเป็นตัวแทนอินพุตมากกว่า json
json
การดำเนินการใช้เวลาอย่างมีนัยสำคัญมากกว่าjsonb
(& การแยกวิเคราะห์ยังต้องทำทุกครั้งที่คุณดำเนินการบางอย่างด้วยjson
ค่าที่พิมพ์)เมื่อjsonb
ใดที่จะสามารถใช้งานได้กับรุ่นที่เสถียรจะมีสองกรณีการใช้งานที่สำคัญเมื่อคุณสามารถเลือกได้อย่างง่ายดาย:
json
จะใช้เฉพาะในการจัดเก็บและเรียกการแสดงนี้คุณควรใช้jsonb
คุณควรใช้jsonb
ไม่สนับสนุนสิ่งนี้ UPDATE test SET data->'a' = 123 WHERE id = 1;
จากCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
json
เกินjsonb
คือถ้าด้วยเหตุผลดั้งเดิมรหัสของคุณบริโภคของคุณjson
จะขึ้นอยู่กับการสั่งซื้อของjson
เขตข้อมูลและพวกเขาไม่สามารถจัดลำดับใหม่
text
vs. json
: หลังมาพร้อมกับการตรวจสอบ JSON ดังนั้นเมื่อใช้ JSON ที่ไม่ถูกต้องมันจะล้มเหลวเมื่อทำการแทรกเท่านั้นแทนทุกครั้งที่แอปพลิเคชันของคุณอ่าน (เพราะได้รับการแสดงที่ไม่ถูกต้อง) นอกจากนี้คุณสามารถโยนหลังเพื่อjsonb
ภายในฐานข้อมูล
Peeyush:
คำตอบสั้น ๆ คือ:
สำหรับคำตอบที่ยาวขึ้นคุณจะต้องรอให้ฉันเขียนบทความ "HowTo" ฉบับเต็มใกล้กับรุ่น 9.4
คำอธิบายอย่างง่ายเกี่ยวกับความแตกต่างระหว่าง json และ jsonb ( ภาพต้นฉบับโดย PostgresProfessional ):
SELECT '{"c":0, "a":2,"a":1}'::json, '{"c":0, "a":2,"a":1}'::jsonb;
json | jsonb
------------------------+---------------------
{"c":0, "a":2,"a":1} | {"a": 1, "c": 0}
(1 row)
เพิ่มเติมในวิดีโอคำพูดและการนำเสนอภาพนิ่งโดยนักพัฒนา jsonb นอกจากนี้พวกเขายังแนะนำJsQuery , pg.extension ให้ภาษาเคียวรี jsonb ที่ทรงพลัง
hstore
เป็นประเภทหน่วยเก็บข้อมูล "คอลัมน์กว้าง" มากกว่ามันเป็นพจนานุกรมแบบแบน (ไม่ซ้อนกัน) ของคู่คีย์ - ค่าซึ่งจัดเก็บในรูปแบบไบนารีที่มีประสิทธิภาพพอสมควรเสมอ (ตารางแฮชดังนั้นชื่อ)json
จัดเก็บเอกสาร JSON เป็นข้อความดำเนินการตรวจสอบความถูกต้องเมื่อจัดเก็บเอกสารและแยกวิเคราะห์เอกสารออกหากจำเป็น (เช่นการเข้าถึงแต่ละฟิลด์) ควรสนับสนุนข้อมูลจำเพาะ JSON ทั้งหมด เนื่องจากข้อความ JSON ทั้งหมดถูกจัดเก็บการจัดรูปแบบจะถูกเก็บไว้jsonb
ใช้ทางลัดเพื่อเหตุผลด้านประสิทธิภาพ: ข้อมูล JSON จะถูกวิเคราะห์ในอินพุตและเก็บไว้ในรูปแบบไบนารีการเรียงลำดับคีย์ในพจนานุกรมจะไม่ได้รับการบำรุงรักษาและไม่มีคีย์ซ้ำกัน การเข้าถึงแต่ละองค์ประกอบในฟิลด์ JSONB นั้นรวดเร็วเนื่องจากไม่ต้องแยกวิเคราะห์ข้อความ JSON ตลอดเวลา บนเอาต์พุตข้อมูล JSON จะถูกสร้างขึ้นใหม่และการจัดรูปแบบเริ่มต้นจะหายไปIMO ไม่มีเหตุผลสำคัญที่จะไม่ใช้jsonb
เมื่อมีหากคุณกำลังทำงานกับข้อมูลที่เครื่องอ่านได้
JSONB เป็นรุ่น "ดีกว่า" ของ JSON
ลองดูตัวอย่าง:
SELECT '{"c":0, "a":2,"a":1}'::json, '{"c":0, "a":2,"a":1}'::jsonb;
json | jsonb
------------------------+---------------------
{"c":0, "a":2,"a":1} | {"a": 1, "c": 0}
(1 row)
โดยทั่วไปเราควรเลือก JSONB ยกเว้นว่ามีความต้องการเฉพาะเช่นสมมติฐานเกี่ยวกับการสั่งซื้อคีย์วัตถุ
ฉันอยู่ที่ pgopen วันนี้มาตรฐานเร็วกว่า mongodb ฉันเชื่อว่ามันเร็วกว่าประมาณ 500% สำหรับการเลือก ทุกอย่างสวยเร็วกว่าอย่างน้อย 200% เมื่อเทียบกับ mongodb มากกว่าหนึ่งข้อยกเว้นในขณะนี้คือการอัปเดตที่ต้องเขียนใหม่ทั้งหมดใน json คอลัมน์ทั้งหมดที่ mongodb จัดการได้ดีกว่า
การจัดทำดัชนีจินบน jsonb ฟังดูน่าทึ่ง
นอกจากนี้ postgres จะยังคงประเภทของ jsonb ภายในและโดยทั่วไปจะจับคู่กับประเภทเช่นตัวเลขข้อความบูลีน ฯลฯ
เข้าร่วมก็จะเป็นไปได้โดยใช้ jsonb
เพิ่ม PLv8 สำหรับขั้นตอนการจัดเก็บและนี่จะเป็นความฝันที่เป็นจริงสำหรับนักพัฒนา node.js
เนื่องจากมันถูกจัดเก็บในรูปแบบไบนารี jsonb จะตัดช่องว่างทั้งหมดเปลี่ยนลำดับของคุณสมบัติและลบคุณสมบัติที่ซ้ำกันโดยใช้การเกิดขึ้นครั้งสุดท้ายของคุณสมบัติ
นอกจากดัชนีเมื่อทำการสอบถามกับคอลัมน์ jsonb ซึ่งตรงกันข้ามกับคอลัมน์ json postgres ไม่จำเป็นต้องเรียกใช้ฟังก์ชันการทำงานเพื่อแปลงข้อความเป็น json ในทุกแถวซึ่งน่าจะประหยัดเวลาได้มาก
เกี่ยวกับความแตกต่างระหว่างjson
และjsonb
ประเภทข้อมูลมีมูลค่าการกล่าวถึงคำอธิบายอย่างเป็นทางการ:
PostgreSQL มีสองประเภทสำหรับการจัดเก็บข้อมูล JSON: และ
json
jsonb
ในการใช้กลไกการสืบค้นที่มีประสิทธิภาพสำหรับประเภทข้อมูลเหล่านี้ PostgreSQL ยังจัดเตรียมชนิดข้อมูล jsonpath ที่อธิบายไว้ในส่วน 8.14.68.14.6
json
และjsonb
ข้อมูลประเภทยอมรับชุดเหมือนกันเกือบของค่าเป็น input ความแตกต่างในทางปฏิบัติที่สำคัญคือประสิทธิภาพอย่างหนึ่งjson
ชนิดข้อมูลร้านค้าสำเนาถูกต้องของการป้อนข้อความซึ่งฟังก์ชั่นการประมวลผลจะต้อง reparse ในแต่ละการดำเนินการ; ในขณะที่jsonb
ข้อมูลถูกเก็บไว้ในรูปแบบไบนารีที่แยกย่อยแล้วซึ่งทำให้การป้อนข้อมูลช้าลงเล็กน้อยเนื่องจากค่าใช้จ่ายในการแปลงเพิ่ม แต่ประมวลผลได้เร็วกว่ามากเนื่องจากไม่จำเป็นต้องทำการวิเคราะห์ซ้ำjsonb
ยังสนับสนุนการจัดทำดัชนีซึ่งเป็นข้อได้เปรียบที่สำคัญเนื่องจาก
json
ชนิดนี้เก็บสำเนาของข้อความอินพุตที่แน่นอนมันจะรักษาพื้นที่สีขาวที่ไม่มีนัยสำคัญทางความหมายระหว่างโทเค็นรวมถึงลำดับของคีย์ภายในวัตถุ JSON นอกจากนี้หากอ็อบเจ็กต์ JSON ภายในค่ามีคีย์เดียวกันมากกว่าหนึ่งครั้งคู่ของคีย์ / ค่าทั้งหมดจะถูกเก็บไว้ (ฟังก์ชั่นการประมวลผลพิจารณาค่าสุดท้ายว่าเป็นหัตถการ) โดยทางตรงกันข้ามjsonb
ไม่รักษาพื้นที่สีขาวไม่รักษาลำดับของคีย์วัตถุและไม่เก็บคีย์วัตถุที่ซ้ำกัน หากระบุคีย์ที่ซ้ำกันในอินพุตจะเก็บเฉพาะค่าสุดท้ายเท่านั้นโดยทั่วไปแอปพลิเคชันส่วนใหญ่ควรเก็บข้อมูล JSON เป็น
jsonb
เว้นแต่มีความต้องการค่อนข้างพิเศษเช่นสมมติฐานดั้งเดิมเกี่ยวกับการสั่งซื้อคีย์วัตถุPostgreSQL อนุญาตการเข้ารหัสชุดอักขระหนึ่งตัวต่อฐานข้อมูลเท่านั้น ดังนั้นจึงเป็นไปไม่ได้สำหรับประเภท JSON เพื่อให้สอดคล้องกับข้อกำหนดคุณสมบัติ JSON อย่างเข้มงวดเว้นแต่การเข้ารหัสฐานข้อมูลคือ UTF8 ความพยายามรวมอักขระที่ไม่สามารถแสดงในการเข้ารหัสฐานข้อมูลโดยตรงจะล้มเหลว ในทางกลับกันตัวอักษรที่สามารถแสดงในการเข้ารหัสฐานข้อมูล แต่ไม่อนุญาตใน UTF8
ที่มา: https://www.postgresql.org/docs/current/datatype-json.html
ข้อแตกต่างที่สำคัญอีกข้อหนึ่งที่ไม่ได้กล่าวถึงในคำตอบข้างต้นคือไม่มีตัวดำเนินการความเสมอภาคสำหรับjson
ประเภท แต่มีสำหรับjsonb
แต่มีหนึ่งสำหรับ
ซึ่งหมายความว่าคุณไม่สามารถใช้DISTINCT
คำหลักเมื่อเลือกjson
-type และ / หรือฟิลด์อื่น ๆ จากตาราง (คุณสามารถใช้DISTINCT ON
แทนได้ แต่อาจไม่สามารถทำได้เนื่องจากทุกกรณีเช่นนี้ )
เท่าที่ฉันสามารถบอกได้
hstore เนื่องจากมีอยู่ในปัจจุบัน (ใน Postgresql 9.3) ไม่อนุญาตให้ซ้อนวัตถุและอาร์เรย์อื่น ๆ เป็นค่าของคู่คีย์ / ค่า อย่างไรก็ตามแพทช์ hstore ในอนาคตจะอนุญาตให้ทำรังได้ โปรแกรมปรับปรุงนี้จะไม่อยู่ในรุ่น 9.4 และอาจไม่รวมในเวลาไม่นาน
JSON ขณะที่มันมีอยู่ในปัจจุบันไม่อนุญาตให้มีการทำรัง แต่เป็นข้อความที่ใช้และไม่อนุญาตให้มีการจัดทำดัชนีสำหรับดังนั้นมันคือ "ช้า"
jsonb ที่จะวางจำหน่ายใน 9.4 จะมีความสามารถในการซ้อนปัจจุบันของ json เช่นเดียวกับการทำดัชนี GIN / GIST ของ hstore ดังนั้นมันจะเร็ว
คนที่ทำงานกับ postgresql 9.4 ดูเหมือนจะบอกว่าประเภท jsonb ใหม่ที่รวดเร็วจะดึงดูดผู้ที่เลือกใช้ noSQL data store เช่น MongoDB แต่ตอนนี้สามารถรวมฐานข้อมูลเชิงสัมพันธ์กับข้อมูลที่ไม่มีโครงสร้างที่สามารถสืบค้นได้ภายใต้หลังคาเดียวกัน
http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html
มาตรฐานของ postgresql 9.4 jsonb ดูเหมือนจะเทียบเท่าหรือในบางกรณีเร็วกว่า MongoDB
http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb