Ich habe ziemlich viel mit relationalen Datenbanken gearbeitet und denke, ich verstehe die Grundkonzepte eines guten Schemaentwurfs ziemlich gut. Vor kurzem wurde ich beauftragt, ein Projekt zu übernehmen, bei dem die DB von einem hochbezahlten Berater entworfen wurde. Bitte lassen Sie mich wissen, ob mein Bauchgefühl - "WTF ??!?" - ist gerechtfertigt, oder ist dieser Typ so ein Genie, dass er außerhalb meines Reiches operiert?
Bei der DB handelt es sich um eine Inhouse-App, mit der Anfragen von Mitarbeitern erfasst werden. Wenn Sie sich nur einen kleinen Abschnitt davon ansehen, erhalten Sie Informationen zu den Benutzern und zu der Anforderung, die gestellt wird. Ich würde das so gestalten:
Benutzertabelle:
UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department
Tisch anfordern
RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table
Einfach, richtig?
Berater gestaltet es so (mit Beispieldaten):
UsersTable
UserID FirstName LastName
234 John Doe
516 Jane Doe
123 Foo Bar
DepartmentsTable
DepartmentID Name
1 Sales
2 HR
3 IT
UserDepartmentTable
UserDepartmentID UserID Department
1 234 2
2 516 2
3 123 1
RequestTable
RequestID UserID <...>
1 516 blah
2 516 blah
3 234 blah
Die gesamte Datenbank ist so aufgebaut, dass jedes Datenelement in einer eigenen Tabelle zusammengefasst ist und numerische IDs alles miteinander verbinden. Anscheinend hatte der Berater über OLAP gelesen und wollte die "Geschwindigkeit der Ganzzahlensuche"
Er verfügt auch über eine große Anzahl gespeicherter Prozeduren, um auf alle diese Tabellen zu verweisen.
Ist dies ein gültiger Entwurf für eine kleine bis mittelgroße SQL-Datenbank?
Danke für Kommentare / Antworten ...
Antworten:
Macht für mich vollkommen Sinn. Es ist einfach sehr normalisiert, was viel Flexibilität verleiht, die Sie sonst nicht hätten. De-normalisierte Daten sind ein Schmerz im Hintern.
quelle
Ich glaube nicht, dass eine WTF gerechtfertigt ist oder dass der Typ irgendeine geniale Art von Design macht - es ist eine ziemlich normale Datenbanknormalisierung.
Der Grund für die Abteilungstabelle ist, dass Sie, wenn Sie die Abteilungen nicht in einer separaten Tabelle ablegen, mit Benutzern in den Abteilungen "Verkauf", "Verkauf", "Verkäufer", "Segel" und "Verkauf" arbeiten müssen. es sei denn, Sie tun etwas, um dies zu verhindern. Und den Extratisch zu haben, ist der beste Weg, das zu tun.
Ob es eine UserDepartment-Tabelle geben soll, ist ein härterer Aufruf, was natürlich bedeutet, dass keine der beiden Entscheidungen aus dem Ruder läuft und verrückt ist. Einerseits ist es eine Qual, wenn all Ihre Tabellenkonstruktion und -logik eine Abteilung pro Benutzer angenommen hat und sich dann ändert, andererseits ist es eine echte Möglichkeit und auch eine Qual, jahrelang ohne Grund einen zusätzlichen Join durchzuführen.
Ich persönlich würde Ihnen zustimmen, dass die UserDepartment-Tabelle wahrscheinlich zu viel ist. Auch wenn es enthalten ist, besteht die Möglichkeit, dass die Leute im Laufe der Zeit Abfragen schreiben, bei denen davon ausgegangen wird, dass es nur einen Benutzer pro Abteilung gibt, sodass Sie am Ende das Schlimmste aus beiden Welten haben - ein zusätzlicher Join ohne Grund, bevor Sie den Tisch benötigen, und Code funktioniert sowieso nicht, wenn mehr als eine Abteilung pro Benutzer zulässig ist.
BEARBEITEN - Ein Schlüsselfaktor für die Unterstützung der Viele-zu-Viele-Beziehung ist, ob die Geschäftsregeln klar sind. Wenn Sie nicht wissen, wie ein Benutzer in mehreren Abteilungen arbeiten würde, macht das Hinzufügen der Tabelle nicht viel Sinn, da Ihr Code möglicherweise die Fälle nicht richtig handhaben kann, in denen sich ein Benutzer in mehreren Abteilungen befindet.
Stellen Sie sich vor, Sie hätten für alle Fälle viele Abteilungen pro Benutzer zugelassen. Anschließend haben Sie eine Geschäftsregel für die Zuordnung von Provisionen basierend auf der Abteilung implementiert. Dann waren mehrere Abteilungen erlaubt. Glücklicherweise hatten Sie auch die Voraussicht, Ihren Provisionscode so zu schreiben, dass dies berücksichtigt wurde. Leider haben Sie die Provisionen aus jeder Abteilung für Benutzer in beiden hinzugefügt . Das Management wollte, dass Sie sich bei jedem Verkauf auf die Rolle der Personen stützen. Wie gut war es also, den Tisch im Voraus zu haben? Was ist mit den anderen Tischen, die Sie "nur für den Fall" hatten, dass sie überhaupt nicht benötigt werden?
SPÄTERE BEARBEITUNG - Ein weiterer Grund, warum der Berater möglicherweise alle diese Zwischentabellen hinzufügen wollte, wird in dieser Folgefrage angesprochen. Die Antworten geben einige Gründe an, warum das Refactoring einer Datenbank in der Regel schwieriger ist als das Refactoring von Code, was Sie tendenziell drängt der Ansatz "Setzen Sie alle Tabellen ein, die Sie jemals benötigen könnten".
quelle
Wenn mehrere Abteilungen pro Benutzer erforderlich sein sollen, ist dieses Design sinnvoll. Der einzige Nachteil dabei ist,
UserDepartmentTable
dass ein ErsatzschlüsselUserDepartmentID
nicht benötigt wird (machen Sie einfach denUserId
undDepartmentId
einen zusammengesetzten Primärschlüssel).Wenn ein Benutzer immer nur einer Abteilung angehört, ist Ihr Entwurf sinnvoll (obwohl eine Abteilungsnachschlagetabelle immer noch eine gute Sache wäre).
quelle
Einige Anforderungen sind in Ihrer Frage nicht klar. Die richtige Antwort hängt davon ab, was Ihr Kunde wünscht. Wenn ich Sie wäre, würde ich den Kunden danach fragen:
0-Was ist der Unterschied zwischen einem Benutzer und einem Mitarbeiter?
1-Angenommen, ein Mitarbeiter = Benutzer, was ist, wenn ein Mitarbeiter die Abteilungen wechselt?
2-Kann eine Gruppe von Mitarbeitern 1 Anfrage stellen?
3-Kann ein Mitarbeiter mehreren Abteilungen angehören? Was ist mit dem CEO?
4-Gibt es eine Untergruppe von Mitarbeitern, die Anfragen stellen dürfen?
5-Was passiert mit der Anfrage, wenn ein Mitarbeiterdatensatz gelöscht wird (falls überhaupt)?
6-Könnten Sie eine Anfrage löschen? Was passiert, wenn die Anfrage nicht beantwortet wird? (Stellen Sie sicher, dass Sie den Mitarbeiterdatensatz von RI nicht löschen.)
7-Kann der Mitarbeiter die "gleiche" Anfrage mehr als einmal stellen (definieren Sie die "gleiche")
8-Wie gehe ich mit Anfragen für Mitarbeiter um, wenn sie das Unternehmen verlassen (storniere ihre Anfragen oder lösche die Anfragen?)
Es mag weitere Fragen geben, aber ich möchte betonen, dass die Lösung von den genauen Anforderungen und dem Projektumfang abhängt . Sobald dies bestimmt ist, kann das Schema direkt abgeleitet werden. Dementsprechend können beide vorgestellten Lösungen korrekt sein.
quelle
Ich möchte ein paar Punkte in Form von Notizen hinzufügen, die explizit auf einige der potenziellen Vorteile der Verwendung einer Join-Tabelle hinweisen, wie es Ihr hochbezahlter Berater getan hat.
UserDepartmentTable.Department
nicht "schwieriger" als das Nachschlagen einer anderen Spalte in derUser
Tabelle.UserDepartmentTable.Active
, das "false" lautet, und eine neue Zuordnung erstellen, die aktiv ist). Es ist auch möglich, eine Versionierung der Abteilungszuordnung mit dem Zweitabellenmodell (nur Benutzer und Abteilung) durchzuführen, dies ist jedoch schwieriger und erfordert das Hinzufügen mindestens einer weiteren Spalte oder das Ausführen von Datenbankakrobatik, um das Duplizieren von Primärschlüsseln zu vermeiden.Davon abgesehen gibt es mehrere Gründe, NICHT das zu tun, was Ihr hochbezahlter Berater getan hat.
quelle
Ohne die vollständige Struktur der benötigten Informationen kann ich nicht sagen, ob es schrecklich ist oder nicht. Zumindest das abgebildete Stück ist jedoch nicht von "WTF" -Design. Es scheint nur als 3. Normalform der Datenstruktur (na ja, wir haben theoretisch auch 4. und 5. auch)
Einige Gespräche können Platz für UserDepartmentTable zwischen zwei Schulen von "natürlichen" und "künstlichen" Schlüsseln im gezeigten Stück haben. Nichts mehr, wie ich sehen kann
Normalisierung ist aus vielen Gründen die Regel eines guten DB-Entwicklers / Designers. * De * Normalisierungen werden manchmal während der Entwicklung verwendet, um die Geschwindigkeit zu steigern
quelle