In vielen relationalen Datenbankdesigns gibt es Felder, auf die in anderen Tabellen verwiesen wird.
Betrachten Sie beispielsweise eine Benutzertabelle mit einem eindeutigen Benutzernamen und einer zweiten Tabelle, in der Adressdaten gespeichert sind.
Ein mögliches Layout, das ich sagen würde, ist der übliche Ansatz, den ich in den meisten Programmen beobachtet habe, die Verwendung von Auto-Inkrement-IDs wie folgt:
Table users
===========
userId int primary auto_increment
userName varchar unique
Table adressdata
==========
userId int references users.userId
adress_type varchar // for example country
address_value varchar // for example US
(you probably also want to put a unique key on (userId,adress_type))
So habe ich es gemacht und wie ich es in den meisten Fällen gesehen habe.
Ein anderer Weg wäre:
Table users
===========
userName varchar primary
Table adressdata
==========
userName varchar references users.userName
adress_type varchar // for example country
address_value varchar // for example US
(you probably also want to put a unique key on (userName,adress_type))
Hier speichern wir den vollständigen Benutzernamen auch in der Adressdata-Tabelle.
Für mich hat dies folgende Vorteile:
Sie können den Benutzernamen sofort aus der Tabelle auswählen, ohne ihn einer anderen Tabelle hinzufügen zu müssen. In diesem Beispiel ist dies aus Sicht der Anwendung wahrscheinlich nicht so relevant, aber es ist nur ein Beispiel.
Es ist möglicherweise einfacher, die Datenbank in einer Master-Master-Replikationsumgebung zu skalieren, da keine Konflikte mit der automatischen Inkrementierung vorliegen.
Aber auch die Nachteile:
- Der Platzbedarf für den Index und die Daten (aber relevanter wird wahrscheinlich der Index sein) für das Feld in der zweiten Tabelle ist höher.
- Eine Änderung des Benutzernamens müsste an alle Tabellen weitergegeben werden. Dies ist ressourcenintensiver als nur das Ändern in einer Tabelle und das Beibehalten der IDs.
Meiner Meinung nach ist es viel einfacher, mit Textfeldern zu arbeiten und keine Inkrement-IDs zu verwenden, und die Kompromisse sind minimal und in den meisten Anwendungen nicht relevant.
Natürlich werden einige Objekte aufgrund ihrer Art mit einer inkrementierenden Nummer identifiziert (z. B. sollten Forenbeiträge eine inkrementierende ID erhalten, da es wahrscheinlich kein anderes eindeutiges Feld wie den Titel oder so gibt).
Bevor ich jedoch anfange, meine Datenbanklayouts ganz anders zu gestalten, möchte ich wissen, ob es Dinge gibt, an die ich nicht gedacht habe.
Gibt es Best Practices?
Gibt es Vor- / Nachteile, an die ich nicht gedacht habe und deren Auswirkungen zu einem späteren Zeitpunkt auftreten können?
Wie gestalten Sie persönlich Datenbanken zu den oben genannten Punkten und warum?
Ich werde aus meiner Erfahrung posten, die sich wahrscheinlich stark von den verschiedenen DBAs unterscheiden wird. Ich bin hauptsächlich auf eine Mischung aus Leistung und Wartbarkeit ausgerichtet, wenn ich Datenbanken für verschiedene Projekte entwerfe.
Ich würde niemals einen natürlichen Schlüssel als Primärschlüssel verwenden. Besonders wenn ich MySQL / InnoDB benutze. Ich habe immer noch keinen Vorteil bei der Verwendung eines natürlichen Schlüssels gesehen. Normalerweise sehe ich Auswirkungen auf die Leistung, wenn nichts. Ich habe "nie, nie" nur deshalb gewagt, weil natürliche Schlüssel verwendet wurden, um Leistungsfresser für meine Projekte zu erstellen. Surrogate (Integer) war immer eine bessere Wahl. Einige mögen nicht zustimmen, aber wir leben in einer Welt, in der Leistung eine Rolle gegenüber der Theorie spielt.
Wenn es um JOINs geht, versuche ich nicht, sie um jeden Preis zu vermeiden, aber ich tendiere dazu, sie zu optimieren. Ich versuche, den Clustered-Index (Primärschlüssel) von InnoDB so weit wie möglich zu missbrauchen. Wenn JOINs über PKs ausgeführt werden, sind sie extrem schnell. Ich neige auch dazu, FKs zu vermeiden, bei denen sie keinen Sinn ergeben. Ehrlich gesagt würde mir die Datenintegrität beim Verknüpfen von Benutzern und ihren Adressinformationen nicht so viel ausmachen. Ich würde es erzwingen, wenn ich Rechnungen mit Artikeln an Benutzer verknüpfe. Die Überbeanspruchung von FKs ist ein Overkill und ein Albtraum, den man aufrechterhalten muss, nachdem man sich auf alles bezogen hat. Irgendwann müssen sich die Dinge ändern, und wenn MySQL sich ständig über Fehler 150 beschwert, möchten Sie einfach nach Hause gehen.
Sie haben auch die Replikation und die Vermeidung von Konflikten aufgrund der Art von auto_increments erwähnt. Ich hatte ein Projekt, in dem wir eine Anzahl von Datenbanken hatten, in denen Produktverkaufsinformationen gespeichert waren. Die Anzahl der Datenbanken war variabel. Jeden Tag wurden die Datenbanken in eine "Master" -Datenbank repliziert, mit der wir Berichte ausgeführt haben. Ich habe PK-Konflikte vermieden, indem ich aus einem auto_increment-Teil und einem anderen INT-Teil einen zusammengesetzten Primärschlüssel erstellt habe, der den Ort angibt, von dem der Datensatz stammt. Auf diese Weise konnte ich verfolgen, woher die Dinge kamen, und ich habe nichts verloren (Produkte hatten dieselbe ID, nur die Standortkennung wurde geändert).
quelle