Wie können schemalose Daten effizient in einer relationalen Datenbank gespeichert werden?

7

Ich versuche ein gutes Gleichgewicht zwischen Suchbarkeit und Geschwindigkeit zu finden. Ich experimentiere mit verschiedenen Methoden.

Option 1: Serialisieren Sie das Array als serialisiertes JSON / PHP-Array und speichern Sie es in einer 'Meta'-Spalte.

   id  |  name   | meta  
1       Bob       {"city":"GoTown","birthdate":"1980\/8\/14","cat":"Felix"}
2       Alice     {"city":"Streamville","birthdate":"1986\/6\/6","dog":"Rex"}

Option 2: Speichern Sie Schlüssel und Werte zusammen in einem Stapel.

user_id  |    key   |   value   
1         name       Bob
1         city       GoTown
1         birthdate  1980/8/14
1         cat        Felix
2         name       Alice
2         city       Streamville
2         birthdate  1986/6/6
2         dog        Rex

Option 3: 3 Tabellen: Entites, Schlüssel, Werte. Speichern Sie jeden Schlüsselnamen nur einmal.

user_id  |   name   
1         Bob
2         Alice

key_id   |   keyname   
1         city
2         birthdate
3         cat
4         dog

user_id   |   key_id   |   value
1          1            GoTown
1          2            1980/8/14
1          3            Felix
2          1            Streamville
2          2            1986/6/6
2          4            Rex

Gibt es Fallstricke bei der Verwendung einer dieser Strategien? Ich möchte einige von ihnen beseitigen, wenn sie unüberwindbare Nachteile haben.

BEARBEITEN: Einige Daten wurden hinzugefügt, um schemalose Daten darzustellen

techturbulence
quelle

Antworten:

3

Mit diesen Tabellen würden einige wirklich schlimme Probleme auftreten (Idee)

  1. Datenredundanz (duplizierte Daten) Was müssen Sie synchronisieren (und überprüfen Sie dies, weil MySQL keine nette JSON-to-Records-Funktion hat?)

  2. Sie können der Datenbank keine korrekten Werte aufzwingen (verabschieden Sie sich von der Datenintegrität und begrüßen Sie die Müll-in-Müll-out-Daten). Das Geburtsdatum des Beispielschlüssels könnte den Wert "Hallo" haben.

Und Sie benötigen eine Art Pivot-Abfrage, um den Schlüssel / die Werte abzurufen

Wenn Sie wirklich EAV-Speicher (Dynamic Key Values) benötigen, gibt es einige weitere Optionen:

Raymond Nijland
quelle
3

Angesichts Ihrer Anforderungen (MySQL und "schemalos") könnte es sich lohnen, Option 1 mit einem Twist in Betracht zu ziehen. Betrachten Sie XML anstelle von JSON.

Warum? Weil MySQL Ihnen keine einfache Möglichkeit bietet, JSON zu verarbeiten, aber es funktioniert mit XML.

Bedenken Sie:

id  |  name   | meta  
1      Bob      <city>GoTown</city><birthdate>1980-08-14&</birthdate>
2      Alice    <city>Streamville</city><birthdate>1986-06-06<birthdate>

Jetzt können Sie eine SQL-Abfrage mit xpath-Ausdrücken für den Inhalt des Metafelds durchführen. Wie so:

SELECT name, extractValue( meta, '//birthdate' ) as birthdate
from tbl

Sie können sogar basierend auf der Stadt eine Auswahl treffen (was natürlich SEHR ineffizient ist, da sie den Inhalt der Felder analysieren müssen, die mit der where-Klausel übereinstimmen, aber:

SELECT name<BR>
from tbl<br>
where id < 100
having extractValue( meta, '//city' ) = 'Streamille'

Sie können sogar UpdateXML (eine andere MySQL-Funktion) verwenden, um Änderungen am Inhalt Ihres Feldes in MySQL vorzunehmen.

Obwohl ich weiß, dass meine Antwort zu spät ist, hoffe ich, dass jemand dies nützlich / interessant findet. :) :)

Wendell Brown
quelle
3

Aus Ihren Beispieldaten sehe ich tatsächlich ein Schema für die Tabelle

UserID | UserName | City | Birthdate

Wenn Sie eine relationale Datenbank mit der richtigen Indizierung verwenden, ist eine Suche sehr schnell. Wenn einige Werte null sein könnten, lassen Sie nullfähige Spalten zu.

Ein Schlüsselwertspeicher ist in Situationen großartig, kann jedoch bei der Datenvalidierung sehr umständlich werden. Wenn Sie ein relationales Datenbankprodukt verwenden, setzen Sie es ein und lassen Sie es die Validierung auf der Eingabeseite mit richtig typisierten Spalten durchführen.

Wenn Sie wirklich einen Schlüsselwertspeicher verwenden möchten, ist ein für sie optimiertes NoSQL-Produkt wahrscheinlich der bessere Weg.

RubberChickenLeader
quelle
2

Antwort des Community-Wikis :

Postgres bietet viel mehr NoSQL-Funktionen als MySQL. Die JSON-Implementierung ist viel effizienter (Sie können JSON-Dokumente indizieren) und verfügt über einen sehr effizienten Schlüssel- / Wertspeicher (auch indizierbar). Postgres ist wahrscheinlich die fortschrittlichste "relationale NoSQL-Datenbank".

user126897
quelle
1

Wenn Sie möglicherweise alle Kunden mit Geburtstag zwischen 08/10 und 08/17 suchen müssen, ist Option 1 nicht geeignet.

Die Optionen 2 und 3 sind ähnlich. Persönlich bevorzuge ich Option 3, weil ich lieber nach Ganzzahlcodes als nach Texten suchen oder gruppieren möchte.

Und nebenbei. Ich empfehle, Monate und Tage als 2 Zahlen zu speichern. Dann können Sie sie als Zeichenfolgen sortieren und es wird immer noch korrekt sein: 1970/10/10 wird nach 1970/08/08 sein, aber es würde vor 1970/8/8 sein.

Alex
quelle
Netter Tipp mit dem Datum, WENN Sie gezwungen sind, ein von Menschen lesbares Datum zu speichern - normalerweise ist es besser, Unixtime in DB zu verwenden, wie von @capnhector erwähnt.
Techturbulence
1

Wenn Sie sich nicht für die Verwendung von MySQL entschieden haben, können Sie DB2 als Option in Betracht ziehen. Es bietet native Unterstützung für JSON-Daten, mit denen Sie JSON-Fragmente einfach abfragen und bearbeiten können ( http://publib.boulder.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.swg.im.dbclient.json) .doc / doc / c0061316.html ).

Eine andere Alternative ist XML. Auch hier bietet DB2 native Unterstützung, einschließlich der Indizierung von XPath-Ausdrücken für die schnelle Suche. ( http://publib.boulder.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.xml.doc/doc/c0022308.html )

DB2 Express-C ist die kostenlose Edition ohne Einschränkung der Produktionsnutzung oder der Datenbankgröße.

mustaccio
quelle
1

Sie können jsonDaten auch in MySQL speichern . MySQL 5.7 unterstützt jsonDaten nativ .

Siehe mysql json-Datentyp

Saurabh Chandra Patel
quelle
-1

Haben Sie NoSQL in Betracht gezogen?

Da ich für einen NoSQL-Anbieter arbeite, bin ich ein bisschen parteiisch, aber ich habe versucht, Ihre Problemdefinition zu übernehmen und sie aus einer Perspektive der besten Technologie zu betrachten. Diese Beschreibung ist ideal für NoSQL, da sie unstrukturierte Daten unterstützt und alle von Ihnen freigegebenen Optionen in NoSQL ausgeführt werden können. Meiner Meinung nach ist Option 3 ziemlich attraktiv, da Sie diese Tabellen in minimaler Zeit erstellen und damit fertig werden können. Und wenn Sie zusätzliche Spalten hinzufügen müssen, ist dies trivial und Sie können Versionen Ihrer Daten behalten. Die meisten NoSQL-DBs unterstützen das Abfragen auf viele verschiedene Arten, und die meisten davon fallen in Ihr Modell.

Die meisten NoSQL-DBs wie FatDB und RavenDB kommen in den Sinn und würden für den Windows-Bereich gut funktionieren. MongoDB usw. für andere.

Brian Langbecker
quelle
1
Umm, das OP suchte nach Tipps, wie "NoSQL" -ähnliche Funktionen in einer relationalen Datenbank implementiert werden können, dh nicht in einer NoSQL-Datenbank.
Colin 't Hart