Warum wird das Benennen der Primärschlüsselspalte einer Tabelle mit "ID" als fehlerhaft angesehen? [geschlossen]


210

Mein t-sql-Lehrer sagte uns, dass die Benennung unserer PK-Spalte "Id" ohne weitere Erklärungen als schlechte Praxis angesehen wird.

Warum wird die Benennung einer PK-Tabellenspalte mit "ID" als unangemessen angesehen?


27
Nun, es ist eigentlich keine Beschreibung und Id bedeutet "Identität", was sehr selbsterklärend ist. Das ist meine meinung
Jean-Philippe Leclerc

49
Ich bin mir sicher, dass es viele Geschäfte gibt, die Id als PK-Namen verwenden. Ich persönlich benutze TableId als meine Namenskonvention, würde aber niemandem den EINZIGEN WAHREN WEG nennen. Es hört sich so an, als würde Ihre Lehrerin nur versuchen, ihre Meinung als allgemein akzeptierte Best Practice zu präsentieren.

22
Definitiv die Art der schlechten Praxis, die nicht so schlecht ist. Es geht darum, konsistent zu werden. Wenn Sie id verwenden, verwenden Sie es überall oder verwenden Sie es nicht.
Deadalnix

57
Du hast einen Tisch ... er heißt People, er hat eine Spalte namens Id. Was denkst du, ist die Id? Einen Wagen? Ein Boot? ... nein, es ist die People Id, das ist es. Ich denke nicht, dass es keine schlechte Praxis ist und es nicht notwendig ist, der PK-Spalte einen anderen Namen als ID zu geben.
jim

38
Also steigt der Lehrer vor die Klasse und sagt dir, dass dies eine schlechte Übung ohne einen einzigen Grund ist? Das ist eine schlimmere Praxis für einen Lehrer.
JeffO

Antworten:


247

Ich werde herauskommen und es sagen: Es ist keine wirklich schlechte Praxis (und selbst wenn es so ist, ist es nicht so schlecht).

Sie könnten das Argument vorbringen (wie Chad betonte), dass es Fehler wie in der folgenden Abfrage maskieren kann:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Dies kann jedoch leicht gemildert werden, indem für Ihre Tabellennamen keine winzigen Aliase verwendet werden:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

Die Praxis, IMMER 3-Buchstaben-Abkürzungen zu verwenden, erscheint mir viel schlimmer als die Verwendung des Spaltennamens id. (Beispiel: Wer würde eigentlich den Tabellennamen carsmit der Abkürzung abkürzen car? Welchem ​​Zweck dient das?)

Der Punkt ist: konsequent sein. Wenn Ihr Unternehmen die ID verwendet und Sie häufig den oben genannten Fehler machen, werden Sie sich angewöhnen, vollständige Tabellennamen zu verwenden. Wenn Ihr Unternehmen die Spalte "ID" verbietet, nehmen Sie sie in Kauf und verwenden Sie die von Ihnen bevorzugte Namenskonvention.

Konzentrieren Sie sich darauf, Dinge zu lernen, die WIRKLICH schlechte Praktiken sind (z. B. mehrere verschachtelte, korrelierte Unterabfragen), anstatt über solche Probleme nachzudenken. Das Problem, Ihre Spalten mit "ID" zu bezeichnen, ist eher eine Geschmackssache als eine schlechte Praxis.


HINWEIS FÜR DIE HERAUSGEBER: Der Fehler in dieser Abfrage ist beabsichtigt und wird verwendet, um einen Punkt zu machen. Bitte lesen Sie die vollständige Antwort, bevor Sie sie bearbeiten.


1
@Chad, es war ein Hinweis auf die Tatsache, dass Sie in dieser speziellen Abfrage 3 Buchstaben als Aliase für Tabellennamen verwendet haben, auch wenn dies keinen Sinn ergab ( cars-> carGott sei Dank - Sie haben meine Finger gerettet). Lies nicht zu tief hinein.
Riwalk

3
Schlimmer als meine Pseudonyme, war meine Vermischung von Pluralität carsund manufacturer. Einer ist Plural, der andere nicht. Wenn die Leute bei der db abholen wollen, dann ist das die schlechte Praxis, auf die man zurückgreifen sollte.
CaffGeek

3
Ich denke, es ist eine schlechte Übung. Offensichtlich ist es, was schlechte Praxis angeht, nicht schrecklich. Aber es ist so leicht zu vermeiden, warum nicht? Nun, ich bin damit einverstanden, für eine Intro-Klasse, ist dies die Sache, auf die man sich konzentrieren sollte? Wahrscheinlich nicht ....
user606723

2
@ user606723, eigentlich denke ich, dass es für eine Intro-Klasse wichtig ist, darauf hinzuweisen. Die Vermittlung von Best Practices sollte von grundlegender Bedeutung sein. Erst wenn Sie Erfahrung haben, verstehen Sie die Konsequenzen und Kompromisse und wann Sie von den Best Practices abweichen sollten.
CaffGeek

5
@Chad, stimme zu, nicht zuzustimmen. Der Versuch, den Schülern "Best Practices" beizubringen, ohne dass sie verstehen, warum dies die Best Practices sind, ist vergeblich. Und da Sie nicht alles abdecken können und diesen Punkt mit "Sie sollten es einfach nicht tun, Sie werden herausfinden, warum später" beschönigen, ist dies aus Sicht eines Professors eine ziemlich vernünftige Wahl. Neugierige Studenten können hier posten oder finden diese Frage hoffentlich schon beantwortet. (Oder fragen Sie nach dem Unterricht)
user606723

123

Denn wenn Sie eine Tabelle mit einem Fremdschlüssel haben, können Sie diesen Fremdschlüssel nicht "Id" nennen. Sie haben den Tabellennamen TableId

Und dann sieht deine Verbindung so aus

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

Und im Idealfall sollte Ihre Bedingung auf beiden Seiten denselben Feldnamen haben

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Obwohl es überflüssig erscheint, die ID als Hersteller-ID zu bezeichnen, ist es weniger wahrscheinlich, dass Sie Fehler in Ihren Join-Bedingungen haben, da Fehler offensichtlich werden.

Dies scheint einfach zu sein, aber wenn Sie mehrere Tische verbinden, wird es wahrscheinlicher, dass Sie einen Fehler machen. Finden Sie den folgenden ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Während bei richtiger Benennung der Fehler auffällt ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Ein weiterer Grund für die Benennung der IDs als "schlecht" ist, dass Sie beim Abfragen von Informationen aus mehreren Tabellen die ID-Spalten umbenennen müssen, damit Sie sie unterscheiden können.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Mit genauen Namen ist dies weniger ein Problem


174
Ich bin mir nicht sicher, ob das eine gute Erklärung für mich ist. Es ist nichts Falsches daran zu sagen SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. Ich habe es idjahrelang benutzt und nie gefunden, dass das, was du beschrieben hast, ein echtes Problem ist.
Riwalk

61
Ich würde sagen, dass die schlechte Praxis hier darin besteht, Tabellen mit Namen wie mfg oder mod zu aliasen. manufacturers.id = cars.manufacturer_id ist sehr gut lesbar und der Fehler wird auch auffallen.
Deadalnix

5
@Chad> Ich habe schon Probleme mit dummen Variablennamen. Viele Male. Für die Aufzeichnung hier, was ich einem Entwickler sagen würde, der dies in meinem Team tut "mfg bedeutet nicht Hersteller, es bedeutet, dass Sie zu faul sind, Hersteller zu schreiben".
Deadalnix

9
@ Stargazer712: Wenn Sie SELECT * aus 2 Tabellen ausführen, erhalten Sie 2 x ID-Spalten. Die ID ist jetzt mehrdeutig: Verweisen Sie auf eine Ordnungszahl oder einen Namen? SELECT * ist ebenfalls keine gute Praxis. Schlechte Argumente. Fragiler Code. Tschad ist richtig: defensive Codierung im Grunde
gbn

6
@gbn, wieder ist jede Mehrdeutigkeit weg, wenn Sie es einfach tun SELECT manufacturer.id FROM .... Jede Schwierigkeit, die daraus resultiert, idkann sehr leicht überwunden werden, was es einfach zu einer Geschmackssache macht.
Riwalk

67

Rubys ActiveRecord-Bibliothek und Groovys GORM verwenden standardmäßig "id" für den Ersatzschlüssel. Ich mag diese Praxis. Das Duplizieren des Tabellennamens in jedem Spaltennamen ist redundant, mühsam zu schreiben und mühsamer zu lesen.


30
+1 für "und mühsamer zu lesen." - Namenskonventionen sollten nicht als Hilfsmittel für schlampigen Code angesehen werden, sondern die Lesbarkeit verbessern.
ocodo

12
ID ist viel mühsamer zu lesen
HLGEM

5
@HLGEM: Den Spaltennamen kann man immer mit dem Tabellennamen qualifizieren.
Kevin Cline

2
Ich würde zustimmen, bis auf das mühsamere Lesen. Ich bevorzuge es, aussagekräftigere Spaltennamen zu lesen und weniger Zeit damit zu verbringen, herauszufinden, wofür diese Spalte eigentlich gedacht ist.
Devin Dixon

2
+1, Ich hasse es, Tabellen mit Spalten wie Posts.postID, Posts.postName zu sehen, bei denen die einfache Verwendung von post.id und post.name viel schöner ist.
Doug

40

Namen von allgemeinen oder Schlüsselspalten wie "Name" oder "Id" sollte der Tabellenname vorangestellt werden.

Es beseitigt Mehrdeutigkeiten, erleichtert die Suche und bedeutet weitaus weniger Spalten-Aliase, wenn beide "Id" -Werte benötigt werden.

Eine weniger verwendete oder Audit-Spalte oder ein Nicht-Schlüssel (z. B. LastUpdatedDateTime) spielt keine Rolle


57
Wenn du das tust, hasse ich dich dafür, dass ich extra tippe !!!! Der Name des Tisches ist Person. Was glaubst du, wird die ID sein? Auto? Nein, es ist Person.
jim

16
@ Jim, ich weiß nichts über dich, aber die Eingabe von 6 zusätzlichen Zeichen dauert ungefähr eine halbe Sekunde. Und wenn ich bedenke, dass ich selten aus einer Tabelle auswähle und daher zwei Spalten mit dem Namen 'Id' haben und den Namen der Tabelle / des Alias ​​trotzdem einfügen muss, gibt es keine Einsparungen bei der Anzahl der eingegebenen Zeichen.
CaffGeek

21
@Chad ich finde es überflüssig. Wenn ich einen Join mache, ist c.id = m.manufacturerid für mich in Ordnung. Diese Spalten sind normalerweise einer Klasse "zugeordnet", und um eine Klasse mit Person.PersonId zu haben, muss ich mich übergeben ... Ja, ich bin mir völlig bewusst, dass ich Probleme habe.
jim

20
Dem stimme ich auch nicht zu. Warum bei nameund anhalten id? Warum wird nicht jeder Spalte der Tabellenname vorangestellt? Es scheint willkürlich, diese beiden Namen zu wählen, um ein Präfix zu vergeben. Konzeptionell muss die Tabelle vorhanden sein, damit der Kontext einer Spalte vorhanden ist. Warum nicht einfach diesen Tabellennamen verwenden, um die Abfrage zu klären: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY ist in der Datenbankentwicklung nicht immer angemessen. In Datenbanken ist es wichtig, dass die Leistung erhöht wird und die Datenbank zusätzliche Arbeit leistet, um die DRY-Prinzipien zu erfüllen (z. B. mithilfe von Skalarfunktionen oder Ansichten, die Ansichten oder Abfragen aufrufen, die zu viele Spalten zurückgeben, oder mithilfe eines Cursors zum Hinzufügen von 1000000 Datensätzen, um einen vorhandenen Prozess zu verwenden). ist oft kontraindiziert. Denken Sie nicht, dass, nur weil etwas in der objektorientierten Welt gut ist, es im Datenbankdesign angemessen ist. Ihre Ablehnung war unangemessen. Die Verwendung von ID ist ein bekanntes SQL-Antipattern.
HLGEM

31

Dieser Thread ist tot, aber ich möchte hinzufügen, dass es eine schlechte Praxis ist , IMO nicht zu verwenden Id. Die IdSpalte ist etwas Besonderes; es ist der Primärschlüssel. Jede Tabelle kann eine beliebige Anzahl von Fremdschlüsseln enthalten, jedoch nur einen Primärschlüssel. In einer Datenbank, in der alle Primärschlüssel aufgerufen werden Id, wissen Sie, sobald Sie sich die Tabelle ansehen, genau, welche Spalte der Primärschlüssel ist.

Glauben Sie mir, ich habe seit Monaten den ganzen Tag in vielen großen Datenbanken (Salesforce) gearbeitet und das Beste, was ich zu den Schemata sagen kann, ist, dass jede Tabelle einen Primärschlüssel mit dem Namen hat Id. Ich kann Ihnen versichern, dass ich niemals verwirrt bin, wenn es darum geht, einen Primärschlüssel mit einem Fremdschlüssel zu verknüpfen, weil der PK aufgerufen wird Id. Eine andere Sache, die die Leute nicht erwähnt haben, ist, dass Tabellen lange alberne Namen haben können wie Table_ThatDoesGood_stuff__c; Dieser Name ist schon schlimm genug, weil der Architekt am Morgen, als er sich diese Tabelle ausgedacht hat, einen Kater hatte, aber jetzt sagen Sie mir, dass es nicht üblich ist, den Primärschlüssel aufzurufen Table_ThatDoesGood_stuff__cId (wobei zu beachten ist, dass bei SQL-Spaltennamen im Allgemeinen die Groß- und Kleinschreibung nicht berücksichtigt wird).

Um ehrlich zu sein, besteht das Problem bei den meisten Leuten, die Computerprogrammierung unterrichten, darin, dass sie seit Jahren keinen Seriencode mehr geschrieben haben und keine Ahnung haben, was ein funktionierender Software-Ingenieur tatsächlich tut. Warten Sie, bis Sie anfangen zu arbeiten, und überlegen Sie sich dann, was Sie für eine gute Idee halten oder nicht.


2
Dies ist nur der Fall, wenn keiner Ihrer Primärschlüssel ein zusammengesetzter Schlüssel ist, was leider viel zu oft der Fall ist. Man sollte wirklich nur unter bestimmten Umständen Ersatzschlüssel verwenden.
nicodemus13

6
Wenn Sie eine solche ID verwenden, kommt es zu einer Situation, in der Entwickler ohne nachzudenken jeder von ihnen erstellten Tabelle eine Primärschlüssel-ID hinzufügen. Eine der Grundlagen relationaler Datenbanken ist die Verwendung von aussagekräftigen und aggregierten Primärschlüsseln, und die Verwendung von id hilft nicht weiter.
Pieter B

Diese Antwort scheint nur so zu sein, als ob Sie sagen "Ich bevorzuge Id" mit stichhaltigen Argumenten. Ihr Argument ist, dass Sie sofort sehen können, welcher Schlüssel der Primärschlüssel ist, indem Sie den Schlüssel mit dem Namen Id finden. Nun, es ist genau das gleiche mit TableID . Ich kann Ihnen garantieren, dass ich nie verwirrt werde, welcher Schlüssel auch der Primärschlüssel ist. Ich suche nur nach dem, der den Tabellennamen vor der ID hat. Nicht nur das, sondern mit welchen heidnischen Tabellen arbeiten Sie, bei denen die erste Spalte nicht der Primärschlüssel ist? Ich bin der Meinung, dass alle Ihre Argumente in dieser Antwort rein auf Präferenzen beruhen und "tableId fühlt sich für mich falsch an" ähneln.
Dallas

@dallin alle antworten sind meinungsbildend, sonst würde jemand einfach auf den offiziellen standard verlinken, und es gibt keinen!
James

@James Meines Erachtens besteht das Ziel von StackExchange-Websites darin, die Anzahl der Antworten zu verringern, die auf die Meinung der Nutzer zurückzuführen sind. Das ist der Grund, warum Fragen geschlossen werden, weil sie zu eigensinnig sind. Zugegeben, ich denke, das ist der Grund, warum diese Frage geschlossen wurde - weil sie meinungsgebundene Antworten hervorruft, aber ich denke, dass diese spezifische Antwort ohne wirkliche Fakten oder Argumente, die auf Tatsachen beruhen, übermäßig meinungsgebunden war. Die gesamte Antwort kann mit den Worten "In meiner meinung nach solltest du id verwenden, nur weil es mir gefällt ". Das ist keine wertvolle Antwort.
5.

24

Ich halte es nicht für schlecht. Beständigkeit ist wie immer König.

Ich denke, es geht nur um den Kontext. Im Kontext der Tabelle bedeutet "id" genau das, was Sie erwarten, eine Bezeichnung, mit deren Hilfe Sie sie eindeutig gegenüber anderen identifizieren können, die ansonsten möglicherweise identisch sind (oder aussehen).

Im Zusammenhang mit Joins liegt es in Ihrer Verantwortung, die Joins so zu konstruieren, dass sie für Sie und Ihr Team lesbar sind. So wie es möglich ist, Dinge mit schlechter Phrasierung oder Benennung schwierig erscheinen zu lassen, ist es auch möglich, eine aussagekräftige Abfrage mit effektiver Verwendung von Aliasen und sogar Kommentaren zu erstellen.

Genauso wie einer Java-Klasse mit dem Namen 'Foo' nicht die Eigenschaft 'Foo' vorangestellt ist, müssen Sie Ihren Tabellen-IDs keine Tabellennamen voranstellen. In der Regel ist im Kontext klar, auf welche ID verwiesen wird.


5
Relationale Datenbanktabellen sind keine Klassen .
Adam Robinson

1
Sie sind jedoch Datenstrukturen und analog zu PODO-Klassen. Die gleichen Namensprobleme gelten.
ocodo

4
@ Slomojo: Nein, sie sind nicht analog zu einfachen Objekten. Objektorientiertes Design und Datenbankdesign sind nicht dasselbe und hängen auch nicht zusammen. Sie können zwar in einigen Fällen ein ähnliches (oder sogar dasselbe) Design ergeben, dies bedeutet jedoch nicht, dass sie miteinander verwandt sind. Zum Beispiel sind m: m-Beziehungen in Klassen trivial, aber es ist unmöglich, zwischen zwei Tabellen ohne eine dritte Zuordnungstabelle zu bestehen.
Adam Robinson

1
Wie das mit einer Namensstrategie zusammenhängt, weiß ich nicht. Meine Analogie ist (klar?) Nur insofern zutreffend.
ocodo

2
Es tut mir leid, dass meine implizite Bedeutung nicht sehr klar war. Ich hätte sagen sollen, dass sie in diesem Sinne den Klassen entsprechen. In beiden Fällen halte ich es nicht für besonders konstruktiv, übermäßig pedantisch zu sein. In Bezug auf die Benennung weisen Tabellen und Klassen eine erhebliche Anzahl von Ähnlichkeiten auf. Best Practices, die sich in einer Sackgasse entwickeln, sind ein faires Spiel zur Überarbeitung oder zumindest offen für Diskussionen. Es gibt eine Menge Fragen und Antworten, die dies effektiv veranschaulichen. Ich habe nichts Besonderes hinzuzufügen.
ocodo

24

Von data.stackexchange.com

ID in Beiträgen

BOOM, beantwortete Frage.
Erzählen Sie jetzt Ihrem Lehrer, dass SO schlechtes Datenbankdesign praktiziert.


8
Meine Vermutung an dem FKs, basierend auf dem Namen: PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Warum sollte eine so einfache Praxis als "schlecht" angesehen werden?
Sjoerd

3
Wie genau beweist dies etwas über Best Practices?
GBa

5
Ob etwas im Stapel verwendet wird oder nicht, beweist nicht, ob es sich um eine gute oder eine schlechte Praxis handelt.
Pieter B

2
Es zeigt sich jedoch, dass diese Vorgehensweise die Skalierbarkeit und Nützlichkeit einer Anwendung in keiner Weise beeinträchtigt.
Cypher,

1
Eigentlich ist SO Übung nicht perfekt. Ich würde diesen Namen verwenden: PostType -> PostType.Id; AcceptedAnswer -> Answer.Id; OwnerUser -> User.Id
alpav

17

Es macht es schwierig (und verwirrend), einen natürlichen Join auf dem Tisch durchzuführen, daher ist es schlecht, wenn nicht sogar sehr schlecht.

Natural Join ist ein uraltes Artefakt der SQL Lore (dh der relationalen Algebra), das Sie vielleicht schon einmal gesehen haben: ⋈ Vielleicht in einem Datenbankbuch. Was ich meine ist, dass Natrual Join keine neue SQL-Idee ist, auch wenn es anscheinend ewig dauert, bis DBMS sie implementiert hat. Daher ist es für Sie keine neue Idee, sie zu implementieren, und es ist möglicherweise sogar unvernünftig, sie zu ignorieren seine Existenz heute.

Wenn Sie alle IDs Ihres Primärschlüssels benennen, verlieren Sie die Leichtigkeit und Einfachheit des natürlichen Joins. select * from dudes natural join carsmuss geschrieben werden select * from dudes inner join cars where cars.dudeid = dudes.idoder select * from dudes inner join cars where dudes.carid = cars.id. Wenn Sie in der Lage sind, eine natürliche Verknüpfung zu erstellen, können Sie die tatsächliche Beziehung ignorieren, was meiner Meinung nach ziemlich beeindruckend ist.


Wenn Sie keine gespeicherte Prozedur schreiben, wann haben Sie als Anwendungsentwickler das letzte Mal einen vollständig formatierten SQL-Selektor geschrieben? Moderne Sprachen enthalten alle eine Art ORM-Funktion, die diese Beziehung für Sie verwaltet. Der Spaltenname ist viel wichtiger, als sauberes manuelles SQL schreiben zu können.
Bill Leeper

4
@Bill Ich mache das die ganze Zeit, viele, viele Male am Tag, hängt mehr von deiner Codebasis ab als von der Sprache, die du entwickelst. Und für die Diagnose können Sie, wenn Sie gute und tiefe Beziehungen herstellen möchten, diese natürlichen Verknüpfungen aneinanderreihen und das Nachschlagen von Feld-IDs vollständig vermeiden. Und wie der heilige Hieronymus berühmt sagte: "Unwissenheit über SQL ist Unwissenheit über Datenbanken".
Peter Turner

Abgesehen von der Tatsache, dass natürliche Verknüpfungen nicht allgemein unterstützt werden, sind natürliche Verknüpfungen nach IMO schwerer zu lesen. Gibt es zwei Spalten in Beziehung oder nur eine? Es ist weitaus besser, explizit zu sein und natürliche Verknüpfungen zu vermeiden.
Thomas

1
@Thomas, ich würde auch keine natürlichen Verknüpfungen in den Code einfügen, aber für die Diagnose habe ich sie als ziemlich nützlich empfunden, wenn die Datenbank so modelliert ist, dass sie tatsächlich funktioniert.
Peter Turner

16

Es gibt eine Situation, in der es nicht die beste Idee ist, "ID" auf jeden Tisch zu kleben: das USINGSchlüsselwort, wenn es unterstützt wird. Wir verwenden es oft in MySQL.

Wenn Sie zum Beispiel fooTablemit Spalte fooTableIdund barTablemit Fremdschlüssel haben fooTableId, können Ihre Abfragen so konstruiert werden:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Das spart nicht nur Tipparbeit, sondern ist im Vergleich zur Alternative auch viel lesbarer:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)

Dies ist die Antwort, die mir am meisten auffällt. Das USINGSchlüsselwort wird von der Datenbank postgres / mysql / sqlite unterstützt, bedeutet weniger Eingaben, die in einigen anderen Antwortlisten als Verwendungsgrund aufgeführt sind id, und ist meiner subjektiven Meinung nach besser lesbar.
Michael Barton

11

Warum fragst du nicht einfach deinen Lehrer?

Denken Sie daran, wenn alle Ihre Tabellen PK-Spalten benannt sind ID, macht es die Verwendung als Fremdschlüssel zu einem Albtraum.

Spaltennamen müssen semantisch signifikant sein. IDist zu generisch.


8
zu generisch für was? die ID eines Tisches?
jim

3
@ Jim von welchem ​​Tisch? idAllein bedeutet nichts, insbesondere im Zusammenhang mit einem Fremdschlüssel für eine andere Tabelle. Dies hat nichts zu tun classesund alles, was mit einem guten grundlegenden relationalen Datenbankdesign zu tun hat.

10
Leicht fettig sein, der Tisch, zu dem er gehört. table.idist eine durchaus akzeptable Art, sich auf ein idFeld zu beziehen . Das Präfixieren des Feldnamens mit dem Tabellennamen ist redundant.
ocodo

2
@Slomoj es ist nicht mehr Typisierung als das Einschließen des Namens in die Spalte und expliziter, wenn Tabellennamen in Monster-Joins mit Einzel- oder Doppelbuchstaben-Abkürzungen aliasiert werden.

6
Von welchem ​​Albtraum sprichst du? Angenommen, Sie haben eine selbstreferenzierende Struktur von Mitarbeitern mit einer Spalte, die deren Manager darstellt. Wie nennt man den Fremdschlüssel? Sie können es nicht EmployeeId nennen, da dies vermutlich Ihre PK ist. Der Name der FK muss nicht mit der PK übereinstimmen. Es sollte benannt werden, was es für die Entität darstellt, in der es enthalten ist.
Thomas

7

Die ID ist aus folgenden Gründen ungültig:

Wenn Sie viele Berichtsabfragen ausführen, müssen Sie die Spalten immer aliasen, wenn Sie beide anzeigen möchten. So wird es zu einer Zeitverschwendung, wenn man es von Anfang an richtig benennen kann. Diese komplexen Abfragen sind schwierig genug (ich schreibe Abfragen, die Hunderte von Zeilen lang sein können), ohne die zusätzliche Belastung durch unnötige Arbeit.

Es kann zu Codefehlern kommen. Wenn Sie eine Datenbank verwenden, die die Verwendung des Natural-Joins ermöglicht (ich denke nicht, dass Sie das jemals verwenden sollten, aber wenn Features verfügbar sind, werden sie von jemandem verwendet), werden Sie sich an der falschen Sache beteiligen, wenn Sie einen Entwickler finden, der sie verwendet.

Wenn Sie Verknüpfungen kopieren, um eine komplexe Abfrage zu erstellen, können Sie leicht vergessen, den Alias ​​in den gewünschten zu ändern, und erhalten eine falsche Verknüpfung. Wenn jede ID nach der Tabelle benannt ist, in der sie sich befindet, wird normalerweise ein Syntaxfehler angezeigt. Es ist auch einfacher zu erkennen, ob die Verknüpfung in einer komplexen Abfrage falsch ist, wenn der pPK-Name und der FK-Name übereinstimmen.


+1: Dies sind meiner Meinung nach zwingende Gründe, während IDmich die anderen gegnerischen Antworten überhaupt nicht überzeugen.
Phoog

Betreff: "Wenn Sie Verknüpfungen kopieren, um eine komplexe Abfrage zu erstellen" - so ist Ihr Problem das Kopieren und Einfügen. Stoppen Sie das Kopieren und Einfügen und Sie werden sehen, wie bequem die Benennung von car.id ist. Verwenden Sie für FK-Beitritte car.mfg = mfg.id, car.color = color.id, car.model = model.id - sehr einfach und entspricht dem, was Sie in LINQ schreiben würden.
alpav

Versuchen Sie, etwas mit 30 Verknüpfungen zu schreiben, und Sie werden sehen, warum es ein Antimuster ist.
HLGEM

Aliasing ist der erste und wichtigste Grund - es bereitet so viel Kopfzerbrechen, wenn große komplexe Berichte erstellt werden. Natürliche Verbindungen sind nur ein süßer Bonus. Es ist erstaunlich, wie andere Antworten diese Punkte einfach ignorieren. Ich denke, dass das Hinzufügen einiger Beispiele den Punkt klarer machen und diese Antwort höher anordnen würde, wo sie sein sollte.
Lulu

5

Es gibt einige Antworten, die sich dem nähern, was ich für den wichtigsten Grund halte, warum "id" nicht als Spaltenname für den Primärschlüssel in einer Tabelle verwendet wird: nämlich Konsistenz und verringerte Mehrdeutigkeit.

Für mich ist der entscheidende Vorteil jedoch der Wartungsprogrammierer, insbesondere einer, der nicht an der ursprünglichen Entwicklung beteiligt war. Wenn Sie den Namen "PersonID" für die ID in der Personentabelle verwendet und diesen Namen konsistent als Fremdschlüssel verwendet haben, ist es trivial, eine Abfrage für das Schema zu schreiben, um herauszufinden, welche Tabellen PersonID haben, ohne auf diese "PersonID" schließen zu müssen. ist der Name, der verwendet wird, wenn es sich um einen Fremdschlüssel handelt. Denken Sie daran, dass richtige oder falsche Fremdschlüsselbeziehungen nicht immer in allen Projekten erzwungen werden.

Es gibt einen Randfall, in dem eine Tabelle möglicherweise zwei Fremdschlüssel für dieselbe Tabelle haben muss. In solchen Fällen würde ich jedoch den ursprünglichen Schlüsselnamen als Suffixnamen für die Spalte verwenden, sodass eine Wildcard-Übereinstimmung,% PersonID, leicht gefunden werden kann diese Instanzen auch.

Ja, ein Großteil davon könnte durch das Vorhandensein von "id" und das Wissen, es immer als "tableNameID" zu verwenden, erreicht werden. Dies erfordert jedoch sowohl das Wissen, dass die Praxis vorhanden ist, als auch das Wissen der ursprünglichen Entwickler, mit weniger zu arbeiten intuitive Standardpraxis.

Während einige Leute darauf hingewiesen haben, dass es einige zusätzliche Tastenanschläge erfordert, um die längeren Spaltennamen zu schreiben, würde ich davon ausgehen, dass das Schreiben des Codes nur einen kleinen Bruchteil des aktiven Lebens des Programms ausmacht. Wenn das Speichern von Entwickler-Tastenanschlägen das Ziel war, sollten Kommentare niemals geschrieben werden.

Als jemand, der viele Jahre damit verbracht hat, große Projekte mit Hunderten von Tabellen zu verwalten, würde ich konsistente Namen für einen Schlüssel über Tabellen hinweg stark bevorzugen.


Angenommen, eine CompaniesTabelle verfügt über zwei Fremdschlüssel für eine PersonsTabelle. Eine vertritt den Präsidenten des Unternehmens; der andere vertritt den Schatzmeister des Unternehmens. Würden Sie die Spalten PersonID1und wirklich anrufen PersonID2? Es wäre weitaus aussagekräftiger, sie PresidentIDund zu nennen TreasurerID. Ich finde es viel einfacher zu lesen inner join Person AS Presidents ON Company.PresidentID = Presidents.IDalsinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
Nein. In Ihrem Beispiel hätte ich wahrscheinlich eine CompanyOfficeroder CompanyPersonTabelle, die eine Viele-zu-Viele-Beziehung zwischen Companyund Personmit zusätzlichen Informationen über die Art der Beziehung ermöglicht. Wenn ich es in der CompanyTabelle implementieren würde, würde ich die Spaltennamen verwenden PresidentPersonIDund TreasurerPersonIDden * PersonID-Teil des Namens beibehalten, während ich den zusätzlichen Deskriptor hinzufüge. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachi

5

Die Praxis der Verwendung von ID als Primärschlüsselfeld führt zu der Praxis, bei der ID zu jeder Tabelle hinzugefügt wird. Viele Tabellen verfügen bereits über eindeutige Informationen, die einen Datensatz eindeutig identifizieren. Verwenden Sie THAT als Primärschlüssel und nicht als ID-Feld, das Sie jeder einzelnen Tabelle hinzufügen. Das ist eine der Grundlagen relationaler Datenbanken.

Und deshalb ist die Verwendung von ID eine schlechte Übung: ID ist oft keine Information, sondern nur eine automatische Erhöhung.

Betrachten Sie die folgenden Tabellen:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Was an dieser Tabelle falsch ist, ist, dass der Benutzer eine weitere Zeile hinzufügen kann: Vereinigte Staaten mit dem Ländercode 840. Sie hat nur die relationale Integrität gebrochen. Natürlich können Sie die Eindeutigkeit einzelner Spalten erzwingen oder einfach einen Primärschlüssel verwenden, der bereits verfügbar ist:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

Auf diese Weise verwenden Sie die Informationen, über die Sie bereits verfügen, als Primärschlüssel, der das Herzstück des relationalen Datenbankdesigns darstellt.


1
Sie werden verstehen, warum Benutzer jeder Tabelle eine generische Schlüsselspalte hinzufügen, wenn Sie Datenbanken zwischen verschiedenen Systemen migrieren mussten oder das Vergnügen hatten, Datenbanken zusammenzuführen.
Cypher,

1
Dies ist gelegentlich der Fall, aber meiner Erfahrung nach ist es ziemlich ungewöhnlich, einen schönen unveränderlichen Schlüssel zu haben. Aber auch in Ihrem Beispiel haben Sie eine bedeutungslose eindeutige Nummer, um Länder zu identifizieren, nur eine, die von der ISO zugewiesen wird, nicht von Ihrer Datenbank.
CodesInChaos

Und jetzt, wenn sich der Ländername ändert, müssen Sie ihn in Ihrer gesamten Datenbank aktualisieren, um ihn zu reparieren. Wenn Sie einfach einen Ersatzschlüssel (wie ... "id") verwendet hätten, wäre das Update trivial. Natürliche Schlüssel sind großartig - wenn sie vollständig unveränderlich sind und sich nie ändern. Es gibt tatsächlich sehr wenige Fälle, in denen dies zutrifft.
Gerrat

@Gerrat: Wenn sich ein Ländername ändert, bleibt der numerische ISO 3166-1-Code unverändert, nur die ISO 3166-1-Codes für Alpha-2 und Alpha-3 werden geändert. Dies geschah zum Beispiel mit Birma / Myanmar. Wenn ein Land sein Territorium ändert, aber seinen Namen behält, ändert sich auch der numerische ISO 3166-1-Code, aber die ISO 3166-1-Codes für Alpha-2 und Alpha-3 bleiben erhalten. Dies geschah, als der Südsudan sich vom Sudan und Eritrea von Äthiopien trennte. Bei der Wiedervereinigung von Ost- und Westdeutschland behielten sie die Alpha-2- und Alpha-3-Codes Westdeutschlands bei, erhielten jedoch einen neuen numerischen Code. Wenn sich Länder vollständig auflösen oder verwandeln (denken Sie…
Jörg W Mittag

Als Ergebnis der Balkankriege der 90er Jahre erhalten sie sowohl neue numerische als auch Alpha-2- und Alpha-3-Codes.
Jörg W Mittag

4

Ich benutze immer 'id' als primären Spaltennamen für jede Tabelle, einfach weil es die Konvention der von mir verwendeten Frameworks ist (Ruby on Rails, CakePHP), so dass ich es nicht die ganze Zeit überschreiben muss.

Das wird für mich die akademischen Gründe nicht übertreffen.


2

Ich denke nicht, dass es eine schlechte Praxis ist, wenn es richtig verwendet wird. Es ist üblich, ein automatisch inkrementierendes ID-Feld mit der Bezeichnung "ID" zu haben, das Sie nie berühren müssen, und eine freundlichere Kennung für die Anwendung zu verwenden. Es kann etwas umständlich sein, Code wie diesen zu schreiben, from tableA a inner join tableB b on a.id = b.a_idaber dieser Code kann verstaut werden.

Als persönliche Präferenz tendiere ich dazu, der ID den Namen der Entität voranzustellen, aber ich sehe kein wirkliches Problem, Idwenn ich nur nutze, wenn es vollständig von der Datenbank behandelt wird.


Sie würden niemals zwei Tabellen mit jedem Primärschlüssel verbinden, insbesondere nicht mit einer Auto-Inkrement-ID. Das obige Beispiel stammt aus Tabelle A, einer inneren Verknüpfungstabelle B, b auf a.id = b.table_a_id.
Bill Leeper

Ja, das habe ich gemeint. Fast Mittag und brauchen Energie.
Wayne Molina

2

ID ist weit verbreitet genug, dass ich nicht denke, dass es jemanden verwirren würde. Sie werden immer den Tisch kennenlernen wollen. Das Einfügen von Feldernamen in den Seriencode ohne Einbeziehung einer Tabelle / eines Alias ​​ist eine schlechte Praxis. Wenn Sie übermäßig besorgt sind, schnell Ad-hoc-Abfragen eingeben zu können, sind Sie auf sich allein gestellt.

Hoffe nur, dass niemand eine SQL-Datenbank entwickelt, in der ID ein reserviertes Wort ist.

CREATE TABLE CAR (ID);

Kümmert sich um den Feldnamen, den Primärschlüssel und die automatischen Inkremente um 1, beginnend mit 1, alles in einem netten kleinen 2-Zeichen-Paket. Oh, und ich hätte es CARS genannt, aber wenn wir Tastenanschläge sparen wollen und wer glaubt wirklich, dass ein Tisch mit dem Namen CAR nur einen hat?


1
Dies zeigt, warum Kenntnisse der formalen Relationentheorie wichtig sind. Der Tabellenname repräsentiert, was eine einzelne Zeile ist. Die Tabelle Carstellt eine Stelle dar, Tablean der jede Roweine einzelne Stelle darstellt Car. Der Aufruf Carsändert die Semantik und zeigt ein völliges Unverständnis der grundlegenden Prinzipien der formalen Relationstheorie. Rails ist ein Paradebeispiel für jemanden, der genug wusste, um gefährlich zu sein .

2

Diese Frage wurde immer und immer wieder gestellt, aber ich dachte, dass auch ich meine Meinung hinzufügen würde.

  1. Ich verwende id, um zu bedeuten, dass dies der Bezeichner für jede Tabelle ist. Wenn ich mich also einer Tabelle anschließe und den Primärschlüssel benötige, verbinde ich mich automatisch mit dem Primärschlüssel.

  2. Das ID-Feld ist eine automatische Inkrementierung ohne Vorzeichen (was bedeutet, dass ich seinen Wert niemals festlegen muss und er nicht negativ sein kann).

  3. Für Fremdschlüssel verwende ich tablenameid (wieder eine Frage des Stils), aber der Primärschlüssel, mit dem ich mich verbinde, ist das ID-Feld der Tabelle, sodass ich aufgrund der Konsistenz Abfragen immer leicht überprüfen kann

  4. Ich bin auch kurz und süß

  5. Zusätzliche Konvention - Verwenden Sie Kleinbuchstaben für alle Tabellen- und Spaltennamen, damit keine Probleme aufgrund von Groß- und Kleinschreibung festgestellt werden können


1

Zu beachten ist auch, dass bestimmte Tools von Drittanbietern nicht verwendet werden können, wenn sich der Name des Primärschlüssels vom Namen des Fremdschlüssels unterscheidet.

Beispielsweise können Sie Ihr Schema nicht in ein Tool wie Visio laden und genaue ERDs erstellen.


Das wäre jedoch die Schuld des Drittanbieters. Konventionen zur Benennung von Spalten sind kein Ersatz für tatsächliche Fremdschlüssel, die das Tool überprüfen sollte.
Gerrat

1

Ich finde, dass die Leute hier so ziemlich jeden Aspekt abdecken, aber ich möchte hinzufügen, dass "id" kein "Bezeichner" ist und nicht gelesen werden sollte, sondern eher ein "Index" ist und mit Sicherheit nicht die Identität der Zeile angibt oder beschreibt. (Möglicherweise habe ich hier einen falschen Wortlaut verwendet. Korrigieren Sie mich, wenn dies der Fall wäre.)

Es ist mehr oder weniger so, wie Leute die Tabellendaten lesen und wie sie ihren Code schreiben. Ich persönlich und höchstwahrscheinlich ist dies der beliebteste Weg, den ich häufiger sehe, dass Codierer die vollständige Referenz als schreiben table.id, auch wenn sie keine Gewerkschafts- oder / und Beitrittskampagnen durchführen müssen. Zum Beispiel:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

Auf diese Weise können Sie es ins Englische übersetzen als "Geben Sie mir Farbe und Modell des Autos, das als nummeriert ist." und nicht als "Gib mir Farbe und Modell des Autos, das als Nummer identifiziert wird." Die ID stellt in keiner Weise das Auto dar, es ist nur der Index des Autos, eine Seriennummer, wenn Sie so wollen. Genau wie wenn Sie das dritte Element aus einem Array nehmen möchten.

Um zusammenzufassen, was ich hinzufügen wollte, ist, dass es nur eine Frage der Präferenz ist und die beschriebene Art, SQL zu lesen, die beliebteste ist.

Es gibt jedoch einige Fälle, in denen dies nicht verwendet wird, z. B. (ein weitaus selteneres Beispiel), wenn die ID eine Zeichenfolge ist, die wirklich beschreibt. Zum Beispiel id = "RedFordMustang1970"oder so ähnlich. Ich hoffe wirklich, dass ich das zumindest erklären konnte, um auf die Idee zu kommen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.