Giải thích về JSONB được giới thiệu bởi PostgreSQL


345

PostgreSQL vừa giới thiệu JSONB và nó đã có xu hướng về tin tức hacker . Sẽ thật tuyệt nếu ai đó có thể giải thích nó khác với Hstore và JSON trước đây như thế nào trong PostgreQuery. Những lợi thế và hạn chế của nó là gì và khi nào ai đó nên xem xét sử dụng nó?


4
Từ PGCon2014: youtube.com/
msanford

5
Url @CraigRinger không đủ chính xác, bây giờ, 1 năm sau, nó thậm chí không đủ gần với nội dung liên quan đến JSONB.
berkus

2
@berkus Tôi nghĩ rằng tôi đã liên kết với bài viết cụ thể. Bực bội như thế nào.
Craig Ringer

1
Nó chỉ đến video cụ thể.
Talonx

Câu trả lời:


455

Đầu tiên, hstorelà một mô-đun contrib, chỉ cho phép bạn lưu trữ cặp khóa => cặp giá trị, trong đó khóa và giá trị chỉ có thể là texts (tuy nhiên giá trị cũng có thể là sql NULLs).

Cả json& jsonbcho phép bạn lưu trữ một JSON hợp lệ giá trị (được định nghĩa trong nó đặc tả ).

F.ex đây là những cơ quan đại diện JSON hợp lệ: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstorechỉ là một chút tập hợp con so với những gì JSON có khả năng (nhưng nếu bạn chỉ cần tập hợp con này, nó tốt).

Sự khác biệt duy nhất giữa json& jsonblà lưu trữ của chúng:

  • json được lưu trữ ở định dạng văn bản đơn giản của nó, trong khi
  • jsonb được lưu trữ trong một số đại diện nhị phân

Có 3 hậu quả chính của việc này:

  • jsonbthường chiếm nhiều không gian đĩa để lưu trữ hơn json(đôi khi không)
  • jsonb mất nhiều thời gian hơn để xây dựng từ đại diện đầu vào của nó hơn json
  • jsoncác hoạt động mất nhiều thời gian hơn đáng kể so với jsonb(& phân tích cú pháp cũng cần được thực hiện mỗi khi bạn thực hiện một số thao tác với jsongiá trị được nhập)

Khi jsonbcó sẵn với một bản phát hành ổn định, sẽ có hai trường hợp sử dụng chính, khi bạn có thể dễ dàng chọn giữa chúng:

  1. Nếu bạn chỉ làm việc với biểu diễn JSON trong ứng dụng của mình, PostgreSQL chỉ được sử dụng để lưu trữ và truy xuất đại diện này, bạn nên sử dụng json.
  2. Nếu bạn thực hiện nhiều thao tác trên giá trị JSON trong PostgreSQL hoặc sử dụng lập chỉ mục trên một số trường JSON, bạn nên sử dụng jsonb.

1
xin chào, vì nó có biểu diễn nhị phân, tại sao jsonbkhông hỗ trợ điều này? UPDATE test SET data->'a' = 123 WHERE id = 1;từCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Kokizzu

1
Kokizzu, nó có thể trong 9.5. wiki.postgresql.org/wiki/ (
ChelowekKot 30/03/2016

1
Chỉ cần thêm, một trong những lý do bạn cũng có thể sử dụng jsontrên jsonblà nếu vì lý do di sản tiêu thụ mã của bạn của bạn jsonlà phụ thuộc vào thứ tự của jsoncác lĩnh vực và họ không thể được sắp xếp lại.
djdrzzy

4
Vì, vì các lý do di sản: trong JSON, không có sự khác biệt về ngữ nghĩa, nếu các đối tượng (bảng, bản đồ, hàm băm, bất cứ thứ gì nó được gọi bằng ngôn ngữ máy chủ) được sắp xếp khác nhau. Nếu bạn dựa vào điều đó, bạn thực sự đang sử dụng một cái gì đó khác với JSON. - Đối textvới vs json.: cái sau đi kèm với xác thực JSON, do đó, khi JSON không hợp lệ, nó sẽ chỉ thất bại khi chèn, thay vì mỗi lần ứng dụng của bạn đọc nó (vì nó có đại diện không hợp lệ). Ngoài ra, bạn có thể truyền cái sau một cách an toàn jsonbvào cơ sở dữ liệu.
pozs

2
Đây là một bài viết tuyệt vời về việc giải thích các chi tiết triển khai cho JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1

131

Peeyush:

Câu trả lời ngắn gọn là:

  • Nếu bạn đang thực hiện nhiều thao tác JSON bên trong PostgreSQL, chẳng hạn như sắp xếp, cắt, ghép, v.v., bạn nên sử dụng JSONB vì lý do tốc độ.
  • Nếu bạn cần tra cứu được lập chỉ mục cho các tìm kiếm khóa tùy ý trên JSON, thì bạn nên sử dụng JSONB.
  • Nếu bạn không làm như trên, có lẽ bạn nên sử dụng JSON.
  • Nếu bạn cần duy trì thứ tự khóa, khoảng trắng và khóa trùng lặp, bạn nên sử dụng JSON.

Để có câu trả lời dài hơn, bạn sẽ cần đợi tôi thực hiện viết hoàn chỉnh "Cách thực hiện" gần hơn với bản phát hành 9.4.


74

Một lời giải thích đơn giản về sự khác biệt giữa json và jsonb ( ảnh gốc của PostgresProf Professional ):

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: lưu trữ văn bản «như là»
  • jsonb: không có khoảng trắng
  • jsonb: không có khóa trùng lặp, khóa cuối cùng giành chiến thắng
  • jsonb: các phím được sắp xếp

Thêm trong bài phát biểu videotrình chiếu slide của các nhà phát triển jsonb. Ngoài ra họ đã giới thiệu JsQuery , pg.extension cung cấp ngôn ngữ truy vấn jsonb mạnh mẽ


1
Cảm ơn, tôi đã thay thế nó thành văn bản
ChelowekKot

55
  • hstore là một kiểu lưu trữ "cột rộng", nó là một từ điển phẳng (không lồng nhau) của các cặp khóa-giá trị, luôn được lưu trữ ở định dạng nhị phân hiệu quả hợp lý (bảng băm, do đó là tên).
  • jsonlưu trữ các tài liệu JSON dưới dạng văn bản, thực hiện xác nhận khi các tài liệu được lưu trữ và phân tích chúng trên đầu ra nếu cần (tức là truy cập các trường riêng lẻ); cần hỗ trợ toàn bộ thông số JSON. Vì toàn bộ văn bản JSON được lưu trữ, định dạng của nó được giữ nguyên.
  • jsonblấy các phím tắt vì lý do hiệu suất: Dữ liệu JSON được phân tích cú pháp trên đầu vào và được lưu trữ ở định dạng nhị phân, thứ tự khóa trong từ điển không được duy trì và cũng không phải là các khóa trùng lặp. Truy cập các phần tử riêng lẻ trong trường JSONB rất nhanh vì nó không yêu cầu phân tích văn bản JSON mọi lúc. Khi xuất ra, dữ liệu JSON được xây dựng lại và định dạng ban đầu bị mất.

IMO, không có lý do đáng kể cho việc không sử dụng jsonbmột khi nó có sẵn, nếu bạn đang làm việc với dữ liệu có thể đọc được bằng máy.


24

JSONB là phiên bản "tốt hơn" của JSON.

Hãy xem xét một ví dụ:

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 lưu trữ khoảng trắng, đó là lý do tại sao chúng ta có thể thấy khoảng trắng khi khóa "a" được lưu trữ, trong khi JSONB thì không.
  2. JSON lưu trữ tất cả các giá trị của khóa. Đây là lý do bạn có thể thấy nhiều giá trị (2 và 1) so với khóa "a", trong khi JSONB chỉ "lưu trữ" giá trị cuối cùng.
  3. JSON duy trì thứ tự các phần tử được chèn vào, trong khi JSONB duy trì thứ tự "được sắp xếp".
  4. Các đối tượng JSONB được lưu trữ dưới dạng nhị phân được giải nén trái ngược với "dữ liệu thô" trong JSON, trong đó không cần phải sửa lại dữ liệu trong quá trình truy xuất.
  5. JSONB cũng hỗ trợ lập chỉ mục, đây có thể là một lợi thế đáng kể.

Nói chung, người ta nên thích JSONB, trừ khi có các nhu cầu chuyên biệt, chẳng hạn như các giả định kế thừa về việc sắp xếp các khóa đối tượng.


13

Tôi đã ở pgopen ngày hôm nay điểm chuẩn nhanh hơn mongodb, tôi tin rằng nó nhanh hơn khoảng 500% cho các lựa chọn. Khá nhiều thứ đã nhanh hơn ít nhất 200% khi tương phản với mongodb, hơn một ngoại lệ ngay bây giờ là một bản cập nhật yêu cầu viết lại hoàn toàn toàn bộ cột json một cái gì đó mongodb xử lý tốt hơn.

Các chỉ số gin trên jsonb âm thanh tuyệt vời.

Ngoài ra, postgres sẽ duy trì các loại jsonb trong nội bộ và về cơ bản khớp với các loại như số, văn bản, boolean, v.v.

Tham gia cũng sẽ có thể sử dụng jsonb

Thêm PLv8 cho các thủ tục được lưu trữ và điều này về cơ bản sẽ trở thành giấc mơ đối với các nhà phát triển node.js.

Được lưu trữ dưới dạng nhị phân jsonb cũng sẽ loại bỏ tất cả các khoảng trắng, thay đổi thứ tự các thuộc tính và loại bỏ các thuộc tính trùng lặp bằng cách sử dụng lần xuất hiện cuối cùng của thuộc tính.

Bên cạnh chỉ mục khi truy vấn cột jsonb tương phản với cột postson, không thực sự phải chạy chức năng để chuyển đổi văn bản thành json trên mỗi hàng có thể sẽ tiết kiệm được một lượng lớn thời gian.


7

Về sự khác biệt giữa jsonjsonbkiểu dữ liệu, cần đề cập đến lời giải thích chính thức:

PostgreSQL cung cấp hai loại để lưu trữ dữ liệu JSON: jsonjsonb. Để thực hiện các cơ chế truy vấn hiệu quả cho các loại dữ liệu này, PostgreSQL cũng cung cấp loại dữ liệu jsonpath được mô tả trong Phần 8.14.6 .

Các kiểu dữ liệu jsonjsonbchấp nhận các bộ giá trị gần như giống hệt nhau làm đầu vào. Sự khác biệt thực tế chính là một trong những hiệu quả. Kiểu jsondữ liệu lưu trữ một bản sao chính xác của văn bản đầu vào, mà các hàm xử lý phải lặp lại trên mỗi lần thực hiện; trong khi jsonbdữ liệu được lưu trữ ở định dạng nhị phân phân tách khiến đầu vào chậm hơn một chút do chi phí chuyển đổi được thêm vào, nhưng xử lý nhanh hơn đáng kể, vì không cần phải xử lý lại.jsonbcũng hỗ trợ lập chỉ mục, có thể là một lợi thế đáng kể.

jsonloại lưu trữ một bản sao chính xác của văn bản đầu vào, nó sẽ duy trì khoảng trắng không đáng kể về mặt ngữ nghĩa giữa các mã thông báo, cũng như thứ tự các khóa trong các đối tượng JSON. Ngoài ra, nếu một đối tượng JSON trong giá trị chứa cùng một khóa nhiều lần, tất cả các cặp khóa / giá trị sẽ được giữ. (Các hàm xử lý coi giá trị cuối cùng là giá trị hoạt động.) Ngược lại,jsonb không bảo toàn khoảng trắng, không bảo toàn thứ tự của các khóa đối tượng và không giữ các khóa đối tượng trùng lặp. Nếu các khóa trùng lặp được chỉ định trong đầu vào, chỉ giữ giá trị cuối cùng.

Nói chung, hầu hết các ứng dụng nên lưu trữ dữ liệu JSON như jsonb , trừ khi có các nhu cầu khá chuyên biệt, chẳng hạn như các giả định cũ về việc sắp xếp các khóa đối tượng.

PostgreSQL chỉ cho phép mã hóa một ký tự cho mỗi cơ sở dữ liệu. Do đó, các loại JSON không thể tuân thủ cứng nhắc với đặc tả JSON trừ khi mã hóa cơ sở dữ liệu là UTF8. Nỗ lực bao gồm trực tiếp các ký tự không thể được trình bày trong mã hóa cơ sở dữ liệu sẽ thất bại; ngược lại, các ký tự có thể được biểu diễn trong mã hóa cơ sở dữ liệu nhưng không có trong UTF8 sẽ được cho phép.

Nguồn: https://www.postgresql.org/docs/cản/datatype-json.html


6

Theo như tôi có thể nói,

  • hstore như hiện tại tồn tại (trong Postgresql 9.3) không cho phép lồng các đối tượng và mảng khác như các giá trị của các cặp khóa / giá trị của nó. tuy nhiên một bản vá hstore trong tương lai sẽ cho phép lồng nhau. Bản vá này sẽ không có trong bản phát hành 9.4 và có thể không được đưa vào sớm.

  • json vì nó hiện đang tồn tại không cho phép lồng nhau, nhưng dựa trên văn bản và không cho phép lập chỉ mục, do đó nó "chậm"

  • jsonb sẽ được phát hành với 9.4 sẽ có khả năng lồng nhau hiện tại của json, cũng như lập chỉ mục GIN / GIST của hstore, vì vậy nó sẽ nhanh

Những người làm việc trên postgresql 9.4 dường như đang nói rằng loại jsonb mới, nhanh sẽ thu hút những người đã chọn sử dụng kho lưu trữ dữ liệu noQuery như MongoDB, nhưng giờ đây có thể kết hợp cơ sở dữ liệu quan hệ với dữ liệu phi cấu trúc có thể truy vấn dưới một mái nhà

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

Điểm chuẩn của postgresql 9,4 jsonb dường như ngang bằng hoặc trong một số trường hợp nhanh hơn MongoDB

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


6

Một sự khác biệt quan trọng khác, không được đề cập trong bất kỳ câu trả lời nào ở trên, đó là không có toán tử đẳng thức cho jsonloại, nhưng có một toán tử cho jsonb.

Điều này có nghĩa là bạn không thể sử dụng DISTINCTtừ khóa khi chọn jsonloại này và / hoặc các trường khác từ một bảng ( DISTINCT ONthay vào đó bạn có thể sử dụng , nhưng không phải lúc nào cũng có thể vì các trường hợp như thế này ).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.