PostgreSQL tarafından sunulan JSONB açıklaması


346

PostgreSQL JSONB'yi tanıttı ve hacker haberlerinde zaten trend oluyor . Birisi daha önce PostgreSQL'de bulunan Hstore ve JSON'dan nasıl farklı olduğunu açıklayabilirse harika olurdu. Avantajları ve sınırlamaları nelerdir ve birisi ne zaman kullanmayı düşünmelidir?


4
PGCon2014 Gönderen: youtube.com/...
msanford

5
@CraigRinger url yeterince kesin değil, şimdi 1 yıl sonra JSONB ile ilgili içeriğe yeterince yakın değil.
berkus

2
@berkus Belirli bir yazıyla bağlantı kurduğumu sanıyordum. Ne kadar sinir bozucu.
Craig Ringer

1
Belirli bir videoya işaret ediyor.
talonx

Yanıtlar:


458

İlk olarak, hstoreanahtar = değer çiftlerini depolamanıza izin veren, anahtarların ve değerlerin yalnızca texts olabileceği bir katkı modülü (ancak değerler sql olabilir)NULL ).

Hem json& jsonbgeçerli bir JSON depolamasına izin verir değeri (onun tanımlanan spec ).

F.ex. Bu geçerli bir JSON gösterimleri şunlardır: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}-hstore JSON neler yapabileceğini kıyasla biraz alt kümesidir (ama sadece bu alt kümesi, 's ince gerekirse).

json& Arasındaki tek fark jsonbdepolama alanıdır:

  • json düz metin biçiminde depolanırken
  • jsonb bazı ikili gösterimlerde saklanır

Bunun 3 ana sonucu vardır:

  • jsonbgenellikle depolamak için daha fazla disk alanı alır json(bazen değil)
  • jsonb Girdi temsilini oluşturmak için daha fazla zaman alır json
  • jsonoperasyonlar almak önemli ölçüde daha fazla zaman jsonb(aynı zamanda ayrıştırmada bir de bazı operasyon yapmak her zaman yapılması gerektiğini ve jsondaktilo değeri)

jsonbKararlı bir sürümle ne zaman sunulacaksa, aralarında kolayca seçim yapabileceğiniz iki büyük kullanım durumu olacaktır:

  1. Yalnızca uygulamanızdaki JSON temsiliyle çalışıyorsanız, PostgreSQL yalnızca bu gösterimi depolamak ve almak için kullanılır, json .
  2. PostgreSQL'de JSON değeri üzerinde çok fazla işlem yaparsanız veya bazı JSON alanlarında dizin oluşturmayı kullanırsanız, kullanmalısınız jsonb.

1
merhaba, ikili temsili olduğundan, bunu neden jsonbdesteklemiyor? UPDATE test SET data->'a' = 123 WHERE id = 1;itibarenCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu

1
Kokizzu, 9.5'te mümkün. wiki.postgresql.org/wiki/…
ChelowekKot

1
Sadece eklemek, ayrıca kullanabilir nedenlerinden biri jsonüzerinde jsonbeski nedenlerle kodunuzu senin tüketen eğer olduğunu jsonve sipariş bağlıdır jsonalanları ve onlar yeniden sıralanmış edilemez.
djdrzzy

4
Eski nedenlerden ötürü: JSON'da, bir nesnenin (tablo, harita, karma, ana makine dilinde çağrılan her ne olursa olsun) anahtar / değer çiftleri farklı şekilde sıralanırsa anlamsal bir fark yoktur. Buna güveniyorsanız, aslında JSON'dan farklı bir şey kullanıyorsunuzdur. - textvs. için json: ikincisi JSON doğrulamasıyla birlikte gelir, bu nedenle geçersiz JSON üzerinde, uygulamanız her okuduğunda (geçersiz bir gösterim aldığından) yerine yalnızca ekleme üzerine başarısız olur. Ayrıca, ikincisini jsonbveritabanına güvenli bir şekilde atabilirsiniz .
17'de pozlar

2
Bu JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html ) için uygulama ayrıntılarını açıklayan harika bir gönderi
manugupt1

132

Peeyush:

Kısa cevap:

  • İçinde çok fazla JSON manipülasyonu yapıyorsanızPostgreSQL sıralama, dilimleme, birleştirme vb.Gibi yapıyorsanız, hız nedenleriyle JSONB kullanmalısınız.
  • JSON'da rasgele anahtar aramaları için dizinlenmiş aramalara ihtiyacınız varsa JSONB'yi kullanmalısınız.
  • Yukarıdakilerin hiçbirini yapmıyorsanız, muhtemelen JSON kullanmalısınız.
  • Anahtar sırasını, boşlukları ve yinelenen anahtarları korumanız gerekiyorsa JSON kullanmalısınız.

Daha uzun bir yanıt için, 9.4 sürümüne daha yakın tam bir "HowTo" yazımı yapmamı beklemeniz gerekecek.


74

Json ve jsonb arasındaki farkın basit bir açıklaması ( PostgresProfessional tarafından orijinal görüntü ):

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: metinsel depolama «olduğu gibi»
  • jsonb: boşluk yok
  • jsonb: yinelenen anahtar yok, son anahtar kazancı
  • jsonb: anahtarlar sıralanır

Daha fazla jsonb geliştiricileri tarafından konuşma videosu ve slayt gösterisi sunumu . Ayrıca JsQuery tanıttı , pg.extension güçlü jsonb sorgu dili sağlar


1
Teşekkürler, metne değiştirdim
ChelowekKot

56
  • hstore "geniş sütun" depolama türünden daha fazla ise, her zaman makul düzeyde verimli bir ikili biçimde (karma tablo, dolayısıyla ad) depolanan düz (iç içe geçmiş) bir anahtar / değer çifti sözlüğüdür.
  • jsonJSON belgelerini metin olarak saklar, belgeler saklandığında doğrulama gerçekleştirir ve gerekirse çıktıda ayrıştırır (örn. ayrı alanlara erişim); tüm JSON spesifikasyonlarını desteklemelidir. JSON metninin tamamı saklandığından, biçimlendirmesi korunur.
  • jsonbperformans nedenleriyle kısayollar alır: JSON verileri girişte ayrıştırılır ve ikili biçimde saklanır, sözlüklerdeki anahtar sıralamaları korunmaz ve ikisi de yinelenen anahtar değildir. JSONB alanındaki tek tek öğelere erişmek hızlıdır çünkü JSON metninin her zaman ayrıştırılmasını gerektirmez. Çıktıda, JSON verileri yeniden oluşturulur ve ilk biçimlendirme kaybolur.

IMO, için anlamlı neden yoktur değil kullanarak jsonbsize makine tarafından okunabilir verilerle çalışıyorsanız o sunulduğu andan.


24

JSONB, JSON'un "daha iyi" bir sürümüdür.

Bir örneğe bakalım:

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 beyaz alanı depolar, bu yüzden JSONB anahtar değil, "a" anahtarı saklandığında boşlukları görebiliyoruz.
  2. JSON, anahtarın tüm değerlerini saklar. JSONB yalnızca son değeri "saklar" iken, "a" anahtarına karşı birden fazla değer (2 ve 1) görmenizin nedeni budur.
  3. JSONB "sıralı" sırayı korurken, JSON öğelerin eklendiği sırayı korur.
  4. JSONB nesneleri, JSON'da "ham veriler" yerine, sıkıştırılmış ikili olarak depolanır; burada, geri alma sırasında verilerin yeniden ayrıştırılması gerekmez.
  5. JSONB ayrıca önemli bir avantaj olabilecek dizin oluşturmayı da destekler.

Genel olarak, nesne anahtarlarının sıralanması ile ilgili eski varsayımlar gibi özel ihtiyaçlar yoksa JSONB'yi tercih etmelisiniz.


13

Bugün pgopen'deydim kriterler mongodb'dan çok daha hızlı, seçimler için yaklaşık% 500 daha hızlı olduğuna inanıyorum. Mongodb ile kontrast oluşturulduğunda hemen hemen her şey en az% 200 oranında daha hızlıydı, şu anda bir istisna, mongodb'un daha iyi işlediği bir şey olan json sütununun tamamını yeniden yazmayı gerektiren bir güncelleme.

Jsonb üzerinde cin indeksleme inanılmaz geliyor.

Ayrıca postgres, dahili jsonb türlerini kalıcı olarak sürdürecek ve temel olarak bunu sayısal, metin, boole vb.

Jsonb kullanarak da birleştirme mümkün olacak

Saklı yordamlar için PLv8 ekleyin ve bu temelde node.js geliştiricileri için bir rüya gerçek olacak.

İkili jsonb olarak depolanması, tüm boşlukları da şeritleyecek, özelliklerin sırasını değiştirecek ve özelliğin son tekrarını kullanarak yinelenen özellikleri kaldıracaktır.

Bir json sütun postgres kontrastlı bir jsonb sütun karşı sorgulama dizinin yanı sıra, büyük olasılıkla tek başına büyük miktarda zaman kazandıracak her satırda metni json dönüştürmek için işlevselliği çalıştırmak zorunda değildir.


8

Arasındaki farklılıklar ile ilgili olarak jsonve jsonbbu değer resmi açıklama söz datatypes:

PostgreSQL, JSON verilerini depolamak için iki tür sunar: jsonve jsonb. Bu veri türleri için etkili sorgulama mekanizmaları uygulamak için PostgreSQL, Bölüm 8.14.6'da açıklanan jsonpath veri türünü de sağlar .

jsonVe jsonbveri türleri girdi olarak değerlerin hemen hemen aynı setleri kabul ediyoruz. En büyük pratik fark verimliliktir. jsonVeri tipi depolar işleme fonksiyonları her yürütme yeniden ayrıştırma gereken giriş metin, tam bir kopyası; ederken jsonbveriler saklanır hiçbir yeniden çözümleme gerekli olduğundan, önemli ölçüde daha hızlı sürecine ikili dolayı eklenen dönüşüm yükü biraz daha yavaş girişine yapar biçimi, ancak çürümüş. jsonbAyrıca, önemli bir avantaj olabilecek dizin oluşturmayı da destekler.

Çünkü jsontip depolar tam giriş metninin kopyalamak, bu anlamsal-önemsiz beyaz jeton arasındaki boşluğu, hem de JSON nesneleri içindeki tuşların düzeni koruyacaktır. Ayrıca, değer içindeki bir JSON nesnesi birden fazla aynı anahtarı içeriyorsa, tüm anahtar / değer çiftleri korunur. (İşleme işlevleri son değeri etkin olarak kabul eder.) Aksine, jsonbbeyaz alanı korumaz, nesne anahtarlarının sırasını korumaz ve yinelenen nesne anahtarlarını tutmaz. Girişte yinelenen tuşlar belirtilirse, yalnızca son değer korunur.

Genel olarak, çoğu uygulama jsonbnesne anahtarlarının sıralanması ile ilgili eski varsayımlar gibi oldukça özel ihtiyaçlar olmadıkça JSON verilerini depolamayı tercih etmelidir .

PostgreSQL veritabanı başına sadece bir karakter seti kodlamasına izin verir. Bu nedenle, veritabanı kodlaması UTF8 olmadığı sürece JSON tiplerinin JSON spesifikasyonuna tam olarak uyması mümkün değildir. Veritabanı kodlamasında temsil edilemeyen karakterleri doğrudan ekleme girişimleri başarısız olur; tersine, veritabanı kodlamasında temsil edilebilecek ancak UTF8'de gösterilemeyen karakterlere izin verilecektir.

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


7

Yukarıdaki herhangi bir cevapta belirtilmeyen bir başka önemli fark, jsontip için eşitlik operatörü olmadığı , ancakjsonb .

Kullanmak olamayacağını Bu araçlar DISTINCTbu seçerken anahtar kelime jsonbir tablodan tipi ve / veya diğer alanlar (kullanabilirsiniz DISTINCT ONyerine, ama bunun nedeni gibi vakaların her zaman mümkün değildir bu ).


6

Söyleyebildiğim kadarıyla,

  • hstore şu anda var olduğu için (Postgresql 9.3'te) diğer nesneleri ve dizileri anahtar / değer çiftlerinin değerleri olarak iç içe geçirmeye izin vermez. ancak gelecekteki bir hstore yaması yuvalanmaya izin verecektir. bu düzeltme eki 9.4 sürümünde olmayacak ve yakında eklenmeyebilir.

  • json halihazırda var olduğu için iç içe geçmeye izin verir, ancak metin tabanlıdır ve dizine eklemeye izin vermez, bu nedenle "yavaş"

  • 9.4 ile piyasaya sürülecek olan jsonb, json'un mevcut yuvalama özelliklerine ve hstore'un GIN / GIST endekslemesine sahip olacak, bu yüzden hızlı olacak

Postgresql 9.4 üzerinde çalışan insanlar, yeni, hızlı jsonb türünün MongoDB gibi bir noSQL veri deposu kullanmayı seçecek insanlara hitap edeceğini söylüyor, ancak şimdi ilişkisel bir veritabanını sorgulanabilir yapılandırılmamış verilerle tek bir çatı altında birleştirebilir

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

Postgresql 9.4 jsonb'in karşılaştırmaları MongoDB ile eşit veya bazı durumlarda daha hızlı görünüyor

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.