Ist das ein "richtiges" Datenbankdesign?

8

Ich arbeite mit der neuen Version einer Drittanbieteranwendung. In dieser Version wird die Datenbankstruktur geändert, sie sagen "um die Leistung zu verbessern".

Die alte Version der DB hatte eine allgemeine Struktur wie folgt:

%Vor%

Wir hatten also eine Haupttabelle mit Feldern für die grundlegenden Eigenschaften und eine separate Tabelle, um benutzerdefinierte Eigenschaften zu verwalten, die vom Benutzer hinzugefügt wurden.

Die neue Version der DB hat eine Struktur wie folgt:

%Vor%

Wenn nun der Benutzer eine benutzerdefinierte Eigenschaft hinzufügt, wird der aktuellen ENTITY_PROPERTY -Tabelle eine neue Spalte hinzugefügt, bis die maximale Anzahl an Spalten (verwaltet von der Anwendung) erreicht ist, und dann eine neue Tabelle wird erstellt.

Also, meine Frage ist: Ist das ein richtiger Weg, eine DB-Struktur zu entwerfen? Ist dies der einzige Weg, Performances zu steigern ? Die alte Struktur benötigt viele Join oder Subselect, aber diese Struktur scheint mir nicht sehr schlau (oder sogar richtig) ...

    
davioooh 03.05.2012, 08:07
quelle

5 Antworten

10

Ich habe das schon einmal auf der angenommenen (oft unbewiesenen) "Kosten" der Verbindung gesehen - es verwandelt im Grunde eine zeilenlastige Datentabelle in eine spaltenlastige Tabelle. Sie haben, wie Sie meinen, mit ihrer eigenen Einschränkung zu kämpfen, indem sie neue Tabellen erstellen, wenn ihnen die Spalten ausgehen.

Ich vollständig stimme nicht damit überein.

Persönlich würde ich bei der alten Struktur bleiben und die Leistungsprobleme neu bewerten. Das heißt nicht, dass der alte Weg der richtige ist, er ist meiner Meinung nach nur marginal besser als die "Verbesserung", und es erübrigt sich ein groß angelegtes Re-Engineering von Datenbanktabellen und DAL-Code.

Diese Tabellen erscheinen mir weitgehend statisch ... Caching wäre eine noch bessere Leistungsverbesserung, ohne die Datenbank zu verstümmeln und eine, die ich zuerst betrachten würde. Holen Sie das "teure" Holen einmal und halten Sie es irgendwo im Gedächtnis, dann vergessen Sie Ihre Schwierigkeiten (Anmerkung, ich mache Licht der Notwendigkeit, den Cache zu verwalten, aber statische Daten sind eine der einfachsten zu verwalten).

Oder warten Sie auf den Tag, an dem Sie auf die maximale Anzahl von Tabellen pro Datenbank stoßen: -)

Andere haben andere Läden vorgeschlagen. Dies ist eine durchaus praktikable Möglichkeit und wenn ich keine existierende Datenbankstruktur hätte, würde ich das auch in Betracht ziehen. Ich sehe jedoch keinen Grund, warum diese Struktur nicht in ein RDBMS passen kann. Ich habe es auf fast allen großen Apps gesehen, an denen ich gearbeitet habe. Interessanterweise gingen alle auf eine ähnliche Route und alle waren meist "erfolgreiche" Implementierungen.

    
Adam Houldsworth 03.05.2012, 08:15
quelle
5

Nein, ist es nicht. Es ist schrecklich.

  

bis die maximale Anzahl der Spalten (nach Anwendung) erreicht ist,   dann wird eine neue Tabelle erstellt.

Dieser Satz sagt alles. Unter keinen Umständen sollte eine Anwendung Tabellen dynamisch erstellen. Der "alte" Ansatz ist auch nicht ideal, aber da Sie die Anforderung haben müssen, dass Benutzer benutzerdefinierte Eigenschaften hinzufügen können, muss dies so sein.

Bedenken Sie Folgendes:

  • Sie verlieren die gesamte Typsicherheit, da Sie alle Werte in der Spalte "PROPERTY_VALUE"
  • speichern müssen
  • Abhängig von Ihren Benutzern können Sie das Schema vorher ändern und dann einen Batch-Job für die Datenbankaktualisierung ausführen lassen, damit mindestens alle Eigenschaften mit dem richtigen Datentyp deklariert werden. Außerdem könnten Sie die Entity_id / Key-Sache verlieren.
  • Sieh dir das an: Ссылка . Das riecht sicher danach.
  • Vielleicht ist ein RDBMS nicht das Richtige für Ihre App. Erwägen Sie, einen auf Schlüssel / Wert basierenden Speicher wie MongoDB oder eine andere NoSQL-Datenbank zu verwenden. ( Ссылка )
Dariop 03.05.2012 08:16
quelle
1


Von dem, was ich über Datenbanken weiß (aber ich bin sicherlich nicht der erfahrenste), scheint es eine ziemlich schlechte Idee, das in Ihrer Datenbank zu tun. Wenn Sie bereits wissen, wie viele benutzerdefinierte Eigenschaften ein Benutzer maximal hat, würde ich sagen, dass Sie die Anzahl der Spalten der Tabelle auf diesen Wert festlegen sollten Andererseits bin ich kein Experte, aber das Erstellen neuer Spalten im laufenden Betrieb ist nicht die Art von Operations-Datenbanken. Es bringt dir mehr Ärger als alles andere Wenn ich Sie wäre, würde ich entweder die Anzahl der benutzerdefinierten Eigenschaften korrigieren oder beim alten System bleiben.

    
Gabriel Theron 03.05.2012 08:15
quelle
0

Ich glaube, dass das Erstellen einer neuen Tabelle für jede Entität zum Speichern von Eigenschaften ein schlechtes Design ist, da Sie die Datenbank mit Tabellen füllen könnten. Der einzige Vorteil bei der Anwendung der zweiten Methode besteht darin, dass Sie nicht alle redundanten Zeilen durchlaufen, die nicht für die ausgewählte Entität gelten. Die Verwendung von Indizes für Ihre Datenbank in der ursprünglichen Tabelle ENTITY_PROPERTIES kann jedoch erheblich zur Leistung beitragen.

Ich würde persönlich bei Ihrem ursprünglichen Entwurf bleiben, Indizes anwenden und die Datenbank-Engine die besten Methoden zur Auswahl der Daten bestimmen lassen, anstatt jede Entitätseigenschaft in eine neue Tabelle zu trennen.

    
Darren Davies 03.05.2012 08:14
quelle
0

Es gibt keinen "richtigen" Weg, eine Datenbank zu entwerfen - ich kenne keine allgemein anerkannten Standards außer den bekannten " Normalform " Theorie; Viele Datenbankdesigns ignorieren diesen Standard aus Leistungsgründen.

Es gibt jedoch Möglichkeiten, Datenbankdesigns zu bewerten - Leistung, Wartbarkeit, Verständlichkeit usw. Oft müssen Sie diese gegeneinander handeln; Das scheint Ihre Veränderung zu sein - Handelbarkeit und Verständlichkeit gegenüber Performance.

Also, der beste Weg, um herauszufinden, ob das ein guter Trade-Off ist, ist zu sehen, ob die Performance-Gewinne eingetreten sind. Der beste Weg, dies herauszufinden, besteht darin, das vorgeschlagene Schema zu erstellen, es mit einem repräsentativen Datensatz zu laden und Abfragen zu schreiben, die Sie in der Produktion ausführen müssen.

Ich nehme an, dass das neue Design bei Abfragen wie "STANDARD_PROPERTY_1 von einer Entität, in der STANDARD_PROPERTY_1 = 'Banane" gefunden wird, nicht wahrnehmbar schneller ist.

Ich nehme an, dass es beim Abrufen aller Eigenschaften für eine gegebene Entität nicht merklich schneller wird; In der Tat könnte es etwas langsamer sein, da anstelle einer einzelnen Verknüpfung zu ENTITY_PROPERTIES das neue Design Joins zu mehreren Tabellen erfordert. Sie werden "spärliche" Ergebnisse zurückgeben - vermutlich haben nicht alle Entitäten Werte in den Spalten von property_n in allen Tabellen von ENTITY_PROPERTIES_n.

Wenn das neue Design möglicherweise wesentlich schneller ist, benötigen Sie eine zusammengesetzte where-Klausel für benutzerdefinierte Eigenschaften. Wenn Sie beispielsweise eine Entität finden, bei der die benutzerdefinierte Eigenschaft 1 wahr ist, die benutzerdefinierte Eigenschaft 2 eine Banane ist und die benutzerdefinierte Eigenschaft 3 nicht vorhanden ist ("Kylie", "Pussycat Dolls", "Giraffe"), ist (wahrscheinlich) schneller als Sie Geben Sie Spalten in den Tabellen ENTITY_PROPERTIES_n anstelle von Zeilen in der Tabelle ENTITY_PROPERTIES an. Wahrscheinlich.

Was die Wartbarkeit betrifft - yuck. Ihr Datenbankzugriffscode muss nun viel intelligenter sein, denn Sie wissen, in welcher Tabelle welche Eigenschaft enthalten ist und wie viele Spalten zu viele Spalten enthalten. Die Wahrscheinlichkeit, Fehler zu behandeln, ist hoch - es gibt mehr bewegliche Teile und ich kann mir keine offensichtlichen Komponententests vorstellen, um sicherzustellen, dass die Datenbankzugriffslogik funktioniert.

Verständlichkeit ist ein anderes Problem - diese Lösung ist nicht in den meisten Entwicklern Toolbox, es ist kein Industriestandard-Muster. Die alte Lösung ist ziemlich allgemein bekannt - gemeinhin als "Entity-Attribut-Wert" bezeichnet. Dies wird zu einem wichtigen Problem bei langlebigen Projekten, bei denen Sie nicht garantieren können, dass das ursprüngliche Entwicklungsteam sich herumtreibt.

    
Neville Kuyt 03.05.2012 10:06
quelle