Umgang mit dem Tabellendesign mit variablen Spalten


16

Ich habe ein Tabellendesignszenario und möchte als Nicht-DBA-Typ Meinungen dazu haben, welche skalierbarer sind.

Angenommen, Sie werden gebeten, Informationen zu Häusern für ein U-Bahn-Gebiet aufzuzeichnen, angefangen bei einem kleinen Viertel (200 Häuser), bis zu 5000000+ Häusern.

Sie müssen Basisinformationen speichern: ID-Nr. (Eine eindeutige Losnummer, die wir als eindeutigen Index verwenden können), Adr, Stadt, Bundesland, Postleitzahl. Feiner, einfacher Tisch wird damit umgehen.

Aber jedes Jahr werden Sie gebeten, zusätzliche Informationen zu allen Häusern aufzuzeichnen - und WELCHE Informationen werden sich jedes Jahr ändern. So werden Sie beispielsweise im ersten Jahr aufgefordert, den Nachnamen und das Quadratmeter des Eigentümers aufzuzeichnen. Im zweiten Jahr werden Sie gebeten, den Nachnamen beizubehalten, das Quadratmeter zu löschen und stattdessen die Vornamen der Besitzer zu sammeln.

Schließlich ändert sich jedes Jahr die Anzahl der zusätzlichen Spalten. Könnte mit 2 zusätzlichen Spalten beginnen, dann mit 6 im nächsten Jahr, dann wieder runter mit 2.

Daher besteht ein Tabellenansatz darin, zu versuchen, die benutzerdefinierten Informationen als Spalten in den Haustabellen hinzuzufügen, sodass nur eine Tabelle vorhanden ist.

Aber ich habe eine Situation, in der jemand die Tische dafür ausgelegt hat:

Spalten "Haustabelle": ID, Adr, Stadt, Bundesland, Postleitzahl - mit einer Zeile pro Haus

ID   Addr              City     State  Zip 
-------------------------------------------
1    10 Maple Street   Boston      MA  11203

2    144 South Street  Chelmsford  MA  11304

3    1 Main Avenue     Lowell      MA  11280

Spalten "Benutzerdefinierte Infotabelle": ID, Name, Wert - die Tabelle sieht folgendermaßen aus:

ID   Name             Value

1    Last Name        Smith

2    Last Name        Harrison

3    Last Name        Markey

1    Square Footage   1200

2    Square Footage   1930

3    Square Footage 

Es gibt also mehrere Zeilen für jeden einzelnen Hausdatensatz. Jedes Jahr, wenn sich die erforderlichen optionalen Informationen ändern, wird diese Tabelle im wahrsten Sinne des Wortes neu erstellt, sodass sie im nächsten Jahr so ​​aussehen könnte:

1    Last Name    Smith

2    Last Name    Harrison

3    Last Name    Markey

1    First Name   John

2    First Name   Harry

3    First Name   Jim

Schließlich sammeln Sie 100.000 Hauszeilen UND in einem Jahr gibt es 10 zusätzliche Informationen. Die zweite Tabelle enthält jetzt 1.000.000 Informationszeilen, von denen viele redundante (Beschreibungs-) Informationen enthalten. Die Datenbankanforderungen insgesamt sind, dass die Benutzer die Hauszeileninformationen und die zugehörigen benutzerdefinierten Feldwerte Tausende Male pro Tag abrufen müssen.

Also meine Frage: Wäre es schlecht (oder schrecklich), stattdessen entweder:

A) Legen Sie eine Haustabelle mit einer maximalen Anzahl von benutzerdefinierten Spalten (mit den Bezeichnungen "1" bis "10") an und fügen Sie diese benutzerdefinierten Werte direkt in die Hauszeilen ein

ODER

B) Speichern Sie die benutzerdefinierten Informationen in der Haustabelle. Erstellen Sie jedoch jedes Jahr, wenn sich die Anforderungen ändern, die Haustabelle mit nur der Anzahl der Spalten neu, die für benutzerdefinierte Informationen erforderlich sind, mit der Idee, dass die Anforderungen verrückt werden könnten und Sie nie wissen, wie viele maximal sind Optionale Felder können angefordert werden?

Danke, hoffe das macht Sinn!


Hallo, wie hast du dein Problem gelöst? Ich bin in der gleichen Art von Szenario ausgeführt und ich bin dabei, eine relationale Tabelle pro zusätzliche Informationen zu erstellen und das mit Ansichten als "einzelne Tabelle" zu rendern.
Benj

Antworten:


15

Sie haben so ziemlich 4 Möglichkeiten:

NoSQL - Definition Jeder Datensatz wird als Satz von Schlüssel / Wert-Paaren gespeichert. Es ist sehr flexibel und schnell. Nicht alle Verfasser von Berichten unterstützen diese Art der Speicherung. Es gibt viele Beispieldatenbankimplementierungen von NoSQL. Die derzeit populärste ist MongoDB.

EAV - Definition Hier drehen Sie entweder den ganzen Tisch oder einen Teil (in einem anderen Tisch) auf die Seite. Dies ist eine gute Wahl, wenn Sie bereits eine relationale Datenbank im Unternehmen haben, von der Sie sich nicht leicht entfernen können. Das von Ihnen angegebene Beispiel für eine benutzerdefinierte Infotabelle ist ein gutes Beispiel für eine EAV-Tabelle.

Standardtabellen mit XML-Spalten - Stellen Sie sich vor, dass NoSQL relationale Tabellen erfüllt. Die in einer XML-Spalte gespeicherten Daten können jedes von XML unterstützte Format aufweisen, einschließlich mehrerer korrelierter Unterdaten. Für die Spalten, von denen Sie wissen, dass sie "reguläre" Spalten sind, können sie als der entsprechende Spaltentyp zum Speichern der Daten (Nachname, Adresse, Stadt, Bundesland usw.) erstellt werden.

Standardtabellen mit vielen zusätzlichen Spalten - Sie haben eine relationale Datenbank, können weder XML noch EAV verwenden und NoSQL ist keine Option. Fügen Sie für jeden Typ viele zusätzliche Spalten hinzu. Ich würde 30 oder mehr Varchar, 30 oder mehr Integer, 15 oder mehr Ziffern schätzen. Und wenn Sie eine Spalte für einen Wert verwenden, verwenden Sie sie nicht mehr . Und nicht löschen Sie die Spalte entweder.

Aus all diesen Lösungen gehe ich davon aus, dass Sie entweder den NoSQL- oder den EAV-Ansatz am erfolgreichsten finden, wenn Sie Ihren Code und Ihr Schema am wenigsten umgestalten.

Sie haben eine Situation, in der Sie Daten für ein Jahr und nicht für das nächste Jahr erfassen und anschließend erneut erfassen. Der Versuch, die älteren Daten mit den richtigen Informationen zu aktualisieren, ist problematisch und teuer. Lagerung ist weder.


Ich habe gehört, Sie können auch Pivot-Tische oder ähnliches verwenden
Alexander Mills

2

Um Ihre Frage zu diesen beiden Optionen zu beantworten, scheint mir keine richtig zu sein. A) wird dich einsperren und B) ist eine Menge Arbeit. Das aktuelle Schema, das Sie beschreiben, ist nicht allzu schlecht (mit Ausnahme des Informationsnamens ("Vorname", "Quadratfuß" usw.) als Zeichenfolge anstelle einer ID, die auf eine Nachschlagetabelle verweist.

Dies scheint mir jedoch ein guter Kandidat für eine NoSQL-Datenbank zu sein ( http://en.wikipedia.org/wiki/NoSQL ). Während ich noch nie mit einer solchen Datenbank gearbeitet habe, ist das, was Sie beschreiben, ein typisches Szenario, das dadurch gelöst wird.


0

Wenn die gleichzeitige Anzahl benutzerdefinierter Spalten endlich ist und die Grenzwerte bekannt sind (z. B. nicht mehr als 10-20 benutzerdefinierte Spalten für Zeichenfolgen, nicht mehr als x Spalten für Ganzzahlen usw.), können
Sie die Basistabelle mit zusätzlichen Feldern pro Datentyp und verwenden Wenn Sie die Tabelle jedes Jahr neu erstellen, erstellen Sie eine Ansicht für dieses Jahr, die nur die relevanten benutzerdefinierten Spalten enthält, und benennen Sie die generischen Felder um, um den Inhalt für dieses Jahr widerzuspiegeln.

House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...

create view house_2014 as 
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...

Das Problem bei diesem Ansatz ist, dass Sie keinen Verlauf haben, aber jedes Jahr eine Kopie anfertigen können, bevor Sie die Spaltenanforderungen ändern.

create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";

0

Können Sie alle Szenarien auflisten, für die Sie diese Daten speichern möchten?

Wenn es eine begrenzte Anzahl von Spaltenkombinationen gibt, die auf die Tabelle angewendet werden können, versuchen Sie, eine "Basistabelle" mit gemeinsamen Spalten zu modellieren, die für alle Szenarien geeignet sind. Erstellen Sie dann weitere Tabellen, um eine Art Vererbung zu implementieren. Dies wird im ERD- und Datenbank-Design als Subtyp / Supertyp bezeichnet.)

eine Tabelle für jedes Szenario, auf diese Weise halten Sie zumindest die Tabellen sauber und vermeiden, dass die Adresse in der Spalte "Nachname" gespeichert wird ...

Schauen Sie sich diese Entwurfsfrage an: /programming/554522/something-like-inheritance-in-database-design

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.