2014-12-30 16 views
7

Ich suche mit PostgreSQL jsonb Spaltentyp für ein neues Back-End-Projekt, das hauptsächlich als REST-ful JSON API dienen wird. Ich glaube, dass PostgreSQLs jsonb eine gute Passung für dieses Projekt sein wird, da es mir JSON-Objekte geben wird, ohne dass eine Konvertierung auf dem Backend erforderlich ist.JSONB und primäre/Fremdschlüssel: welche besser in PostgreSQL führt?

Ich habe jedoch gelesen, dass der jsonb-Datentyp verlangsamt, wenn Schlüssel hinzugefügt werden, und mein Schema muss Primärschlüssel und Fremdschlüsselverweise verwenden.

Ich frage mich, ob Primärschlüssel/Fremdschlüssel in ihren eigenen Spalten (in der Standard-relationalen Datenbank Weg) und dann eine jsonb Spalte für den Rest der Daten wäre vorteilhaft, oder würde dies Probleme verursachen (ob jetzt oder die Straße hinunter)?

Kurz gesagt würde:

table car(id int, manufacturer_id int, data jsonb) 

durchführen besser oder schlechter als:

table car(data jsonb) 

Vor allem, wenn häufig Fremdschlüssel aufzublicken?
Wäre es aus der Perspektive der Performance oder des Schemas Nachteile für den ersten?

+0

Warum möchten Sie 'jsonb' überhaupt verwenden? Klingt so, als ob Sie ein mehr oder weniger festes Schema haben und das Konvertieren von Zeilen in JSON sollte schnell genug sein, damit Sie sich keine Sorgen machen müssen. –

+0

Gute Frage: Ich habe eine gute Vorstellung von den Beziehungen, die mein Schema benötigt, aber zu diesem Zeitpunkt habe ich kein konkretes Verständnis der Informationen, die jede Tabelle benötigt, und ich konnte jedes Mal Datenbankmigrationen durchführen Ich denke, dass ich mit jsonb eine gute Leistung zusammen mit einer einfachen Möglichkeit, Dinge schnell hinzuzufügen, würde. Vielleicht kann ich später, wenn ich ein konkreteres Verständnis der benötigten Daten habe, zu einem guten Beziehungsaufbau zurückkehren. Aber das ist neben der Frage, die lautet: Leistet man besser/schlechter als die andere? –

+1

Aber du wirst sowieso eine Reihe von Migrationen machen müssen, um dein JSON neu zu schreiben, ein paar ALTER TABLEs hier und dort sollte nicht beängstigend sein und wenn sie dann all deine Daten und Code neu schreiben um ein sich ständig änderndes Schema zu verfolgen beängstigender sein. Was die Beantwortung der Frage betrifft, müssen Sie zuerst die richtige Frage stellen. Ich denke, Sie müssen herausfinden, wie Ihre Daten aussehen, bevor Sie beginnen, Daten herumzuschleppen. Wenn du denkst, dass du es flügelst und dann zurück gehst und die Datenbank neu entwirfst, ist es fast sicher falsch, wird es nicht passieren. –

Antwort

12

Alle beteiligten Werte in einer PRIMARY KEY oder FOREIGN KEY Einschränkung muss als dedizierte Spalten gespeichert werden (in normierter Form am besten). Constraints und Referenzen funktionieren nicht für verschachtelte Werte innerhalb eine json/jsonb Spalte.

Wie für den Rest der Daten: es hängt. Wenn Sie sie innerhalb eines (vorzugsweise) Werts haben, trägt sie die bekannten Vor- und Nachteile des Speicherns unstrukturierter Daten vom Typ Dokument.

Für Attribute, die für alle oder die meisten Zeilen vorhanden sind, ist es wahrscheinlich besser (schneller, sauberer, kleinerer Speicher), sie als separate Spalten zu speichern. Einfachere Indizierung und einfachere Abfragen. Auch wenn das neue jsonbamazing index capabilities hat, ist die Indexierung dedizierter Spalten noch einfacher/schneller.

Für selten verwendete oder dynamisch erscheinende Attribute oder wenn Sie JSON-Werte speichern und abrufen möchten, ohne viel in der Datenbank zu arbeiten, schauen Sie auf jsonb.

Für grundlegende EAV structures mit hauptsächlich Zeichendaten, ohne Verschachtelung und keine Verbindung zu JSON würde ich hstore betrachten. Es gibt auch die xml (komplexere und ausführliche) und json Datentypen (meist ersetzt durch jsonb), die an Boden verlieren.

+1

Yup ... "es kommt darauf an". Ein Problem, das hier nicht behandelt wird, ist, dass wenn Sie * irgendein * Unterfeld eines jsonb-Wertes aktualisieren, das * ganze Tupel * neu geschrieben werden muss und alle/alle auf es zeigenden Indizes aktualisiert werden müssen.Wenn Sie Ihre Daten in Entitäten mit pk/fk-Beziehungen zerlegt haben, ist dies nicht mehr der Fall, Sie können nur Teile davon einfügen/aktualisieren/löschen, ohne das Ganze neu schreiben zu müssen. –

+0

@CraigRinger Stimmt das noch in Postgres 9.5? Ich frage nach dem Lesen dieses Abschnitts in den Release-Dokumenten https://wiki.postgresql.org/wiki/What_new_in_PostgreSQL_9.5#JSONB-modifying_operators_and_functions – t1m0

+3

@ t1m0 Ja. Es ist dem TOAST-Out-of-Line-Speicher und MVCC inhärent. PostgreSQL kann jetzt ein Jsonb-Objekt modifizieren, ohne es vollständig dekonstruieren und rekonstruieren zu müssen, aber das ist eine In-Memory-Modifikation. Es muss das Ganze noch von der Platte lesen und es muss immer noch die ganze neue modifizierte Version auf das neue Tupel schreiben. –

2

Welche Leistung besser? Hängt von der Verwendung ab. Es ist dieselbe Frage, wenn Sie SQL (relational) und NoSQL (KeyValue oder Document) Datenbanken vergleichen. Für einige Anwendungsfälle schneidet eine NoSQL-Datenbank sehr gut ab, für andere nicht.

Relational Konzept (normalisiertes Schema) ist für typische OLTP-Nutzung optimiert - 70% lesen/30% schreiben, Multiuser, viele Updates, Bericht berechnen, einige Ad-hoc-Abfragen. Relationales Konzept ist relativ allgemein.mit sehr breiter Verwendbarkeit (Beweis, Buchhaltung, Verarbeitungsunterstützung, ...). Normalerweise ist es nicht überall so schlecht.

Es ist klar, so spezialisierte Datenbanken (Document, KeyValue, Graph) können deutlich besser (eine Bestellung schneller) in spezialisierten Anwendungsfällen sein. Aber ihre Verwendung ist deutlich enger. Wenn Sie nicht mehr im optimierten Anwendungsfall sind, kann die Leistung schlecht sein.

Andere Frage ist Datenbankgröße - Rekordzahlen. Der Leistungsunterschied in Produktionsdatenbanken kann in hunderttausend Zeilen signifikant sein. Bei einigen kleineren Datenbanken kann die Auswirkung nicht signifikant sein.

Postgres ist relationale Datenbank und meine Präferenz ist es, ein normalisiertes Schema für alle wichtigen Daten in der Datenbank zu verwenden. Wenn man es gut benutzt, ist es furchtbar schnell. Nicht-Relationstypen sind perfekt für einige unscharfe Daten (HStore, JSON, XML, Jsonb) - es ist signifikant besser als das EAV-Schema (schlechter bei größeren Daten).

Wenn Sie eine wichtige Entscheidung treffen müssen, bereiten Sie den Prototyp vor, füllen Sie ihn für die erwarteten Daten (3 Jahre) und überprüfen Sie die Geschwindigkeit einiger wichtiger Abfragen für Ihr System. Achtung: starke Auswirkungen auf diese Benchmarks hat verwendet hw, aktuelle Belastung, Strom sw.

Verwandte Themen