Was ist das bessere Datenbankdesign: mehr Tabellen oder mehr Spalten?

77

Ein ehemaliger Mitarbeiter bestand darauf, dass eine Datenbank mit mehr Tabellen mit jeweils weniger Spalten besser ist als eine mit weniger Tabellen mit jeweils mehr Spalten. Anstelle einer Kundentabelle mit Spalten für Name, Adresse, Stadt, Bundesland, Postleitzahl usw. hätten Sie beispielsweise eine Namenstabelle, eine Adresstabelle, eine Stadttabelle usw.

Er argumentierte, dieses Design sei effizienter und flexibler. Vielleicht ist es flexibler, aber ich bin nicht qualifiziert, seine Effizienz zu kommentieren. Selbst wenn es effizienter ist, denke ich, dass diese Gewinne durch die zusätzliche Komplexität aufgewogen werden können.

Gibt es also signifikante Vorteile für mehr Tabellen mit weniger Spalten gegenüber weniger Tabellen mit mehr Spalten?

Rabe
quelle

Antworten:

59

Ich habe ein paar ziemlich einfache Faustregeln, die ich beim Entwerfen von Datenbanken befolge. Ich denke, sie können verwendet werden, um Entscheidungen wie diese zu treffen.

  1. Bevorzugen Sie die Normalisierung. Die Denormalisierung ist eine Form der Optimierung mit allen erforderlichen Kompromissen und sollte daher mit einer YAGNI- Haltung angegangen werden .
  2. Stellen Sie sicher, dass der Clientcode, der auf die Datenbank verweist, so weit vom Schema entkoppelt ist, dass für eine Überarbeitung keine größere Neugestaltung der Clients erforderlich ist.
  3. Haben Sie keine Angst vor einer Denormalisierung, wenn dies einen deutlichen Vorteil für die Leistung oder die Komplexität der Abfragen bietet.
  4. Verwenden Sie Ansichten oder nachgeschaltete Tabellen, um die Denormalisierung zu implementieren, anstatt den Kern des Schemas zu denormalisieren, wenn Datenvolumen und Verwendungsszenarien dies zulassen .

Das übliche Ergebnis dieser Regeln ist, dass beim ursprünglichen Entwurf Tabellen gegenüber Spalten bevorzugt werden, wobei der Schwerpunkt auf der Beseitigung von Redundanz liegt. Während das Projekt fortschreitet und Denormalisierungspunkte identifiziert werden, wird sich die Gesamtstruktur zu einem Gleichgewicht entwickeln, das Kompromisse mit begrenzter Redundanz und Spaltenproliferation eingeht, im Austausch für andere wertvolle Vorteile.

Chris Ammerman
quelle
Was genau ist eine "Downstream-Tabelle"?
Olive
1
Ich meine "Downstream" im Kontext eines "Datenflusses". Dies bedeutet im Wesentlichen, dass Sie einen Prozess haben, der die normalisierten Tabellen als Quelle verwendet, die Daten irgendwie transformiert und das Ergebnis dann an einer anderen Stelle ablegt.
Chris Ammerman
12

Ich würde mich für mehr Tische aussprechen, aber nur bis zu einem gewissen Punkt. Wenn Sie in Ihrem Beispiel die Informationen Ihres Benutzers in zwei Tabellen unterteilt haben, z. B. USERS und ADDRESS, haben Sie die Flexibilität, mehrere Adressen pro Benutzer zu haben. Eine offensichtliche Anwendung hierfür ist ein Benutzer, der separate Rechnungs- und Versandadressen hat.

Das Argument für eine separate CITY-Tabelle wäre, dass Sie den Namen jeder Stadt nur einmal speichern und dann bei Bedarf darauf verweisen müssen. Das reduziert zwar die Duplizierung, aber in diesem Beispiel denke ich, dass es übertrieben ist. Es ist zwar platzsparender, aber Sie zahlen den Preis in Joins, wenn Sie Daten aus Ihrer Datenbank auswählen.

Bill die Eidechse
quelle
11

Es klingt nicht so sehr nach einer Frage zu Tabellen / Spalten, sondern nach Normalisierung. In einigen Situationen ist ein hoher Normalisierungsgrad (in diesem Fall "mehr Tabellen") gut und sauber, aber normalerweise ist eine hohe Anzahl von JOINs erforderlich, um relevante Ergebnisse zu erhalten. Und mit einem ausreichend großen Datensatz kann dies die Leistung beeinträchtigen.

Jeff hat ein wenig darüber geschrieben, was das Design von StackOverflow betrifft. Siehe auch den Beitrag, auf den Jeff von Dare Obasanjo verweist .

Swilliams
quelle
1
Nach meiner Erfahrung ist dies offensichtlich falsch. Ich habe mit Abfragen gearbeitet, die Dutzende von Tabellen mit jeweils mehr als 1 Million Zeilen verknüpfen. Solange Sie Primärschlüssel verbinden, werden die Ergebnisse sehr schnell wieder angezeigt.
JosephStyons
1
Was ist "schnell"? Wenn Sie eine Website betreiben, die versucht, Tausende von Seitenaufrufen pro Sekunde "schnell genug" zu liefern, hat dies eine völlig andere Bedeutung als eine einzelne Benutzerdatenbank, bei der Sie sich nur um die Antwortzeit für den Benutzer kümmern.
Chris Upchurch
"Solange Sie sich mit Primärschlüsseln verbinden, kommen die Ergebnisse sehr schnell zurück." Nun ja. Nach meiner Erfahrung mit mehr Tabellen ist es jedoch wahrscheinlicher, dass Verknüpfungen für nicht-pk-Spalten, nicht indizierte Spalten usw. auftreten
swilliams
Die Normalisierung und das anschließende Zusammenfügen von Tabellen tragen normalerweise zur Leistung bei, da Sie per Definition selektiver vorgehen und Tabellenscans vermeiden können - die langsamste Methode zur Auswahl.
Ed Guiness
Schlechtes Design ist normalerweise der größte Faktor für schlechte Leistung, nicht für Normalisierung.
Ed Guiness
5

Ein vollständig normalisiertes Design (dh "Mehr Tabellen") ist flexibler, einfacher zu warten und vermeidet doppelte Daten, was bedeutet, dass Ihre Datenintegrität viel einfacher durchzusetzen ist.

Das sind starke Gründe, sich zu normalisieren. Ich würde mich dafür entscheiden, zuerst zu normalisieren und dann bestimmte Tabellen erst zu denormalisieren , nachdem Sie gesehen haben, dass die Leistung zu einem Problem wird.

Ich habe die Erfahrung gemacht, dass Sie in der realen Welt selbst bei sehr großen Datenmengen nicht den Punkt erreichen, an dem eine Denormalisierung erforderlich ist.

JosephStyons
quelle
Einverstanden. Ich habe immer nur denormalisiert, um die Komplexität von Abfragen zu verringern, normalerweise um eine Impedanzfehlanpassung mit einem ORM zu beseitigen. Niemals, weil die Optimierung für die Leistung erforderlich war, auch nicht in großem Maßstab.
Ben Simmons
5

Dies hängt von Ihrer Datenbankvariante ab. MS SQL Server beispielsweise bevorzugt eher engere Tabellen. Das ist auch der "normalisierte" Ansatz. Andere Motoren bevorzugen es möglicherweise umgekehrt. Mainframes fallen in der Regel in diese Kategorie.

Joel Coehoorn
quelle
4

Jede Tabelle sollte nur Spalten enthalten, die sich auf die Entität beziehen, die durch den Primärschlüssel eindeutig identifiziert wird. Wenn alle Spalten in der Datenbank Attribute derselben Entität sind, benötigen Sie nur eine Tabelle mit allen Spalten.

Wenn eine der Spalten jedoch null sein kann, müssen Sie jede nullfähige Spalte mit einem Fremdschlüssel für die Haupttabelle in eine eigene Tabelle einfügen, um sie zu normalisieren. Dies ist ein häufiges Szenario. Für ein übersichtlicheres Design fügen Sie vorhandenen Tabellen wahrscheinlich mehr Tabellen als Spalten hinzu. Wenn Sie diese optionalen Attribute zu ihrer eigenen Tabelle hinzufügen, müssen sie keine Nullen mehr zulassen, und Sie vermeiden eine Reihe von NULL-bezogenen Problemen.

Mark Cidade
quelle
3

Die Datenbank mit mehreren Tabellen ist viel flexibler, wenn eine dieser Eins-zu-Eins-Beziehungen in Zukunft zu einer zu vielen oder zu vielen zu vielen wird. Wenn Sie beispielsweise für einige Kunden mehrere Adressen speichern müssen, ist es viel einfacher, wenn Sie eine Kundentabelle und eine Adresstabelle haben. Ich kann nicht wirklich eine Situation erkennen, in der Sie möglicherweise einige Teile einer Adresse duplizieren müssen, andere jedoch nicht. Daher sind separate Tabellen für Adresse, Stadt, Bundesland und Postleitzahl möglicherweise etwas übertrieben.

Chris Upchurch
quelle
Ich habe 40 eindeutige Felder zu Benutzerinformationen, die eindeutig sind und eins zu eins vom Benutzerauthentifizierungssystem stammen. Denken Sie, dass es in Ordnung ist, wenn ich diese 40 Spalten in einer Tabelle behalte? Wenn ich sie trenne, muss ich mehr Joins in meine Abfragen schreiben :-(. Können Sie vorschlagen
vkrams
3

Wie alles andere: es kommt darauf an.

Es gibt keine feste Regel bezüglich der Anzahl der Spalten gegenüber der Anzahl der Tabellen.

Wenn Ihre Kunden mehrere Adressen benötigen, ist eine separate Tabelle dafür sinnvoll. Wenn Sie einen wirklich guten Grund haben, die City-Spalte in einer eigenen Tabelle zu normalisieren, kann das auch gehen, aber das habe ich vorher noch nicht gesehen, weil es (normalerweise) ein Freiformfeld ist.

Ein tischlastiges, normalisiertes Design ist platzsparend und sieht "Lehrbuch-gut" aus, kann aber extrem komplex werden. Es sieht gut aus, bis Sie 12 Joins durchführen müssen, um den Namen und die Adresse eines Kunden zu erhalten. Diese Designs sind nicht automatisch fantastisch in Bezug auf die Leistung, die am wichtigsten ist: Abfragen.

Vermeiden Sie nach Möglichkeit Komplexität. Wenn ein Kunde beispielsweise nur zwei Adressen haben kann (nicht beliebig viele), ist es möglicherweise sinnvoll, alle Adressen in einer einzigen Tabelle zu speichern (Kunden-ID, Name, ShipToAddress, BillingAddress, ShipToCity, BillingCity usw.).

Hier ist Jeffs Beitrag zum Thema.

Michael Haren
quelle
2

Tabellen mit weniger Spalten bieten Vorteile. Sie müssen sich jedoch auch das obige Szenario ansehen und die folgenden Fragen beantworten:

Darf der Kunde mehr als eine Adresse haben? Wenn nicht, ist eine separate Adressentabelle nicht erforderlich. In diesem Fall ist eine separate Tabelle hilfreich, da Sie später problemlos weitere Adressen hinzufügen können, wenn es schwieriger wird, der Tabelle weitere Spalten hinzuzufügen.

Dillie-O
quelle
1

Ich würde die Normalisierung als ersten Schritt betrachten, daher wären Städte, Landkreise, Bundesstaaten und Länder besser als separate Spalten geeignet. Dank der Leistungsfähigkeit der SQL-Sprache und der heutigen DBMS-es können Sie Ihre Daten später gruppieren, wenn Sie sie anzeigen müssen es in einer anderen, nicht normalisierten Ansicht.

Während der Entwicklung des Systems können Sie in Betracht ziehen, einen Teil zu „normalisieren“, wenn Sie dies als Verbesserung betrachten.

Zappan
quelle
1
Meine 2 Cent: Ich muss nicht zustimmen; Diese Art der Optimierung während des Entwurfs ist ein klassischer Fall vorzeitiger Optimierung. Warten Sie, bis Sie feststellen, dass die Leistung ein Problem darstellt, bevor Sie ein gutes Design opfern.
JosephStyons
1

Ich denke, das Gleichgewicht ist in diesem Fall in Ordnung. Wenn es sinnvoll ist, eine Spalte in eine Tabelle einzufügen, fügen Sie sie in die Tabelle ein. Wenn dies nicht der Fall ist, tun Sie dies nicht. Der Ansatz Ihrer Mitarbeiter würde definitiv dazu beitragen, die Datenbank zu normalisieren. Dies ist jedoch möglicherweise nicht sehr nützlich, wenn Sie 50 Tabellen zusammenfügen müssen, um die benötigten Informationen zu erhalten.

Ich denke, meine Antwort wäre, verwenden Sie Ihr bestes Urteilsvermögen.

Craig H.
quelle
1

Dies hat viele Seiten, aber aus Sicht der Anwendungseffizienz können Mote-Tabellen manchmal effizienter sein. Wenn Sie jedes Mal, wenn die Datenbank eine Operation ausführt, einige Tabellen mit einer Reihe von Spalten haben, besteht die Möglichkeit, dass eine Sperre ausgeführt wird. Weitere Daten sind für die Dauer der Sperre nicht verfügbar. Wenn Sperren zu Seiten und Tabellen eskaliert werden (hoffentlich nicht zu Tabellen :)), können Sie sehen, wie dies das System verlangsamen kann.

kemiller2002
quelle
1

Hmm.

Ich denke, es ist eine Wäsche und hängt von Ihrem speziellen Designmodell ab. Berücksichtigen Sie auf jeden Fall Entitäten, die mehr als ein paar Felder in ihrer eigenen Tabelle haben, oder Entitäten, deren Zusammensetzung sich wahrscheinlich ändert, wenn sich die Anforderungen Ihrer Anwendung ändern (zum Beispiel - ich würde die Adresse sowieso herausrechnen, da sie so viele Felder enthält, aber ich Ich würde es besonders tun, wenn Sie dachten, es gäbe eine Chance, dass Sie mit Adressen aus dem Ausland umgehen müssen, die eine andere Form haben können. Dasselbe gilt für Telefonnummern.

Das heißt, wenn Sie es zum Laufen bringen, achten Sie auf die Leistung. Wenn Sie eine Entität ausgegliedert haben, für die Sie große, teure Verknüpfungen durchführen müssen, ist es möglicherweise eine bessere Entwurfsentscheidung, diese Tabelle wieder in das Original umzuwandeln.

John Christensen
quelle
1

Wenn Sie Ihre Datenbank entwerfen, sollten Sie so nah wie möglich an der Bedeutung der Daten sein und NICHT an Ihrem Anwendungsbedarf!

Ein gutes Datenbankdesign sollte unverändert über 20 Jahre Bestand haben.

Ein Kunde könnte mehrere Adressen haben, das ist die Realität. Wenn Sie entschieden haben, dass Ihre Anwendung für die erste Version auf eine Adresse beschränkt ist, betrifft dies das Design Ihrer Anwendung und nicht die Daten!

Es ist besser, mehrere Tabellen anstelle mehrerer Spalten zu haben und die Ansicht zu verwenden, wenn Sie Ihre Abfrage vereinfachen möchten.

In den meisten Fällen treten bei einer Datenbank Leistungsprobleme auf, bei denen es um die Netzwerkleistung (Kettenabfrage mit einem Zeilenergebnis, nicht benötigte Abrufspalte usw.) und nicht um die Komplexität Ihrer Abfrage geht.

Marco Guignard
quelle
0

Abfragen mit möglichst wenigen Spalten bieten enorme Vorteile . Aber die Tabelle selbst kann eine große Anzahl haben. Jeff sagt auch etwas dazu.

Stellen Sie grundsätzlich sicher, dass Sie beim Abfragen nicht mehr verlangen, als Sie benötigen. Die Leistung von Abfragen hängt direkt von der Anzahl der Spalten ab, nach denen Sie fragen.

ColinYounger
quelle
0

Ich denke, Sie müssen sich die Art der Daten ansehen, die Sie speichern, bevor Sie diese Entscheidung treffen. Eine Adresstabelle ist großartig, aber nur, wenn die Wahrscheinlichkeit hoch ist, dass mehrere Personen dieselbe Adresse teilen. Wenn jede Person unterschiedliche Adressen hatte, führt das Speichern dieser Daten in einer anderen Tabelle nur zu unnötigen Verknüpfungen.

Ich sehe keinen Vorteil darin, eine Stadttabelle zu haben, es sei denn, Städte an sich sind Entitäten, die Sie in Ihrer Bewerbung interessieren. Oder wenn Sie die Anzahl der Städte begrenzen möchten, die Ihren Benutzern zur Verfügung stehen.

Unter dem Strich müssen Entscheidungen wie diese die Anwendung selbst berücksichtigen, bevor Sie mit der Aufnahme beginnen, um die Effizienz zu steigern. IMO.

Tundey
quelle
0

Normalisieren Sie zunächst Ihre Tabellen. Dies stellt sicher, dass Sie redundante Daten vermeiden und weniger Datenzeilen scannen müssen, was Ihre Abfragen verbessert. Wenn Sie dann auf einen Punkt stoßen, an dem die normalisierten Tabellen, denen Sie beitreten, dazu führen, dass die Verarbeitung der Abfrage zu lange dauert (teure Join-Klausel), denormalisieren Sie sie gegebenenfalls.

pbars23
quelle
0

Schön, so viele inspirierende und fundierte Antworten zu sehen.

Meine Antwort wäre (leider): es kommt darauf an.

Zwei Fälle: * Wenn Sie ein Datenmodell erstellen, das für viele Jahre verwendet werden soll und daher möglicherweise viele zukünftige Änderungen vornehmen muss: Wählen Sie mehr Tabellen und weniger Zeilen und eine ziemlich strenge Normalisierung. * In anderen Fällen können Sie zwischen mehr Tabellen ohne Zeilen oder weniger Zeilen mit mehr Tabellen wählen. Insbesondere für Personen, die relativ neu in diesem Thema sind, kann dieser letzte Ansatz intuitiver und leichter zu verstehen sein.

Gleiches gilt für die Wahl zwischen dem objektorientierten Ansatz und anderen Optionen.

Bart Rozinga
quelle