Was ist eine effektive Methode zum Beschriften von Spalten in einer Datenbank?

30

Früher habe ich Spalten in meinen Datenbanken folgendermaßen beschriftet:

user_id
user_name
user_password_hash

Um Konflikte beim Verknüpfen von zwei Tabellen zu vermeiden, habe ich dann mehr über das Aliasing von Tabellen gelernt und aufgehört, dies zu tun.

Was ist eine effektive Methode zum Beschriften von Spalten in einer Datenbank? Warum?

Thomas O.
quelle
Welche Datenbank? Die Beschriftung in Oracle unterscheidet sich von den meisten anderen Datenbanken durch die automatische Auswahl von Spalten für Basis-Joins, wenn die Namen übereinstimmen.
Joe
@ Joe Nun, ich habe immer MySQL und SQLite3 verwendet, aber es sollte für die meisten anderen Datenbanken gelten.
Thomas O
@ Joe hat nie bemerkt, dass Oracle anders ist. Kannst du einen Link geben?
bernd_k
@bernd_k: Ich habe unten einige Links zu meiner Antwort hinzugefügt
Joe

Antworten:

33

In Ihrem Fall ist der Präfixbenutzer redundant. Wir (die zuständigen Entwickler) wissen, dass dies der Tabellenbenutzer ist. Warum also user_vor jedem Feld ein Präfix einfügen ?

Ich würde Ihnen vorschlagen, dies mit einem natürlicheren Ansatz zu tun.

Was sind die Merkmale einer Person: Nachname, Vorname, Geburtsdatum, Nationalität, etc ...

Was sind die Eigenschaften eines Autos: Modell, Jahr, Farbe, Energie, etc ...

Ihre Spalte sollte so natürlich wie möglich benannt werden, damit das Schema für alle klarer wird, für Sie und für diejenigen, die nach Ihnen kommen. Dies wird auch als Wartungsphase bezeichnet. Alles, was Sie tun können, um die Wartung zu vereinfachen, ist in der Regel die Mühe wert.

Spredzy
quelle
1
Ja, es macht mich wütend, wenn Leute das tun. Auch wenn sie alle ihre Tabellen tbl_whatever aufrufen.
Gaius
Dies ist auch für das Konzept der "Klassenwörter" relevant, und es scheint eine Debatte in der Community zu geben, wenn Klassenwörter angemessen sind und nicht. (Ein Klassenwort ist ein Werkzeug, um: eine bestimmte Kategorie oder Klassifikation von Daten zu identifizieren, den durch den Datennamen beschriebenen Datentyp abzugrenzen und die Hauptklassifikation von Daten zu beschreiben, die einem Datenelement zugeordnet sind.)
Jon Schoning
17

Beschriften Sie zusätzlich zu Spredzys Kommentar Ihre Primärschlüssel mit derselben (ID), damit Sie sich beim Schreiben von Abfragen im laufenden Betrieb leicht daran erinnern können (u.ID = c.ID), anstatt nachzuschlagen "War es countryID" , country_ID, countries_ID, countriesID,? "

David Hall
quelle
5
Ich habe einmal an einer Datenbank gearbeitet, in der der DBA beschlossen hat, ID in einigen Tabellen und ID in anderen zu verwenden, und wir haben MySQL so eingerichtet, dass Groß- und Kleinschreibung beachtet wird ... unterhaltsame Zeiten!
Toby
6
Wir verwenden normalerweise tablename.tablename_id. ZB car.car_id; person.person_id. Singuläre Namen für Tabellen.
Glasnt
@glasnt kluge Entscheidung.
Garik
1
Dies ist eigentlich eine sehr schlechte Idee, und Sie verlieren die Möglichkeit, die SQL- USINGKlausel zu verwenden (dies verstößt gegen die Spezifikation).
Evan Carroll
9

Ich könnte David Halls Nachtrag zu Spredzys hervorragender Antwort nicht mehr zustimmen. Einfach und natürlich ist der Weg zu gehen. Tabellenverwirrung sollte kein Problem sein, wenn Sie Tabellen natürlich auch benennen.

Es macht keinen Sinn, users.user_id und cars.car_id zu haben, wenn Sie users.id und cars.id haben könnten

bsoist
quelle
7

Ich würde argumentieren, dass in einem Datenbankschema jede Spalte über Tabellen hinweg einen eindeutigen Namen haben sollte. Dafür gibt es mehrere Gründe:

  • Aus Sicht der Modellierung: Sie beginnen mit einer Menge von Attributen und normalisieren diese in Tabellen. Im Laufe der Zeit können Sie möglicherweise denormalisieren oder weiter normalisieren oder Ansichten oder materialisierte Ansichten einführen oder neue Tabellen einführen. Dies ist kein Problem, wenn alle Spaltennamen eindeutig sind.

  • Sie können diese Join - Syntax verwenden: a JOIN b USING (a_id) JOIN c USING (a_id). Sehr praktisch und hilft auch bei folgendem Punkt.

  • Wenn Sie Abfragen mit vielen Verknüpfungen ausführen oder materialisierte Ansichten mit erstellen SELECT *, wird es nie (naja, vielleicht selten) zu Konflikten kommen. Denken Sie über den Beitritt zu person.name, product.name, country.nameetc. Urgh.

  • Wenn Sie große Fragen haben, ist es im Allgemeinen schwierig zu verfolgen, was idüberall bedeutet.

Peter Eisentraut
quelle
Wie würden Sie die Spalte zum Beispiel für einen Mitarbeiternamen und einen Site-Namen benennen? Wie würden Sie die Redundanz der Namensschildspalte vermeiden?
Spredzy
@Spredzy: Ich würde einfach mit der Redundanz gehen.
Peter Eisentraut
1
Die Antwort auf diese Bedenken: Aliase.
Jon of All Trades
7

Mal sehen, mit deinem Beispiel sieht es so aus:

USERS
----
id
username,
password
registration_date

Ich benutze den Tabellennamen in Großbuchstaben. Dadurch kann ich die Tabelle leicht identifizieren. Die Spalten, die ich gerade benannt habe, entsprechen jeweils dem, was sie darstellen. Ich versuche, keine Zahlen zu verwenden oder Präfixe oder Suffixe hinzuzufügen. Dies macht die Abfragen sehr einfach und ziemlich unkompliziert.

Übrigens, ich denke, Sie sollten einen Stil finden, den Sie mögen, und dabei bleiben. Wenn Sie es häufig ändern, erhalten Sie ein unordentlicheres DB-Schema.

Eiefai
quelle
+1 für "Finde einen Stil, den du magst und bleibe dabei." Konsistenz ist besser als die genaue Einhaltung eines bestimmten Standards (wenn Sie jedoch noch keinen Standard ausgewählt haben, sind einige besser als andere).
Jon of All Trades
5

Wie die anderen empfehle ich, dass Sie den Tabellennamen nicht als Teil der Spalte einschließen. Es sei denn, Sie haben Hunderte von Tabellen mit zumeist ähnlichen Spaltennamen. Wenn Sie mehrere Dutzend Tabellen mit einer Spalten-ID haben, müssen Sie diesen unbedingt den Tabellennamen voranstellen.

Ich habe kürzlich eine Firma verlassen, in der einer der Entwickler es vorgezogen hat, Primärschlüssel- und Fremdschlüsselspalten mit pk und fk zu versehen. Dies führte zu einigen Gräueln, bei denen Spalten mit pkfk begannen (normalerweise ein zusammengesetzter Primärschlüssel, der auf 2 Spalten basiert, von denen eine Spalte ein Fremdschlüssel für eine andere Tabelle war).

Tangurena
quelle
4
zählt das als fk_cluster?
Kaji
5

Ich arbeite in einer Umgebung, in der jeder Spaltenname mit einem vom Tabellennamen abgeleiteten Präfix beginnt. Es ist nicht meine Erfindung, aber ich bin sehr zufrieden damit.

Im Idealfall sind Spaltennamen für alle Tabellen in der Datenbank eindeutig.

Einige Beobachtungen:

  • Wir brauchen nur Tabellen-Aliase, wenn Tabellen in einer select-Anweisung mehrfach verknüpft werden
  • Dies verhindert einige Fehler beim Kopieren von Codeausschnitten, da die Spaltennamen an den Tabellennamen angepasst werden müssen
  • Es ist hilfreich zu zeigen, auf welche Tabelle eine Fremdschlüsselspalte verweist

Allgemeine Ideen: Am wichtigsten ist die Konsistenz der einzelnen Namenskonventionen: - Singular vs. Plural (ok, gilt für Tabellen und nicht für Spalten) - Identifizieren von Primär- und Fremdschlüsseln (sie bilden die Struktur gegenüber dem Inhalt der Datenbank) - Seien Sie konsistent, wenn Sie speichern Strings und kurze Varianten desselben Strings - stimmen mit Flags, Status usw. überein.

bernd_k
quelle
3

Ich stimme Spredzys Antwort zu, möchte aber hinzufügen, dass ich camelCase anstelle von under_score verwenden würde.

Vorname, Nachname usw.

Toby
quelle
2
-1, weil CamelCase nicht in allen Datenbanksystemen funktioniert und Sie kein Datenbanksystem angegeben haben. Zum Beispiel ist es eine schlechte Nachricht, CamelCase in Oracle zu verwenden (es würde doppelte Anführungszeichen erfordern, um es zu erstellen, aber von da an müsste jeder, der darauf zugreift, durch Rahmen springen, um darauf zuzugreifen / es zu verwenden). Was ein Alptraum.
ScottCher
@ScottCher - Ich wusste nicht, dass es in Oracle nicht funktioniert, aber dann bin ich kein Oracle-DBA. Ich hätte gedacht, dass es eine Selbstverständlichkeit ist, dass die Spaltennamen zuerst den Regeln des betreffenden DBS entsprechen müssen.
Toby
3

Im Fall von Oracle, möchten Sie nicht generische Spalten ‚id‘ oder ‚name‘ oder irgendetwas nennen.

Das Problem ist, dass Oracle in älteren Versionen standardmäßig versucht, Tabellen anhand ähnlicher Spaltennamen zu verknüpfen. Wenn ich also alles richtig benannt habe, habe ich auch die Standardverbindungsklausel zwischen meinen Tabellen angegeben.

Aber auch wenn Sie nicht Oracle verwenden, indem sie nicht Namen chosing , die in mehreren Tabellen erscheinen, es bedeutet auch , dass Sie nicht dann durch die Mühe machen müssen , um jedes Mal von Aliasing Sie wählen über zwei Tabellen zu tun haben:

SELECT
  instrument.name as instrument_name,
  instrument.abbr as instrument_abbr,
  source.name     as source_name,
  source.abbr     as source_abbr,
  ...
FROM ...

Wenn also Mehrtabellenauswahlen die Norm sind, ersparen längere Spaltennamen die Eingabe. (Wenn Sie jeweils nur eine Tabelle verwenden ... benötigen Sie wirklich sogar eine relationale Datenbank?)

... und das Speichern der Eingabe bringt uns zu einem weiteren Problem in Oracle - zumindest in 8i (der aktuellen Version, als ich an den Kursen zu Oracle SQL - Optimierung und Datenmodellierung teilgenommen habe). Das Zwischenspeichern von Ausführungsplänen basiert nur auf den ersten so vielen Zeichen der query (kann sich nicht an den exakten Wert erinnern ... 1024?). Wenn Sie also Abfragen haben, die sich nur am Ende der where-Klausel um etwas ändern, und eine wirklich lange Liste von Spalten, die Sie extrahieren, dann haben Sie kann auf einen Leistungstreffer stoßen, da der Ausführungsplan nicht korrekt zwischengespeichert werden kann.

Oracle hatte einen Leitfaden zur Auswahl der angeblich guten Tabellen- und Spaltennamen, der im Grunde genommen ein Leitfaden zum Entfernen von Buchstaben ist, bis es sich um 5 bis 8 Zeichen handelt, aber ich habe mich nie darum gekümmert.

...

Wie die Dinge anders laufen:

  • Spalten sind immer singulär (Tabellen sind immer plural)
  • Alle Namen werden in Kleinbuchstaben geschrieben, nur für den Fall, dass zwischen Groß- und Kleinschreibung unterschieden wird
  • Verwenden Sie daher Unterstriche anstelle des Kamelkastens.

Update : Für diejenigen, die mit dem Join-Verhalten von Oracle nicht vertraut sind, siehe das letzte Beispiel zur Beherrschung von Oracle SQL: Join-Bedingungen , in dem Folgendes erwähnt wird:

Was ist passiert? Der Grund liegt darin, dass diese beiden Tabellen neben supplier_id ein weiteres Spaltenpaar mit einem gemeinsamen Namen haben. Diese Spalte heißt name. Wenn Sie also einen natürlichen Join zwischen dem Lieferanten und den Teiletabellen anfordern, erfolgt der Join nicht nur durch Gleichsetzen der Spalte supplier_id der beiden Tabellen, sondern auch durch Gleichsetzen der Namensspalte aus den beiden Tabellen. Da kein Lieferantenname mit einem Teilenamen desselben Lieferanten identisch ist, werden von der Abfrage keine Zeilen zurückgegeben.

Unter der 'alten Join-Syntax' (8i und früher) war 'NATURAL JOIN' das Standard-Join-Verhalten, und ich glaube, es ist immer noch so, wenn Sie keine Join-Bedingung angeben. Als 'NATURAL JOIN' in 9i eine offizielle Option war, wurde generell empfohlen, es nicht zu verwenden , da eine schlechte Spaltenbenennung Sie durcheinander bringen kann. Ich befürworte daher gute Spaltennamen.

Joe
quelle
4
Sie beziehen sich in Ihrem zweiten Absatz auf "Natural Joins"? Wenn ja, SHUDDER ... Wenn möglich, sollten Sie angeben, wie Ihr Datenbanksystem Ihre Tabellen verknüpfen soll. Wenn Sie die Entscheidung der Datenbank überlassen, kann dies zu unerwarteten / inkonsistenten Ergebnissen führen. Außerdem sind natürliche Verknüpfungen auf Verknüpfungen zwischen zwei Tabellen beschränkt und daher in ihrer Verwendbarkeit relativ eingeschränkt.
ScottCher
2
NATURAL JOIN war noch nie die Standardeinstellung. Wenn keine explizite Verknüpfung angegeben ist / wurde, wird eine kartesische Verknüpfung durchgeführt (dh jede Zeile in einer Tabelle wird mit jeder Zeile in der anderen Tabelle verknüpft). Bevor ANSI-Joins unterstützt wurden (dh die in der FROM-Klausel angegebenen), mussten Joins in der WHERE-Klausel ausgeführt werden.
Gary
1
-1 für natürliche Verknüpfungen. Wenn eine Änderung des Schemas, die nichts mit ihm zu tun hat, zu einer Unterbrechung der Verknüpfungen führen kann oder, noch schlimmer, zu einer fehlerfreien Änderung der Verknüpfungen. Denken Sie bitte an die Kinder, und geben Sie IMMER Ihre Join-Felder an.
Jon of All Trades
2
@ScottCher: "Überlassen Sie die Entscheidung der Datenbank" - zuerst meinen Sie vermutlich "DBMS" und nicht "Datenbank". Zweitens gibt es in Oracle keine KI oder keinen anthropomorphistischen Mechanismus. ist vielmehr NATURAL JOINdeterministisch.
Tag, wenn
1
@ Joe cross joinist, war und wird immer der 'Standard' sein. Oracle hat noch nie eine Übereinstimmung für den Spaltennamen gefunden, es natural joinsei denn, dies wurde ausdrücklich verwendet
Jack Douglas
1
  1. Verwenden Sie niemals doppelte Anführungszeichen, "da Sie dadurch die native Groß- / Kleinschreibung der Datenbank überschreiben. Die SQL-Spezifikation fordert, dass alle Bezeichner in Großbuchstaben umgewandelt werden. Einige Datenbanken, wie PostgreSQL, falten sie in Kleinbuchstaben. Wenn nichts in Anführungszeichen steht, funktioniert es in allen Datenbanken und sie können sie auf die Spezifikation oder die rdbms-spezifischen Standardeinstellungen falten.
  2. Verwenden Sie under_score ( _), da Sie, wie oben beschrieben, camelCase nicht verwenden sollten.
  3. Verwenden Sie {entity}_idfür IDs (und Fremdschlüssel, die auf diese IDs verweisen). Denn dann können Sie die USINGKlausel verwenden. Die in Join-Bedingungen verwendeten global eindeutigen Schlüsselnamen sind eine in der Spezifikation festgelegte Konvention.

    SELECT *
    FROM employee
    INNER JOIN department
      USING (department_id);
    
      -- compare to
      ON employee.department_id = department.department_id;
Neil McGuigan
quelle
1
Ich habe dies aktualisiert, um es expliziter zu machen.
Evan Carroll