Mir wurde beigebracht, den Namen Id
nicht für die Identitätsspalte meiner Tabellen zu verwenden, aber in letzter Zeit habe ich ihn sowieso nur verwendet, weil er einfach, kurz und sehr aussagekräftig ist, was die Daten tatsächlich sind.
Ich habe gesehen, wie Leute vorgeschlagen haben, Id
den Tabellennamen voranzustellen, aber dies scheint nur für die Person, die die SQL-Abfragen schreibt (oder für den Programmierer, wenn Sie ein ORM wie Entity Framework verwenden), mehr Arbeit zu bedeuten bei längeren Tabellennamen wie CustomerProductId
oder AgencyGroupAssignementId
Ein Drittanbieter, den wir beauftragt haben, etwas für uns zu erstellen, hat tatsächlich alle seine Identitätsspalten Ident
benannt, um die Verwendung von Id
zu vermeiden. Zuerst dachte ich, dass sie das getan haben, weil Id
ein Schlüsselwort war, aber als ich es mir ansah, stellte ich fest, dass Id
kein Schlüsselwort in SQL Server 2005 ist, was wir verwenden .
Warum empfehlen die Leute, den Namen Id
nicht für eine Identitätsspalte zu verwenden?
Edit : Zur Verdeutlichung frage ich nicht, welche Namenskonvention verwendet werden soll oder ob Argumente eine Namenskonvention über der anderen verwenden sollen. Ich möchte nur wissen, warum empfohlen wird, Id
nicht für den Namen der Identitätsspalte zu verwenden.
Ich bin ein einzelner Programmierer, kein dba, und für mich ist die Datenbank nur ein Ort zum Speichern meiner Daten. Da ich normalerweise kleine Apps erstelle und normalerweise ein ORM für den Datenzugriff verwende, ist es viel einfacher, mit einem allgemeinen Feldnamen für das Identitätsfeld zu arbeiten. Ich möchte wissen, was mir dadurch entgeht und ob es wirklich gute Gründe für mich gibt, dies nicht zu tun.
Hier ist eine Zusammenfassung aller Antworten zu den Vorteilen der Konvention, nicht für alle Primärschlüssel einen gemeinsamen Namen zu verwenden:
Weniger Fehler, da die Identitätsfelder nicht gleich benannt sind
Sie können nicht fälschlicherweise eine Abfrage schreiben, die sich mit B.Id = B.Id
Anstelle von A.Id = B.Id
Verbindet, da die Identitätsfelder niemals exakt gleich benannt werden.
Klarere Spaltennamen.
Wenn Sie sich eine Spalte mit dem Namen CustomerId
ansehen, wissen Sie sofort, welche Daten sich in dieser Spalte befinden. Wenn der Spaltenname etwas Generisches wie Id
war, müssen Sie auch den Tabellennamen kennen, um zu wissen, welche Daten die Spalte enthält.
Vermeidet unnötige Spaltenaliasnamen
Sie können jetzt SELECT CustomerId, ProductId
Aus einer Abfrage schreiben, die Customers
mit Products
anstelle von SELECT Customer.Id as CustomerId, Products.Id as ProductId
Verbindet.
Ermöglicht die Syntax JOIN..USING
Sie können Tabellen mit der Syntax Customer JOIN Products USING (CustomerId)
anstelle von Customer JOIN Products ON Customer.Id = Products.Id
Verknüpfen.
Der Schlüssel ist bei der Suche leichter zu finden
Wenn Sie in einer großen Lösung nach dem Identitätsfeld eines Kunden suchen, ist die Suche nach CustomerId
weitaus nützlicher als die Suche nach Id
Wenn Sie sich weitere Vorteile dieser Namenskonvention vorstellen können, lassen Sie es mich wissen und ich werde sie der Liste hinzufügen.
Ob Sie eindeutige oder identische Spaltennamen für Identitätsfelder verwenden, liegt bei Ihnen. Unabhängig von Ihrer Auswahl sollten Sie jedoch konsistent sein :)
Das Tabellennamenpräfix hat sehr gute Gründe.
Erwägen:
TableA (id int identity, stringdata varchar(max))
TableB (id int identity, stringdata varchar(max))
Wir wollen DELETE
aus TableA
Datensätzen, die in beiden Tabellen vorhanden sind. Einfach genug, wir machen einfach ein INNER JOIN
:
DELETE a
FROM
TableA A
INNER JOIN
TableB B
ON b.id = B.id
....nd wir haben gerade alle TableA
gelöscht. Wir haben versehentlich die ID von B mit sich selbst verglichen - jeder Datensatz stimmte überein und jeder Datensatz wurde gelöscht.
Wenn die Felder TableAId
und TableBId
genannt worden wären, wäre dies unmöglich (Invalid field name TableAid in TableB
).
Persönlich habe ich kein Problem mit der Verwendung des Namens id
in einer Tabelle, aber es ist wirklich eine bessere Praxis, ihm den Tabellennamen (oder den Entitätsnamen, wenn TableA
Personen waren, dann PeopleId
würde auch gut funktionieren), um zu vermeiden, dass versehentlich mit dem falschen Feld verglichen und etwas in die Luft gesprengt wird.
Dies macht auch sehr deutlich, woher Felder in langen Abfragen mit vielen JOIN
s stammen.
Meistens soll verhindert werden, dass Fremdschlüssel zu einem enormen Schmerz werden. Angenommen, Sie haben zwei Tabellen: Customer und CustomerAddress. Der Primärschlüssel für beide ist eine Spalte mit dem Namen id, bei der es sich um eine Identitätsspalte (int) handelt.
Jetzt muss die Kunden-ID von CustomerAddress referenziert werden. Sie können die Spalten-ID natürlich nicht benennen, also entscheiden Sie sich für customer_id.
Dies führt zu einigen Problemen. Zunächst müssen Sie sich immer daran erinnern, wann Sie die Spalte "id" und wann Sie "customer_id" aufrufen müssen. Und wenn Sie dies vermasseln, führt dies zum zweiten Problem. Wenn Sie eine große Abfrage mit etwa einem Dutzend Joins haben und keine Daten zurückgeben, haben Sie Spaß beim Spielen von Where's Waldo und bei der Suche nach diesem Tippfehler:
ON c.id = ca.id
Hoppla, hätte ON c.id = ca.customer_id
Sein sollen. Oder noch besser, benennen Sie Ihre Identitätsspalten beschreibend, damit es ON c.customer_id = ca.customer_id
Sein kann. Wenn Sie dann versehentlich irgendwo den falschen Tabellenalias verwenden, ist customer_id keine Spalte in dieser Tabelle, und Sie erhalten einen netten Kompilierungsfehler, anstatt leere Ergebnisse und nachfolgendes Code-Schielen.
Zugegeben, es gibt Fälle, in denen dies nicht hilft, z. B. wenn Sie mehrere Fremdschlüsselbeziehungen von einer Tabelle zu einer anderen einzelnen Tabelle benötigen, aber die Benennung aller Primärschlüssel "id" auch dort nicht hilft.
So kopieren Sie meine Antwort von der verknüpften Frage:
Es gibt eine Situation, in der es nicht die beste Idee ist, "ID" in jede Tabelle zu stecken: das Schlüsselwort USING
, falls es unterstützt wird. Wir verwenden es oft in MySQL.
Wenn Sie beispielsweise fooTable
mit der Spalte fooTableId
und barTable
mit dem Fremdschlüssel fooTableId
haben, können Ihre Abfragen wie folgt erstellt werden:
SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)
Es spart nicht nur das Tippen, sondern ist im Vergleich zur Alternative viel besser lesbar:
SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
Nach dem Normalisieren eines Datenbankschemas zur Begrenzung der Redundanz werden Tabellen in kleinere Tabellen mit festgelegten Beziehungen (eins zu eins, eins zu viele, viele zu viele) unterteilt. Dabei können einzelne Felder in der Originaltabelle in mehreren normalisierten Tabellen erscheinen.
Beispielsweise könnte eine Datenbank für ein Blog in ihrer nicht normalisierten Form so aussehen, wenn eine eindeutige Einschränkung für den Autorennamen angenommen wird.
| Author_Nickname | Author_Email | Post_Title | Post_Body |
+-----------------+--------------+------------+-----------+
| dave | [email protected] | Blah | Bla bla |
| dave | [email protected] | Stuff | I like |
| sophie | [email protected] | Lorem | Ipsum |
Eine Normalisierung würde zwei Tabellen ergeben:
Autor:
| Author_Nickname | Author_Email |
+-----------------+--------------+
| dave | [email protected] |
| sophie | [email protected] |
Post
| Author_Nickname | Post_Title | Post_Body |
+-----------------+------------+-----------+
| dave | Blah | Bla bla |
| dave | Stuff | I like |
| sophie | Lorem | Ipsum |
Hier wäre Author_Nickname ein Primärschlüssel für die Autorentabelle und ein Fremdschlüssel in der Post-Tabelle. Selbst wenn Author_Nickname in zwei Tabellen angezeigt wird, entspricht er immer noch einer einzelnen Informationseinheit, d. H. jeder Spaltenname entspricht einem einzelnen Feld.
In vielen Fällen kann es keine eindeutige Einschränkung für die ursprünglichen Felder geben, daher wird stattdessen ein numerisches künstliches Feld als Primärschlüssel verwendet. Dies ändert nichts an der Tatsache, dass jeder Spaltenname immer noch ein einzelnes Feld darstellt. Im herkömmlichen Datenbankdesign entsprechen einzelne Spaltennamen einzelnen Feldern, auch wenn sie keine Schlüssel sind. (zB würde man eher part.partname und client.clientname verwenden als part.name und client.name ). Dies ist der Grund für die Existenz des INNER JOIN ... USING <key>
und der NATURAL JOIN
Syntax.
Heutzutage und mit ORM-Schichten, die in vielen Sprachen leicht verfügbar sind, werden Datenbanken häufig als Persistenzschicht für OO Sprachen) entworfen, in denen es natürlich ist, dass Variablen in verschiedenen Klassen dieselbe Rolle spielen werden gleich ( part.name und client.name genannt, nicht part.partname und client.clientname ). In einem solchen Kontext Ich neige dazu, 'ID' für meine Primärschlüssel zu verwenden.
Ein Drittanbieter, den wir beauftragt haben, etwas für uns zu erstellen, hat tatsächlich alle Identitätsspalten Ident benannt, um die Verwendung von Id zu vermeiden.
Die Verwendung von "Ident" anstelle von "Id" löst nichts, wenn "Ident" für alle Tabellen verwendet wird.
Es gibt einen guten Artikel über SQL-Codierungskonventionen auf der Drupal Site , der eine gute Vorgehensweise für diese Situation angibt:
Es wird empfohlen, Tabellennamen den Modulnamen voranzustellen, um mögliche Namespace-Konflikte zu vermeiden.
Unter diesem Gesichtspunkt sind CustomerProductId und AgencyGroupAssignmentId sinnvoll zu verwenden. Ja, es ist ziemlich ausführlich. Sie könnten es verkürzen, aber der größte Punkt, mit dem Sie sich dann befassen müssen, ist , ob der Entwickler, der Ihnen folgt, versteht, was Sie gemeint haben . Mit ausführlichen Tabellennamen vorangestellte IDs sollten keine Unklarheiten darüber hinterlassen, was sie sind. Und (für mich) das ist wichtiger als ein paar Tastenanschläge zu sparen.
Ich benenne meine Spalten CustomerID anstelle von ID, also wann immer ich tippe
FROM dbo.Customers AS c JOIN dbo.CustomerOrders AS o
Die SQL-Eingabeaufforderung schlägt sofort Folgendes vor
ON c.CustomerID = o.CustomerID
Das erspart mir ein paar Tastenanschläge. Dennoch denke ich, dass Namenskonventionen sehr subjektiv sind und als solche habe ich auf die eine oder andere Weise keine starke Meinung.
Es ist der gleiche Grund, warum Sie nicht alle Ihre varchar-Felder so benennen würden wie "UserText" und "UserText1" oder warum Sie nicht "UserDate" und "UserDate1" verwenden würden.
Wenn Sie ein Identitätsfeld in einer Tabelle haben, ist dies normalerweise Ihr Primärschlüssel. Wie würden Sie eine untergeordnete Tabelle mit einem Fremdschlüssel für eine übergeordnete Tabelle erstellen, wenn der Primärschlüssel in beiden Tabellen id wäre?
Nicht jeder stimmt dieser Methode zu, aber in meinen Datenbanken ordne ich jeder Tabelle eine eindeutige Abkürzung zu. Die PK für diese Tabelle würde PK_ [abbrv] ID heißen. WENN das irgendwo als FK verwendet wird, würde ich die ID FK_ [abbrv] verwenden. Jetzt habe ich keine Vermutungen mehr, um herauszufinden, wie die Tabellenbeziehungen aussehen.
Aus dem gleichen Grund benennen Sie normalerweise nicht die Parameter parameter1, parameter2 ... es ist korrekt, aber nicht beschreibend. Wenn Sie TableId sehen, können Sie wahrscheinlich davon ausgehen, dass es verwendet wird, um ein pk für Table zu speichern, unabhängig vom Kontext.
Wer Ident verwendet hat, verfehlt den Punkt völlig, da er zwischen Ident und ID wählen kann. Ident ist noch verwirrender als Id.
Außerhalb des Kontexts kann angenommen werden, dass ID der Primärschlüssel für eine Tabelle ist (nicht sehr nützlich, es sei denn, die ID ist eine Richtlinie), aber Ident sagt Ihnen (oder zumindest mir) das nicht einmal. Ich würde irgendwann herausfinden, dass Ident für Identität steht (auf die eine oder andere Weise), aber die Zeit, die ich damit verbracht habe, das herauszufinden, wäre verschwendet.
Verwenden Sie ein Präfix, damit der gleiche Name sowohl im Primärschlüssel- als auch im Fremdschlüsselkontext verwendet werden kann, sodass Sie natural join
/join ... using
Ausführen können.