PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Ein Überblick über die JSON-Funktionen in PostgreSQL

Was ist JSON?

JSON steht für „JavaScript Object Notation“, ein Datenformat, das häufig von Webanwendungen verwendet wird. Das heißt, die Daten würden in einem solchen Format zwischen Webanwendungen und Servern übertragen. JSON wurde als Alternative zum XML-Format eingeführt. In der „guten alten Zeit“ wurden die Daten im XML-Format übertragen, das im Vergleich zu JSON ein schwergewichtiger Datentyp ist. Unten sehen Sie ein Beispiel für eine JSON-formatierte Zeichenfolge:

{ "ID":"001","name": "Ven", "Country": "Australia",  "city": "Sydney", "Job Title":"Database Consultant"}

Ein JSON-String kann ein anderes JSON-Objekt in sich selbst enthalten, wie unten gezeigt:

{ "ID":"001", "name": "Ven", "Job Title":"Database Consultant", "Location":{"Suburb":"Dee Why","city": "Sydney","State":"NSW","Country": "Australia"}}

Moderne Web- und Mobilanwendungen generieren die Daten meist im JSON-Format, auch als „JSON-Bytes“ bezeichnet, die von den Anwendungsservern abgeholt und an die Datenbank gesendet werden. Die JSON-Bytes werden wiederum verarbeitet, in separate Spaltenwerte zerlegt und in eine RDBMS-Tabelle eingefügt.
Beispiel:

{ "ID":"001","name": "Ven", "Country": "Australia",  "city": "Sydney", "Job Title":"Database Consultant"}

Obige JSON-Daten werden wie unten in ein SQL konvertiert..

Insert into test (id, name, country,city,job_title) values  (001,'Ven','Australia','Sydney','Database Consultant');

Wenn es um die Speicherung und Verarbeitung der JSON-Daten geht, gibt es verschiedene NoSQL-Datenbanken, die dies unterstützen, und die beliebteste ist MongoDB. Bei RDBMS-Datenbanken wurden JSON-Strings bis vor kurzem als normaler Text behandelt, und es gab keine Datentypen, die speziell Strings im JSON-Format erkennen, speichern oder verarbeiten. PostgreSQL, die beliebteste Open-Source-RDBMS-Datenbank, hat den JSON-Datentyp entwickelt, der sich als äußerst vorteilhaft für die Leistung, Funktionalität und Skalierbarkeit bei der Verarbeitung von JSON-Daten erwiesen hat.

PostgreSQL + JSON

Seit der Einführung des JSON-Datentyps ist die PostgreSQL-Datenbank immer beliebter geworden. Tatsächlich hat PostgreSQL MongoDB übertroffen, wenn es um die Verarbeitung einer großen Menge an JSON-Daten geht. Die Anwendungen können JSON-Strings in der PostgreSQL-Datenbank im Standard-JSON-Format speichern. Entwickler müssen der Anwendung lediglich mitteilen, dass sie die JSON-Strings als JSON-Datentyp an die Datenbank senden und im JSON-Format abrufen soll. Das Speichern von JSON-Strings im JSON-Datentyp hat mehrere Vorteile im Vergleich zum Speichern derselben im TEXT-Datentyp. Der JSON-Datentyp kann nur gültige Zeichenfolgen im JSON-Format akzeptieren. Wenn die Zeichenfolge nicht im richtigen JSON-Format vorliegt, wird ein Fehler generiert. Der JSON-Datentyp hilft der Anwendung, effiziente und indexbasierte Suchen durchzuführen, die wir in Kürze im Detail sehen werden.

Der JSON-Datentyp wurde in PostgreSQL-9.2 eingeführt, in dem erhebliche Verbesserungen vorgenommen wurden. Die wichtigste Neuerung kam in PostgreSQL-9.4 mit der Hinzufügung des JSONB-Datentyps. JSONB ist eine erweiterte Version des JSON-Datentyps, der die JSON-Daten im Binärformat speichert. Dies ist die wichtigste Verbesserung, die einen großen Unterschied in der Art und Weise gemacht hat, wie JSON-Daten in PostgreSQL gesucht und verarbeitet wurden. Lassen Sie uns einen detaillierten Blick auf die Vorteile von JSON-Datentypen werfen.

JSON- und JSONB-Datentypen

Der JSON-Datentyp speichert Zeichenfolgen im JSON-Format als Text, der nicht sehr leistungsfähig ist und viele JSON-bezogene Funktionen, die für die Suche verwendet werden, nicht unterstützt. Es unterstützt nur die herkömmliche B-TREE-Indizierung und keine anderen Indextypen, die für schnellere und effizientere Suchvorgänge in JSON-Daten unerlässlich sind.

JSONB, die erweiterte Version des JSON-Datentyps, wird dringend zum Speichern und Verarbeiten von JSON-Dokumenten empfohlen. Es unterstützt eine breite Palette von JSON-Operatoren und hat zahlreiche Vorteile gegenüber JSON, wie das Speichern von JSON-formatierten Zeichenfolgen im Binärformat und die Unterstützung von JSON-Funktionen und -Indizierung, um effiziente Suchen durchzuführen.

Schauen wir uns die Unterschiede an.

  JSON JSONB
1 So ziemlich wie ein TEXT-Datentyp, der nur gültige JSON-Dokumente speichert. Speichert die JSON-Dokumente im Binärformat.
2 Speichert die JSON-Dokumente unverändert, einschließlich Leerzeichen. Entfernt Leerzeichen und speichert in einem Format, das schnellere und effizientere Suchen ermöglicht
3 Unterstützt keine VOLLTEXTSUCHE Indexierung Unterstützt VOLLTEXTSUCHE Indexierung
4 Unterstützt keine Vielzahl von JSON-Funktionen und -Operatoren Unterstützt alle JSON-Funktionen und -Operatoren

Beispiel für Nr. 4 oben aufgeführt

JSON

Unten ist eine Tabelle mit JSON-Datentyp

dbt3=# \d product
                   Table "dbt3.product"
     Column     |  Type  | Collation | Nullable | Default
----------------+--------+-----------+----------+---------
 item_code      | bigint |           | not null |
 productdetails | json   |           |          |
Indexes:
    "product_pkey" PRIMARY KEY, btree (item_code)

Unterstützt keine herkömmlichen JSON-Operatoren (wie „@>“ oder „#>“). Die Volltextsuche durch JSON-Daten erfolgt mit „@>“ oder „#>“ in einer SQL, die nicht vom JSON-Datentyp unterstützt wird

dbt3=# select * from product where productdetails @> '{"l_shipmode":"AIR"}' and productdetails @> '{"l_quantity":"27"}';
ERROR:  operator does not exist: json @> unknown
LINE 1: select * from product where productdetails @> '{"l_shipmode"...
                                                   ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
dbt3=#

JSONB

Nachfolgend finden Sie eine Tabelle mit dem Datentyp JSONB

dbt3=# \d products
                  Table "dbt3.products"
    Column     |  Type  | Collation | Nullable | Default
---------------+--------+-----------+----------+---------
 item_code     | bigint |           | not null |
 order_details | jsonb  |           |          |
Indexes:
    "products_pkey" PRIMARY KEY, btree (item_code)

Unterstützt VOLLTEXTSUCHE durch JSON-Daten mit Operatoren (wie „@>“)

dbt3=# select * from products where order_details @> '{"l_shipmode" : "AIR"}' limit 2;
 item_code |                                                                                        order_details
-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         4 | {"l_partkey": 21315, "l_orderkey": 1, "l_quantity": 28, "l_shipdate": "1996-04-21", "l_shipmode": "AIR", "l_commitdate": "1996-03-30", "l_shipinstruct": "NONE", "l_extendedprice": 34616.7}
         8 | {"l_partkey": 42970, "l_orderkey": 3, "l_quantity": 45, "l_shipdate": "1994-02-02", "l_shipmode": "AIR", "l_commitdate": "1994-01-04", "l_shipinstruct": "NONE", "l_extendedprice": 86083.6}
(2 rows)
Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunter

So fragen Sie JSON-Daten ab

Werfen wir einen Blick auf einige JSON-Funktionen von PostgreSQL im Zusammenhang mit Datenoperationen. Nachfolgend sehen Sie, wie die JSON-Daten in einer Tabelle aussehen. Die Spalte „order_details“ ist vom Typ JSONB

dbt3=# select * from product_details ;
 item_code |                                                                                                 order_details
-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         1 | {"l_partkey": 1551894, "l_orderkey": 1, "l_quantity": 17, "l_shipdate": "1996-03-13", "l_shipmode": "TRUCK", "l_commitdate": "1996-02-12", "l_shipinstruct": "DELIVER IN PERSON", "l_extendedprice": 33078.9}
         2 | {"l_partkey": 673091, "l_orderkey": 1, "l_quantity": 36, "l_shipdate": "1996-04-12", "l_shipmode": "MAIL", "l_commitdate": "1996-02-28", "l_shipinstruct": "TAKE BACK RETURN", "l_extendedprice": 38306.2}
         3 | {"l_partkey": 636998, "l_orderkey": 1, "l_quantity": 8, "l_shipdate": "1996-01-29", "l_shipmode": "REG AIR", "l_commitdate": "1996-03-05", "l_shipinstruct": "TAKE BACK RETURN", "l_extendedprice": 15479.7}
         4 | {"l_partkey": 21315, "l_orderkey": 1, "l_quantity": 28, "l_shipdate": "1996-04-21", "l_shipmode": "AIR", "l_commitdate": "1996-03-30", "l_shipinstruct": "NONE", "l_extendedprice": 34616.7}
         5 | {"l_partkey": 240267, "l_orderkey": 1, "l_quantity": 24, "l_shipdate": "1996-03-30", "l_shipmode": "FOB", "l_commitdate": "1996-03-14", "l_shipinstruct": "NONE", "l_extendedprice": 28974}
         6 | {"l_partkey": 156345, "l_orderkey": 1, "l_quantity": 32, "l_shipdate": "1996-01-30", "l_shipmode": "MAIL", "l_commitdate": "1996-02-07", "l_shipinstruct": "DELIVER IN PERSON", "l_extendedprice": 44842.9}
         7 | {"l_partkey": 1061698, "l_orderkey": 2, "l_quantity": 38, "l_shipdate": "1997-01-28", "l_shipmode": "RAIL", "l_commitdate": "1997-01-14", "l_shipinstruct": "TAKE BACK RETURN", "l_extendedprice": 63066.3}
         8 | {"l_partkey": 42970, "l_orderkey": 3, "l_quantity": 45, "l_shipdate": "1994-02-02", "l_shipmode": "AIR", "l_commitdate": "1994-01-04", "l_shipinstruct": "NONE", "l_extendedprice": 86083.6}
         9 | {"l_partkey": 190355, "l_orderkey": 3, "l_quantity": 49, "l_shipdate": "1993-11-09", "l_shipmode": "RAIL", "l_commitdate": "1993-12-20", "l_shipinstruct": "TAKE BACK RETURN", "l_extendedprice": 70822.1}
        10 | {"l_partkey": 1284483, "l_orderkey": 3, "l_quantity": 27, "l_shipdate": "1994-01-16", "l_shipmode": "SHIP", "l_commitdate": "1993-11-22", "l_shipinstruct": "DELIVER IN PERSON", "l_extendedprice": 39620.3}
(10 rows)

Wählen Sie alle Artikelcodes einschließlich ihrer Versanddaten aus

dbt3=# select item_code, order_details->'l_shipdate' as shipment_date from product_details ;

 item_code | shipment_date
-----------+---------------
         1 | "1996-03-13"
         2 | "1996-04-12"
         3 | "1996-01-29"
         4 | "1996-04-21"
         5 | "1996-03-30"
         6 | "1996-01-30"
         7 | "1997-01-28"
         8 | "1994-02-02"
         9 | "1993-11-09"
        10 | "1994-01-16"
(10 rows)

Holen Sie sich den item_code, die Menge und den Preis aller Bestellungen, die auf dem Luftweg eingetroffen sind

dbt3=# select item_code, order_details->'l_quantity' as quantity, order_details->'l_extendedprice' as price, order_details->'l_shipmode' as price from product_details where order_details->>'l_shipmode'='AIR';

 item_code | quantity |  price  | price
-----------+----------+---------+-------
         4 | 28       | 34616.7 | "AIR"
         8 | 45       | 86083.6 | "AIR"
(2 rows)

Die JSON-Operatoren „->“ und „->>“ werden für Selektionen und Vergleiche in der SQL-Abfrage verwendet. Der Operator „->“ gibt das JSON-Objektfeld als Feld in Anführungszeichen zurück, und der Operator „->>“ gibt das JSON-Objektfeld als TEXT zurück. Die beiden obigen SQLs sind Beispiele für die unveränderte Anzeige von JSON-Feldwerten. Unten sehen Sie ein Beispiel für das Extrahieren des JSON-Felds im TEXT-Formular.
Unten sehen Sie ein Beispiel für das Abrufen des JSON-Felds im TEXT-Format

dbt3=# select item_code, order_details->>'l_shipdate' as shipment_date from product_details ;
 item_code | shipment_date
-----------+---------------
         1 | 1996-03-13
         2 | 1996-04-12
         3 | 1996-01-29
         4 | 1996-04-21
         5 | 1996-03-30
         6 | 1996-01-30
         7 | 1997-01-28
         8 | 1994-02-02
         9 | 1993-11-09
        10 | 1994-01-16
(10 rows)

Es gibt einen weiteren Operator namens „#>“, der verwendet wird, um den Datenteil eines JSON-Elements abzufragen, das wiederum Teil eines JSON-Strings ist. Sehen wir uns ein Beispiel an.
Unten sind die Daten in der Tabelle.

dbt3=# select * from test_json ;
  id   |                                                                                                details
-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 10000 | {"Job": "Database Consultant", "name": "Venkata", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Dee Why", "Country": "Australia"}}
 20000 | {"Job": "Database Consultant", "name": "Smith", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Manly", "Country": "Australia"}}
 30000 | {"Job": "Developer", "name": "John", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Brookvale", "Country": "Australia"}}
 50000 | {"cars": {"Ford": [{"doors": 4, "model": "Taurus"}, {"doors": 4, "model": "Escort"}], "Nissan": [{"doors": 4, "model": "Sentra"}, {"doors": 4, "model": "Maxima"}, {"doors": 2, "model": "Skyline"}]}}
 40000 | {"Job": "Architect", "name": "James", "Location": {"city": "Melbourne", "State": "NSW", "Suburb": "Trugnania", "Country": "Australia"}}

Ich möchte alle Details mit „State“ „NSW“ sehen und „State“ ist der JSON-Objektschlüssel, der Teil des Schlüssels „Location“ ist. Unten erfahren Sie, wie Sie dasselbe abfragen.

dbt3=# select * from test_json where details #> '{Location,State}'='"NSW"';
  id   |                                                                    details
-------+------------------------------------------------------------------------------------------------------------------------------------------------
 10000 | {"Job": "Database Consultant", "name": "Venkata", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Dee Why", "Country": "Australia"}}
 20000 | {"Job": "Database Consultant", "name": "Smith", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Manly", "Country": "Australia"}}
 30000 | {"Job": "Developer", "name": "John", "Location": {"city": "Sydney", "State": "NSW", "Suburb": "Brookvale", "Country": "Australia"}}
 30000 | {"Job": "Architect", "name": "James", "Location": {"city": "Melbourne", "State": "NSW", "Suburb": "Trugnania", "Country": "Australia"}}
(4 rows)

Arithmetische Operationen können mit JSON-Daten durchgeführt werden. Type Casting ist erforderlich, da der Datenteil der JSON-Spalte TEXT ist.

dbt3=# select item_code, order_details->'l_quantity' as quantity, order_details->'l_extendedprice' as price, order_details->'l_shipmode' as price from product_details where (order_details->'l_quantity')::int > 10;
 item_code | quantity |  price  |  price
-----------+----------+---------+---------
         1 | 17       | 33078.9 | "TRUCK"
         2 | 36       | 38306.2 | "MAIL"
         4 | 28       | 34616.7 | "AIR"
         5 | 24       | 28974   | "FOB"
         6 | 32       | 44842.9 | "MAIL"
         7 | 38       | 63066.3 | "RAIL"
         8 | 45       | 86083.6 | "AIR"
         9 | 49       | 70822.1 | "RAIL"
        10 | 27       | 39620.3 | "SHIP"
(9 rows)

Abgesehen von all dem oben genannten können die folgenden Operationen auch auf JSON mit SQLs einschließlich JOINs ausgeführt werden

  1. Sortieren der Daten mit der ORDER BY-Klausel
  2. Aggregation unter Verwendung von Aggregatfunktionen wie SUM, AVG, MIN, MAX usw.
  3. Gruppieren Sie die Daten mit der GROUP BY-Klausel

Wie sieht es mit der Leistung aus?

Die Daten in JSON-Spalten sind Text und aufgrund der Datengröße sind Leistungsprobleme zu erwarten. Das Durchsuchen von JSON-Daten kann Zeit und Rechenleistung in Anspruch nehmen, was zu langsamen Antworten auf die Anwendung(en) führt. DBAs müssen unbedingt sicherstellen, dass SQLs, die auf die JSON-Spalten zugreifen, schnell genug reagieren und eine gute Leistung erbringen. Da die Datenextraktion über SQL erfolgt, ist die Option, nach der die DBAs suchen würden, die Möglichkeit der Indizierung, und ja, JSON-Datentypen unterstützen Indizierungsoptionen.

Werfen wir einen Blick auf die Indizierungsoptionen, die JSON uns bietet.

Indizierung von JSONB

Der JSONB-Datentyp unterstützt die FULL-TEXT-SEARCH-Indizierung. Dies ist die wichtigste Funktion von JSONB, auf die sich DBAs freuen werden, wenn sie JSONB-Datentypen verwenden. Ein normaler Index für einen JSON-Objektschlüssel hilft möglicherweise nicht, wenn JSON-spezifische Operatoren in den Suchabfragen verwendet werden. Nachfolgend finden Sie eine TEXT SEARCH-Abfrage, die für einen FULL-TABLE-SCAN gilt

dbt3=# explain select * from products where order_details @> '{"l_shipmode" : "AIR"}';
                             QUERY PLAN
--------------------------------------------------------------------
 Seq Scan on products  (cost=0.00..4205822.65 rows=59986 width=252)
   Filter: (order_details @> '{"l_shipmode": "AIR"}'::jsonb)
(2 rows)

JSONB unterstützt den VOLLTEXT-SUCHE-Indextyp namens GIN, der Abfragen wie oben hilft.
Lassen Sie mich jetzt einen GIN-Index erstellen und sehen, ob das hilft

dbt3=# create index od_gin_idx on products using gin(order_details jsonb_path_ops);
CREATE INDEX

Wie Sie unten sehen können, erfasst die Abfrage den GIN-Index

dbt3=# explain select * from products where order_details @> '{"l_shipmode" : "AIR"}';
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Bitmap Heap Scan on products  (cost=576.89..215803.18 rows=59986 width=252)
   Recheck Cond: (order_details @> '{"l_shipmode": "AIR"}'::jsonb)
   ->  Bitmap Index Scan on od_gin_idx  (cost=0.00..561.90 rows=59986 width=0)
         Index Cond: (order_details @> '{"l_shipmode": "AIR"}'::jsonb)

Und ein B-TREE-Index statt GIN würde NICHT helfen

dbt3=# create index idx on products((order_details->>'l_shipmode'));
CREATE INDEX

dbt3=# \d products
                  Table "dbt3.products"
    Column     |  Type  | Collation | Nullable | Default
---------------+--------+-----------+----------+---------
 item_code     | bigint |           | not null |
 order_details | jsonb  |           |          |
Indexes:
    "products_pkey" PRIMARY KEY, btree (item_code)
    "idx" btree ((order_details ->> 'l_shipmode'::text))

Wie Sie unten sehen können, bevorzugt die Abfrage FULL-TABLE-SCAN

dbt3=# explain select * from products where order_details @> '{"l_shipmode" : "AIR"}';
                             QUERY PLAN
--------------------------------------------------------------------
 Seq Scan on products  (cost=0.00..4205822.65 rows=59986 width=252)
   Filter: (order_details @> '{"l_shipmode": "AIR"}'::jsonb)

Was ist der GIN-Index?

GIN steht für Generalized Inverted Index. Die Kernfunktion von GIN Index ist die Beschleunigung der Volltextsuche. Wenn Sie eine Suche basierend auf bestimmten Schlüsseln oder Elementen in einem TEXT oder einem Dokument durchführen, ist GIN Index der richtige Weg. Der GIN-Index speichert „Schlüssel“ (oder ein Element oder einen Wert) und die „Positionsliste“-Paare. Die Positionsliste ist die rowID des Schlüssels. Das heißt, wenn der „Schlüssel“ an mehreren Stellen im Dokument vorkommt, speichert GIN Index den Schlüssel nur einmal zusammen mit seiner Position des Vorkommens, was nicht nur den GIN-Index kompakt in der Größe hält, sondern auch dazu beiträgt, die Suche in einem großen zu beschleunigen Weg. Dies ist die Verbesserung in Postgres-9.4.

Herausforderungen mit GIN Index

Je nach Komplexität der Daten kann die Pflege von GIN-Indizes teuer werden. Die Erstellung von GIN-Indizes verbraucht Zeit und Ressourcen, da der Index das gesamte Dokument durchsuchen muss, um die Schlüssel und ihre Zeilen-IDs zu finden. Noch schwieriger kann es werden, wenn der GIN-Index aufgebläht ist. Außerdem kann die Größe des GIN-Index basierend auf der Datengröße und -komplexität sehr groß sein.

Indizieren von JSON

JSON unterstützt keine Textsuche und Indizes wie GIN

dbt3=# create index pd_gin_idx on product using gin(productdetails jsonb_path_ops);
ERROR:  operator class "jsonb_path_ops" does not accept data type json

Normale Indizierung wie B-TREE wird sowohl von JSON als auch von JSONB unterstützt

Ja, normale Indizes wie der B-TREE-Index werden sowohl von JSON- als auch von JSONB-Datentypen unterstützt und sind für Textsuchvorgänge nicht förderlich. Jeder JSON-Objektschlüssel kann einzeln indiziert werden, was NUR dann wirklich hilfreich wäre, wenn derselbe Objektschlüssel in der WHERE-Klausel verwendet wird.
Lassen Sie mich einen B-TREE-Index für JSONB erstellen und sehen, wie er funktioniert

dbt3=# create index idx on products((order_details->>'l_shipmode'));
CREATE INDEX

dbt3=# \d products
                  Table "dbt3.products"
    Column     |  Type  | Collation | Nullable | Default
---------------+--------+-----------+----------+---------
 item_code     | bigint |           | not null |
 order_details | jsonb  |           |          |
Indexes:
    "products_pkey" PRIMARY KEY, btree (item_code)
    "idx" btree ((order_details ->> 'l_shipmode'::text))

Wir haben bereits oben gelernt, dass ein B-TREE-Index NICHT nützlich ist, um SQLs zu beschleunigen, die eine VOLLTEXT-SUCHE in den JSON-Daten mit Operatoren (wie „@>“) durchführen, und solche Indizes würden NUR dazu beitragen, die Abfragen wie zu beschleunigen die unten, die typische RDBMS-Typ-SQLs sind (die keine Suchanfragen sind). Jeder der JSON-Objektschlüssel kann einzeln indiziert werden, was dazu beitragen würde, Abfragen zu beschleunigen, wenn diese indizierten JSON-Objektschlüssel in der WHERE-Klausel verwendet werden.
Das Beispiel unten verwendet den Objektschlüssel „l_shipmode“ in der WHERE-Klausel und seitdem Es ist indiziert, die Abfrage wird für einen Index-Scan verwendet. Wenn Sie mit einem anderen Objektschlüssel suchen möchten, würde die Abfrage einen FULL-TABLE-SCAN wählen.

dbt3=# explain select * from products where order_details->>'l_shipmode'='AIR';
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Index Scan using idx on products  (cost=0.56..1158369.34 rows=299930 width=252)
   Index Cond: ((order_details ->> 'l_shipmode'::text) = 'AIR'::text)

Das Gleiche funktioniert auch mit dem JSON-Datentyp

dbt3=# create index idx on products((order_details->>'l_shipmode'));
CREATE INDEX

dbt3=# \d products
                  Table "dbt3.products"
    Column     |  Type  | Collation | Nullable | Default
---------------+--------+-----------+----------+---------
 item_code     | bigint |           | not null |
 order_details | json  |           |          |
Indexes:
    "products_pkey" PRIMARY KEY, btree (item_code)
    "idx" btree ((order_details ->> 'l_shipmode'::text))

Wie Sie sehen können, verwendet die Abfrage den Index

dbt3=# explain select * from products where order_details->>'l_shipmode'='AIR';
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Index Scan using idx on products  (cost=0.56..1158369.34 rows=299930 width=252)
   Index Cond: ((order_details ->> 'l_shipmode'::text) = 'AIR'::text)

Schlussfolgerung

Hier sind einige Dinge, die Sie bei der Verwendung von PostgreSQL-JSON-Daten beachten sollten...

  • PostgreSQL ist eine der besten Optionen zum Speichern und Verarbeiten von JSON-Daten
  • Mit all den leistungsstarken Funktionen kann PostgreSQL Ihre Dokumentendatenbank sein
  • Ich habe Architekturen gesehen, bei denen zwei oder mehr Datenspeicher ausgewählt wurden, mit einer Mischung aus PostgreSQL- und NoSQL-Datenbanken wie MongoDB oder Couchbase-Datenbank. Eine REST-API würde Anwendungen helfen, die Daten in verschiedene Datenspeicher zu verschieben. Da PostgreSQL JSON unterstützt, kann diese Komplexität in der Architektur vermieden werden, indem nur ein Datenspeicher ausgewählt wird.
  • JSON-Daten in PostgreSQL können abgefragt und indiziert werden, was zu einer unglaublichen Leistung und Skalierbarkeit führt
  • Der JSONB-Datentyp ist die am meisten bevorzugte Option, da er gut in Speicher und Leistung ist. Unterstützt VOLLTEXTSUCHE und Indizierung vollständig. Liefert gute Leistung
  • Verwenden Sie den JSON-Datentyp nur, wenn Sie JSON-Strings als JSON speichern möchten und keine sehr komplexen Textsuchen durchführen
  • Der größte Vorteil von JSON in PostgreSQL ist, dass die Suche mit SQLs durchgeführt werden kann
  • Die JSON-Suchleistung in PostgreSQL war mit den besten NoSQL-Datenbanken wie MongoDB vergleichbar