Penjelasan JSONB diperkenalkan oleh PostgreSQL

346

PostgreSQL baru saja memperkenalkan JSONB dan sudah tren di berita hacker . Akan lebih bagus jika seseorang dapat menjelaskan bagaimana perbedaannya dengan Hstore dan JSON yang sebelumnya ada di PostgreSQL. Apa kelebihan dan keterbatasannya dan kapan seseorang harus mempertimbangkan untuk menggunakannya?

Peeyush
sumber
4
Dari PGCon2014: youtube.com/…
msanford
5
@CraigRinger url tidak cukup tepat, sekarang, 1 tahun kemudian bahkan tidak cukup dekat dengan konten terkait JSONB.
Berkus
2
@berkus saya pikir saya tertaut ke posting tertentu. Sangat frustasi.
Craig Ringer
1
Itu menunjuk ke video tertentu.
talonx

Jawaban:

457

Pertama, hstoreadalah modul contrib, yang hanya memungkinkan Anda untuk menyimpan pasangan kunci => nilai, di mana kunci dan nilai hanya dapat berupa texts (namun nilai juga dapat berupa sql NULLs).

Keduanya json& jsonbmemungkinkan Anda untuk menyimpan nilai JSON yang valid (ditentukan dalam speknya ).

F.ex. ini adalah representasi JSON valid: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstorehanya bagian kecil dibandingkan dengan apa JSON mampu (tetapi jika Anda hanya perlu subset ini, itu baik-baik saja).

Satu-satunya perbedaan antara json& jsonbadalah penyimpanannya:

  • json disimpan dalam format teks biasa, sementara
  • jsonb disimpan dalam beberapa representasi biner

Ada 3 konsekuensi utama dari ini:

  • jsonbbiasanya membutuhkan lebih banyak ruang disk untuk menyimpan daripada json(terkadang tidak)
  • jsonb membutuhkan lebih banyak waktu untuk membangun dari representasi inputnya daripada json
  • jsonoperasi membutuhkan waktu lebih banyak secara signifikan daripada jsonb(& parsing juga perlu dilakukan setiap kali Anda melakukan beberapa operasi pada jsonnilai yang diketik)

Kapan jsonbakan tersedia dengan rilis stabil, akan ada dua kasus penggunaan utama, ketika Anda dapat dengan mudah memilih di antara mereka:

  1. Jika Anda hanya bekerja dengan representasi JSON di aplikasi Anda, PostgreSQL hanya digunakan untuk menyimpan & mengambil representasi ini, Anda harus menggunakan json.
  2. Jika Anda melakukan banyak operasi pada nilai JSON di PostgreSQL, atau menggunakan pengindeksan pada beberapa bidang JSON, Anda harus menggunakan jsonb.
pozs
sumber
1
hai, karena memiliki representasi biner, mengapa jsonbtidak mendukung ini? UPDATE test SET data->'a' = 123 WHERE id = 1;dariCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu
1
Kokizzu, itu mungkin di 9.5. wiki.postgresql.org/wiki/…
ChelowekKot
1
Hanya untuk menambahkan, salah satu alasan Anda mungkin juga menggunakan jsonlebih jsonbadalah jika karena alasan warisan kode Anda memakan Anda jsontergantung pada pemesanan jsonbidang dan mereka tidak dapat disusun ulang.
djdrzzy
4
Karena, untuk alasan sebelumnya: dalam JSON, tidak ada perbedaan semantik, jika objek (tabel, peta, hash, apa pun namanya dalam bahasa host) pasangan nilai kunci dipesan secara berbeda. Jika Anda mengandalkan itu, Anda sebenarnya menggunakan sesuatu yang berbeda dari JSON. - Untuk textvs json.: yang terakhir disertai dengan validasi JSON, jadi pada JSON yang tidak valid, itu hanya akan gagal saat memasukkan, alih-alih setiap kali aplikasi Anda membacanya (karena mendapat representasi yang tidak valid). Anda juga dapat dengan aman memasukkan yang terakhir ke jsonbdalam basis data.
pozs
2
Ini adalah pos yang bagus untuk menjelaskan detail implementasi untuk JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1
131

Peeyush:

Jawaban singkatnya adalah:

  • Jika Anda melakukan banyak manipulasi JSON di dalam PostgreSQL, seperti menyortir, mengiris, menyambung, dll., Anda harus menggunakan JSONB untuk alasan kecepatan.
  • Jika Anda membutuhkan pencarian yang diindeks untuk pencarian kunci sewenang-wenang di JSON, maka Anda harus menggunakan JSONB.
  • Jika Anda tidak melakukan hal di atas, Anda mungkin harus menggunakan JSON.
  • Jika Anda perlu mempertahankan kunci pemesanan, spasi putih, dan kunci duplikat, Anda harus menggunakan JSON.

Untuk jawaban yang lebih lama, Anda harus menunggu saya melakukan penulisan "HowTo" lengkap lebih dekat dengan rilis 9.4.

FuzzyChef
sumber
74

Penjelasan sederhana tentang perbedaan antara json dan jsonb ( gambar asli oleh 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)
  • json: penyimpanan teks «sebagaimana adanya»
  • jsonb: tidak ada spasi putih
  • jsonb: tidak ada kunci duplikat, kunci menang terakhir
  • jsonb: kunci diurutkan

Lebih banyak di video pidato dan presentasi slide oleh pengembang jsonb. Juga mereka memperkenalkan JsQuery , pg.extension menyediakan bahasa permintaan jsonb yang kuat

ChelowekKot
sumber
1
Terima kasih, saya telah menggantinya ke teks
ChelowekKot
56
  • hstore lebih dari jenis penyimpanan "kolom lebar", ini adalah kamus datar (bukan-bersarang) dari pasangan nilai kunci, selalu disimpan dalam format biner yang cukup efisien (tabel hash, karenanya namanya).
  • jsonmenyimpan dokumen JSON sebagai teks, melakukan validasi ketika dokumen disimpan, dan menguraikannya pada output jika diperlukan (yaitu mengakses masing-masing bidang); harus mendukung seluruh spesifikasi JSON. Karena seluruh teks JSON disimpan, pemformatannya dipertahankan.
  • jsonbmengambil jalan pintas untuk alasan kinerja: data JSON diuraikan pada input dan disimpan dalam format biner, urutan kunci dalam kamus tidak dikelola, dan juga kunci duplikat. Mengakses elemen individual di bidang JSONB cepat karena tidak memerlukan penguraian teks JSON setiap saat. Pada output, data JSON direkonstruksi dan pemformatan awal hilang.

IMO, tidak ada alasan signifikan untuk tidak menggunakan jsonbsetelah tersedia, jika Anda bekerja dengan data yang dapat dibaca mesin.

Ivan Voras
sumber
24

JSONB adalah versi JSON yang "lebih baik".

Mari kita lihat sebuah contoh:

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)
  1. JSON menyimpan spasi, itulah sebabnya kita bisa melihat spasi ketika kunci "a" disimpan, sementara JSONB tidak.
  2. JSON menyimpan semua nilai kunci. Ini adalah alasan Anda dapat melihat beberapa nilai (2 dan 1) terhadap kunci "a", sementara JSONB hanya "menyimpan" nilai terakhir.
  3. JSON mempertahankan urutan elemen dimasukkan, sementara JSONB mempertahankan urutan "diurutkan".
  4. Objek JSONB disimpan sebagai biner yang dikompresi sebagai lawan dari "data mentah" di JSON, di mana tidak diperlukan reparasi data selama pengambilan.
  5. JSONB juga mendukung pengindeksan, yang bisa menjadi keuntungan yang signifikan.

Secara umum, seseorang harus memilih JSONB, kecuali ada kebutuhan khusus, seperti asumsi warisan tentang pemesanan kunci objek.

subodhkarwa
sumber
13

Saya berada di pgopen hari ini tolok ukur jauh lebih cepat daripada mongodb, saya percaya itu sekitar 500% lebih cepat untuk pilihan. Cukup banyak semuanya lebih cepat setidaknya 200% bila dibandingkan dengan mongodb, dari satu pengecualian saat ini adalah pembaruan yang mengharuskan sepenuhnya menulis ulang seluruh kolom json sesuatu yang ditangani mongodb lebih baik.

Pengindeksan gin pada jsonb terdengar luar biasa.

Postgres juga akan tetap menggunakan tipe jsonb secara internal dan pada dasarnya mencocokkan ini dengan tipe seperti numerik, teks, boolean dll.

Bergabung juga akan dimungkinkan menggunakan jsonb

Tambahkan PLv8 untuk prosedur tersimpan dan ini pada dasarnya akan menjadi mimpi yang menjadi kenyataan bagi pengembang node.js.

Menjadi itu disimpan sebagai binary jsonb juga akan menghapus semua spasi putih, mengubah urutan properti dan menghapus properti duplikat menggunakan kejadian terakhir properti.

Selain indeks ketika kueri terhadap kolom jsonb berbeda dengan kolom json, postgres tidak harus benar-benar menjalankan fungsionalitas untuk mengubah teks menjadi json di setiap baris yang kemungkinan akan menghemat banyak waktu sendirian.

John
sumber
8

Mengenai perbedaan antara jsondan jsonbtipe data, ada baiknya menyebutkan penjelasan resmi:

PostgreSQL menawarkan dua jenis untuk menyimpan data JSON: jsondan jsonb. Untuk menerapkan mekanisme kueri yang efisien untuk tipe data ini, PostgreSQL juga menyediakan tipe data jsonpath yang dijelaskan dalam Bagian 8.14.6 .

Tipe jsondan jsonbdata menerima set nilai yang hampir identik sebagai input. Perbedaan praktis utama adalah efisiensi. The jsontipe data toko salinan dari teks input, yang berfungsi pengolahan harus reparse pada setiap eksekusi; sementara jsonbdata disimpan dalam format biner terurai yang membuatnya sedikit lebih lambat untuk input karena penambahan overhead konversi, tetapi secara signifikan lebih cepat untuk diproses, karena tidak diperlukan reparsing. jsonbjuga mendukung pengindeksan, yang bisa menjadi keuntungan yang signifikan.

Karena jsontipe menyimpan salinan teks input yang tepat, itu akan mempertahankan ruang putih semantik-tidak signifikan antara token, serta urutan kunci dalam objek JSON. Juga, jika objek JSON dalam nilai berisi kunci yang sama lebih dari sekali, semua pasangan kunci / nilai disimpan. (Fungsi pemrosesan menganggap nilai terakhir sebagai yang operatif.) Sebaliknya, jsonbtidak mempertahankan ruang putih, tidak mempertahankan urutan kunci objek, dan tidak menyimpan kunci objek duplikat. Jika kunci duplikat ditentukan dalam input, hanya nilai terakhir yang disimpan.

Secara umum, sebagian besar aplikasi harus memilih untuk menyimpan data JSON sebagai jsonb, kecuali ada kebutuhan yang cukup khusus, seperti asumsi warisan tentang pemesanan kunci objek.

PostgreSQL hanya mengizinkan satu set karakter pengkodean per basis data. Oleh karena itu tidak mungkin untuk tipe JSON untuk menyesuaikan secara kaku dengan spesifikasi JSON kecuali jika pengkodean database adalah UTF8. Upaya untuk secara langsung memasukkan karakter yang tidak dapat direpresentasikan dalam pengkodean basis data akan gagal; sebaliknya, karakter yang dapat direpresentasikan dalam pengkodean basis data tetapi tidak dalam UTF8 akan diizinkan.

Sumber: https://www.postgresql.org/docs/current/datatype-json.html

Dinei
sumber
7

Perbedaan penting lainnya, yang tidak disebutkan dalam jawaban di atas, adalah bahwa tidak ada operator kesetaraan untuk jsontipe, tetapi ada satu untuk jsonb.

Ini berarti bahwa Anda tidak dapat menggunakan DISTINCTkata kunci saat memilih json-type ini dan / atau bidang lain dari sebuah tabel (Anda dapat menggunakannya DISTINCT ON, tetapi itu tidak selalu memungkinkan karena kasus seperti ini ).

vlasiak
sumber
6

Sejauh yang saya tahu,

  • hstore seperti yang ada saat ini (dalam Postgresql 9.3) tidak memungkinkan untuk bersarang objek dan array lainnya sebagai nilai pasangan kunci / nilainya. Namun patch hstore masa depan akan memungkinkan untuk bersarang. tambalan ini tidak akan ada dalam rilis 9.4 dan mungkin tidak akan disertakan dalam waktu dekat.

  • json karena saat ini ada memang memungkinkan untuk bersarang, tetapi berbasis teks, dan tidak memungkinkan untuk pengindeksan, sehingga "lambat"

  • jsonb yang akan dirilis dengan 9,4 akan memiliki kemampuan bersarang json saat ini, serta pengindeksan GIN / GIST dari hstore, sehingga akan cepat

Orang-orang yang bekerja pada postgresql 9.4 tampaknya mengatakan bahwa tipe jsonb baru yang cepat akan menarik bagi orang-orang yang akan memilih untuk menggunakan penyimpanan data noSQL seperti MongoDB, tetapi sekarang dapat menggabungkan database relasional dengan data tak terstruktur yang dapat dikueri dalam satu atap.

http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html

Benchmark dari postgresql 9.4 jsonb tampaknya setara dengan atau dalam beberapa kasus lebih cepat dari MongoDB

http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb

erik swedberg
sumber