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?
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?
Antworten:
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 cars
mit 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.
cars
-> car
Gott sei Dank - Sie haben meine Finger gerettet). Lies nicht zu tief hinein.
cars
und 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.
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
SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId
. Ich habe es id
jahrelang benutzt und nie gefunden, dass das, was du beschrieben hast, ein echtes Problem ist.
SELECT manufacturer.id FROM ...
. Jede Schwierigkeit, die daraus resultiert, id
kann sehr leicht überwunden werden, was es einfach zu einer Geschmackssache macht.
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.
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
name
und 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, ...
Dieser Thread ist tot, aber ich möchte hinzufügen, dass es eine schlechte Praxis ist , IMO nicht zu verwenden Id
. Die Id
Spalte 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.
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.
BOOM, beantwortete Frage.
Erzählen Sie jetzt Ihrem Lehrer, dass SO schlechtes Datenbankdesign praktiziert.
PostTypeId -> PostTypes.Id
; AcceptedAnswerId -> Answers.Id
; OwnerUserId -> Users.Id
. Warum sollte eine so einfache Praxis als "schlecht" angesehen werden?
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 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 Verknüpfung zu erstellen, können Sie die tatsächliche Beziehung ignorieren, was meiner Meinung nach ziemlich beeindruckend ist.
Es gibt eine Situation, in der es nicht die beste Idee ist, "ID" auf jeden Tisch zu kleben: das USING
Schlüsselwort, wenn es unterstützt wird. Wir verwenden es oft in MySQL.
Wenn Sie zum Beispiel fooTable
mit Spalte fooTableId
und barTable
mit 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)
USING
Schlü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.
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. ID
ist zu generisch.
id
Allein bedeutet nichts, insbesondere im Zusammenhang mit einem Fremdschlüssel für eine andere Tabelle. Dies hat nichts zu tun classes
und alles, was mit einem guten grundlegenden relationalen Datenbankdesign zu tun hat.
table.id
ist eine durchaus akzeptable Art, sich auf ein id
Feld zu beziehen . Das Präfixieren des Feldnamens mit dem Tabellennamen ist redundant.
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.
ID
mich die anderen gegnerischen Antworten überhaupt nicht überzeugen.
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.
Companies
Tabelle verfügt über zwei Fremdschlüssel für eine Persons
Tabelle. Eine vertritt den Präsidenten des Unternehmens; der andere vertritt den Schatzmeister des Unternehmens. Würden Sie die Spalten PersonID1
und wirklich anrufen PersonID2
? Es wäre weitaus aussagekräftiger, sie PresidentID
und zu nennen TreasurerID
. Ich finde es viel einfacher zu lesen inner join Person AS Presidents ON Company.PresidentID = Presidents.ID
alsinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
CompanyOfficer
oder CompanyPerson
Tabelle, die eine Viele-zu-Viele-Beziehung zwischen Company
und Person
mit zusätzlichen Informationen über die Art der Beziehung ermöglicht. Wenn ich es in der Company
Tabelle implementieren würde, würde ich die Spaltennamen verwenden PresidentPersonID
und TreasurerPersonID
den * PersonID-Teil des Namens beibehalten, während ich den zusätzlichen Deskriptor hinzufüge. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
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.
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_id
aber 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, Id
wenn ich nur nutze, wenn es vollständig von der Datenbank behandelt wird.
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?
Car
stellt eine Stelle dar, Table
an der jede Row
eine 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 .
Diese Frage wurde immer und immer wieder gestellt, aber ich dachte, dass auch ich meine Meinung hinzufügen würde.
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.
Das ID-Feld ist eine automatische Inkrementierung ohne Vorzeichen (was bedeutet, dass ich seinen Wert niemals festlegen muss und er nicht negativ sein kann).
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
Ich bin auch kurz und süß
Zusätzliche Konvention - Verwenden Sie Kleinbuchstaben für alle Tabellen- und Spaltennamen, damit keine Probleme aufgrund von Groß- und Kleinschreibung festgestellt werden können
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.
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.