it-swarm.dev

Warum wird das Benennen der Primärschlüsselspalte einer Tabelle "ID" als schlechte Praxis angesehen?

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

Warum wird das Benennen einer Tabellen-PK-Spalte "Id" als schlechte Praxis angesehen?

215

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

Sie könnten das Argument (wie Chad hervorhob) vorbringen, 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 keine winzigen Aliase für Ihre Tabellennamen 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 Abkürzungen mit 3 Buchstaben zu verwenden, scheint mir viel schlimmer zu sein als die Verwendung des Spaltennamens id. (Beispiel: Wer würde den Tabellennamen cars tatsächlich mit der Abkürzung car abkürzen? Welchem ​​Zweck dient das?)

Der Punkt ist: konsequent sein. Wenn Ihr Unternehmen ID verwendet und Sie häufig den oben genannten Fehler machen, gewöhnen Sie sich an, vollständige Tabellennamen zu verwenden. Wenn Ihr Unternehmen die ID-Spalte 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 "ID" zu nennen, 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 hervorzuheben. Bitte lesen Sie die vollständige Antwort, bevor Sie sie bearbeiten.

250
riwalk

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 dein Join so aus

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

Und im Idealfall sollte Ihre Bedingung auf jeder Seite den gleichen Feldnamen haben

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

Obwohl es überflüssig erscheint, die ID als ManufacturerId zu benennen, 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 Tabellen verbinden, wird es wahrscheinlicher, dass Sie einen Fehler machen. Finden Sie die folgende ...

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 ID ist "schlecht": Wenn Sie Informationen aus mehreren Tabellen abfragen, müssen Sie die ID-Spalten umbenennen, 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

Bei genauen Namen ist dies weniger ein Problem

125
CaffGeek

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.

68
kevin cline

Gemeinsamen oder Schlüsselspaltennamen wie "Name" oder "Id" sollte der Tabellenname vorangestellt werden.

Es beseitigt Mehrdeutigkeiten, ist einfacher zu suchen und bedeutet weitaus weniger Spaltenaliasnamen, wenn beide "Id" -Werte benötigt werden.

Eine weniger verwendete oder geprüfte Spalte oder ein Nichtschlüssel (z. B. LastUpdatedDateTime) spielt keine Rolle

40
gbn

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

Glauben Sie mir, seit Monaten arbeite ich jeden Tag den ganzen Tag in vielen großen Datenbanken (Salesforce). Das Beste, was ich zu den Schemas sagen kann, ist, dass jede Tabelle einen Primärschlüssel namens Id hat. Ich kann Ihnen versichern, dass ich absolut nie verwirrt bin, wenn ich einen Primärschlüssel mit einem Fremdschlüssel verbinde, da die PK Id heißt. 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 eine schlechte Praxis ist, den Primärschlüssel Table_ThatDoesGood_stuff__cId nicht aufzurufen (denken Sie daran, dass SQL-Spaltennamen dies nicht sind im Allgemeinen Groß- und Kleinschreibung beachten).

Um ehrlich zu sein, besteht das Problem bei den meisten Menschen, die Computerprogrammierung unterrichten, darin, dass sie seit Jahren, wenn überhaupt, keine Zeile mit Produktionscode mehr geschrieben haben und keine Ahnung haben, was ein arbeitender Softwareentwickler tatsächlich tut. Warten Sie, bis Sie anfangen zu arbeiten, und entscheiden Sie sich dann selbst, was Sie für eine gute Idee halten oder nicht.

32
user23157

Von data.stackexchange.com

Id in Posts

BOOM, Frage beantwortet.
Sagen Sie jetzt Ihrem Lehrer, dass SO schlechtes Datenbankdesign üben.

25
Cyril Gandon

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

Ich denke, es geht nur um den Kontext. Im Kontext der Tabelle allein bedeutet "id" genau das, was Sie erwarten, eine Bezeichnung, mit deren Hilfe sie eindeutig gegen andere identifiziert werden kann, die ansonsten möglicherweise identisch sind (oder erscheinen).

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

Auf die gleiche Weise hat eine Java -Klasse mit dem Namen 'Foo' keine Eigenschaften, denen 'Foo' vorangestellt ist. Sie müssen Ihren Tabellen-IDs keine Tabellennamen voranstellen. Dies ist normalerweise klar im Kontext auf welche ID verwiesen wird.

24
lotsoffreetime

Es macht es schwierig (und verwirrend), eine natürliche Verbindung auf dem Tisch herzustellen, daher ist es schlecht, wenn nicht sehr schlecht.

Natural Join ist ein uraltes Artefakt von SQL Lore (d. H. Relationale Algebra), das Sie möglicherweise gesehen haben: ⋈ vielleicht in einem Datenbankbuch. Was ich damit meine, ist, dass Natrual Join keine neue SQL-Idee ist, obwohl es anscheinend ewig gedauert hat, bis DBMS sie implementiert hat. Daher ist es keine neue Idee für Sie, sie zu implementieren. Es ist möglicherweise sogar unvernünftig, sie zu ignorieren seine Existenz heutzutage.

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

17
Peter Turner

Es gibt eine Situation, in der es nicht die beste Idee ist, "ID" in jede Tabelle zu setzen: 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)
16
Izkata

Warum fragst du nicht einfach deinen Lehrer?

Denken Sie darüber nach, wenn alle Ihre Tabellen-PK-Spalten ID heißen, wird die Verwendung als Fremdschlüssel zu einem Albtraum.

Spaltennamen müssen semantisch signifikant sein. ID ist zu generisch.

11
user7519

ID ist aus folgenden Gründen schlecht:

Wenn Sie viele Berichtsabfragen durchführen, müssen Sie die Spalten immer mit einem Alias ​​versehen, wenn Sie beide anzeigen möchten. Es wird also zu Zeitverschwendung, wenn Sie es zunächst richtig benennen können. 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 natürlichen Joins ermöglicht (nicht, dass Sie das jemals verwenden sollten, aber wenn Funktionen verfügbar sind, werden sie von jemandem verwendet), werden Sie auf der falschen Seite beitreten, 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 Alias ​​zu ändern und eine falsche Verknüpfung zu erhalten. 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 der Join in einer komplexen Abfrage falsch ist, wenn der pPK-Name und der FK-Name übereinstimmen.

7
HLGEM

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

Und deshalb ist die Verwendung von ID eine schlechte Praxis: 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: USA mit dem Ländercode 840. Sie hat nur die relationale Integrität verletzt. Natürlich können Sie die Eindeutigkeit einzelner Spalten erzwingen oder einfach einen bereits verfügbaren Primärschlüssel verwenden:

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

Auf diese Weise verwenden Sie die Informationen, die Sie bereits haben, als Primärschlüssel, der das Herzstück des relationalen Datenbankdesigns bildet.

5
Pieter B

Es gibt einige Antworten, die sich dem nähern, was ich als den wichtigsten Grund dafür ansehen würde, "id" nicht als Spaltennamen für den Primärschlüssel in einer Tabelle zu verwenden: Konsistenz und reduzierte Mehrdeutigkeit.

Für mich wird der Hauptvorteil jedoch vom Wartungsprogrammierer realisiert, insbesondere von einem, 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, ob richtig oder falsch, Fremdschlüsselbeziehungen werden nicht immer in allen Projekten durchgesetzt.

Es gibt einen Edge-Fall, 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, damit eine Platzhalterübereinstimmung,% PersonID, leicht gefunden werden kann diese Instanzen auch.

Ja, ein Großteil davon könnte durch den Standard erreicht werden, "id" zu haben und zu wissen, dass es immer als "tableNameID" verwendet wird. Dies setzt jedoch voraus, dass beide wissen, dass die Praxis vorhanden ist, und dass sie von den ursprünglichen Entwicklern abhängig sind, um weniger zu erreichen intuitive Standardpraxis.

Während einige Leute darauf hingewiesen haben, dass zum Schreiben der längeren Spaltennamen einige zusätzliche Tastenanschläge erforderlich sind, würde ich davon ausgehen, dass das Schreiben des Codes nur einen kleinen Bruchteil der aktiven Lebensdauer des Programms ausmacht. Wenn das Speichern von Entwickler-Tastenanschlägen das Ziel war, sollten niemals Kommentare 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 bevorzugen.

5
Malachi

Ich verwende immer 'id' als primären Spaltennamen für jede Tabelle, einfach weil dies die Konvention der von mir verwendeten Frameworks ist (Ruby on Rails, CakePHP), sodass ich es nicht ständig überschreiben muss.

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

4
Sfynx

ID ist häufig genug, dass ich nicht denke, dass es jemanden verwirren würde. Du wirst immer den Tisch wissen wollen. Das Einfügen von Feldnamen in den Produktionscode ohne Einfügen 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 und wer glaubt wirklich, dass ein Tisch namens CAR nur einen haben wird?

2
JeffO

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

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

  2. Das ID-Feld ist ein vorzeichenloses Autoinkrement (was bedeutet, dass ich seinen Wert nie festlegen muss und es nicht negativ sein kann).

  3. Für Fremdschlüssel verwende ich die Tabellennamen-ID (wieder eine Frage des Stils), aber der Primärschlüssel, dem ich beitrete, ist das ID-Feld der Tabelle. Aufgrund der Konsistenz kann ich Abfragen immer einfach überprüfen

  4. iD ist kurz und süß

  5. Zusätzliche Konvention - Verwenden Sie für alle Tabellen- und Spaltennamen Kleinbuchstaben, damit aufgrund der Groß- und Kleinschreibung keine Probleme auftreten

Ich denke nicht, dass es eine schlechte Praxis ist, wenn es richtig verwendet wird. Es ist üblich, ein automatisch inkrementierendes ID-Feld mit dem Namen "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 from tableA a inner join tableB b on a.id = b.a_id aber dieser Code kann versteckt werden.

Aus persönlichen Gründen stelle ich der ID in der Regel den Namen der Entität voran, sehe jedoch kein wirkliches Problem bei der Verwendung von Id, wenn diese vollständig von der Datenbank verarbeitet wird.

2
Wayne Molina

Ich finde, dass die Leute hier so ziemlich jeden Aspekt abdecken, aber ich möchte hinzufügen, dass "id" nicht als "Bezeichner" gelesen wird und nicht gelesen werden sollte, sondern eher ein "Index" ist und sicherlich nicht die Identität der Zeile angibt oder beschreibt. (Ich habe hier möglicherweise einen falschen Wortlaut verwendet. Bitte korrigieren Sie mich, wenn ich dies getan habe.)

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 die beliebteste Art und Weise, die ich häufiger sehe, dass Codierer die vollständige Referenz als table.id, auch wenn sie keine Gewerkschaften oder/und Beitritte machen 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 ist." Die ID repräsentiert das Auto in keiner Weise, sondern nur den 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. Beispielsweise id = "RedFordMustang1970" oder etwas ähnliches. Ich hoffe wirklich, dass ich das zumindest erklären konnte, um auf die Idee zu kommen.

1

Eine andere zu berücksichtigende Sache ist, dass, wenn sich der Primärschlüsselname vom Fremdschlüsselnamen unterscheidet, bestimmte Tools von Drittanbietern nicht verwendet werden können.

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

1
1earldog