Il mio insegnante t-sql ci ha detto che nominare la nostra colonna PK "Id" è considerata una cattiva pratica senza ulteriori spiegazioni.
Perché la denominazione di una tabella PK della colonna "Id" è considerata una cattiva pratica?
Il mio insegnante t-sql ci ha detto che nominare la nostra colonna PK "Id" è considerata una cattiva pratica senza ulteriori spiegazioni.
Perché la denominazione di una tabella PK della colonna "Id" è considerata una cattiva pratica?
Verrò fuori e lo dirò: non è davvero una cattiva pratica (e anche se lo è, non è che è pessimo).
Potresti rendere l'argomento (come sottolineato da Ciad ) che può mascherare errori come nella seguente query :
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
ma questo può essere facilmente mitigato non usando minuscoli alias per i nomi delle tabelle:
SELECT *
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.ManufacturerId
JOIN models
ON models.Id = cars.ModelId
JOIN colors
ON manufacturer.Id = cars.ColorId
La pratica di SEMPRE usando abbreviazioni a 3 lettere mi sembra molto peggiore dell'uso del nome della colonna id
. (Caso in questione: chi vorrebbe effettivamente abbreviare il nome della tabella cars
con l'abbreviazione car
? Che fine serve?)
Il punto è: essere coerenti. Se la tua azienda utilizza Id e generalmente fai l'errore sopra, prendi l'abitudine di usare i nomi completi delle tabelle. Se la tua azienda vieta la colonna Id, prendila nel modo giusto e usa le convenzioni di denominazione che preferiscono.
Concentrati sull'apprendimento di cose che sono effettivamente cattive pratiche (come più sottocorrette correlate annidate) piuttosto che rimuginare su problemi come questo. Il problema di nominare le tue colonne "ID" è più vicino all'essere una questione di gusti piuttosto che essere una cattiva pratica.
NOTA PER I REDATTORI: l'errore in questa query è intenzionale e viene usato per creare un punto. Leggi la risposta completa prima di modificarla.
Perché quando si ha una tabella con una chiave esterna non si può nominare la chiave esterna "Id". Hai il nome della tabella TableId
E poi il tuo join è come
SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId
E idealmente, la tua condizione dovrebbe avere lo stesso nome di campo su ciascun lato
SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId
Quindi, mentre sembra ridondante nominare l'Id come ManufacturerId, rende meno probabile che si verifichino degli errori nelle condizioni di join in quanto gli errori diventano ovvi.
Sembra semplice, ma quando ti unisci a più tavoli, diventa più probabile che tu commetta un errore, trova quello sotto ...
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
Mentre con un'appropriata denominazione, l'errore spicca ...
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
Un altro motivo per chiamarli Id è "cattivo" è che quando stai interrogando per ottenere informazioni da più tabelle, dovrai rinominare le colonne Id in modo da poterle distinguere.
SELECT manufacturer.Id as 'ManufacturerId'
,cars.Id as 'CarId'
--etc
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.Id
Con nomi precisi questo è meno di un problema
La libreria ActiveRecord di Ruby e GORM di Groovy utilizzano "id" per la chiave surrogata per impostazione predefinita. Mi piace questa pratica. Duplicare il nome della tabella in ogni nome di colonna è ridondante, noioso da scrivere e più noioso da leggere.
I nomi di colonne comuni o chiave come "Nome" o "Id" devono essere preceduti dal TableName.
Rimuove l'ambiguità, più facile da cercare, significa molto meno alias di colonna quando sono necessari entrambi i valori "Id".
Una colonna meno utilizzata o di controllo o non chiave (ad esempio LastUpdatedDateTime) non ha importanza
Questo thread è morto, ma vorrei aggiungere che IMO not che usa Id
è una cattiva pratica. La colonna Id
è speciale; è la chiave primaria . Qualsiasi tabella può avere un numero qualsiasi di chiavi esterne, ma può avere solo una chiave primaria. In un database in cui tutte le chiavi primarie sono chiamate Id
, non appena visualizzi la tabella, sai esattamente quale colonna è la chiave primaria.
Credimi, per mesi ho passato tutto il giorno tutti i giorni a lavorare in molti grandi database (Salesforce) e la cosa migliore che posso dire sugli schemi è che ogni tabella ha una chiave primaria chiamata Id
. Posso assicurarti che non mi confondo assolutamente mai di unire una chiave primaria a una chiave esterna perché il PK è chiamato Id
. Un'altra cosa che le persone non hanno menzionato è che le tabelle possono avere nomi lunghi e sciocchi come Table_ThatDoesGood_stuff__c
; quel nome è già abbastanza grave perché l'architetto ha avuto una sbornia la mattina in cui ha inventato quel tavolo, ma ora mi stai dicendo che è una cattiva pratica non chiamare la chiave primaria Table_ThatDoesGood_stuff__cId
(ricordando che i nomi delle colonne SQL non sono nel caso generale sensibile).
Per essere onesti, i problemi con la maggior parte delle persone che insegnano programmazione al computer sono che non hanno scritto una riga di codice di produzione in anni, se mai, e non hanno idea di cosa sia realmente un ingegnere del software di lavoro. Attendi fino a quando non inizi a lavorare e poi decidi cosa ne pensi sia una buona idea o meno.
Non lo considero una cattiva pratica. La coerenza è il re, come al solito.
Penso che sia tutto basato sul contesto. Nel contesto della tabella da sola, "id" significa esattamente ciò che ti aspetti, un'etichetta per identificarla in modo univoco con altri che potrebbero altrimenti essere identificati o apparire.
Nel contesto dei join, è tua responsabilità costruire i join in modo tale da renderli leggibili a te e al tuo team. Proprio come è possibile rendere le cose difficili con una frasatura o una denominazione scadenti, è ugualmente possibile costruire una query significativa con un uso efficace di alias e persino commenti.
Allo stesso modo, una classe Java chiamata "Foo" non ha le sue proprietà precedute da "Foo", non si sentono obbligate a anteporre gli ID della tabella ai nomi delle tabelle. Di solito è chiaro nel contesto a che cosa si riferisce l'ID.
BOOM, risposta alla domanda.
Ora vai a dire al tuo insegnante che SO pratica la cattiva progettazione del database.
Rende difficile (e confuso) eseguire un join naturale sul tavolo, quindi sì, è brutto se non molto brutto.
Natural Join è un antico artefatto di SQL Lore (ad esempio algebra relazionale) che potresti aver visto uno di questi: perhaps in un libro di database, forse. Quello che voglio dire è che Natrual Join non è una nuova idea di Fangled SQL, anche se sembra che ci sia voluto per sempre che DBMS lo abbia implementato, quindi non è un'idea nuova per te implementarla, potrebbe anche essere irragionevole ignorare la sua esistenza al giorno d'oggi.
Bene, se si nomina l'ID della chiave primaria, si perde la facilità e la semplicità del join naturale. select * from dudes natural join cars
dovrà essere scritto select * from dudes inner join cars where cars.dudeid = dudes.id
o select * from dudes inner join cars where dudes.carid = cars.id
. Se sei in grado di fare un join naturale, puoi ignorare ciò che è effettivamente la relazione, il che, credo, è davvero fantastico.
C'è una situazione in cui attaccare "ID" su ogni tabella non è l'idea migliore: la parola chiave USING
, se è supportata. Lo usiamo spesso in MySQL.
Ad esempio, se hai fooTable
con colonna fooTableId
e barTable
con chiave esterna fooTableId
, allora le tue query possono essere costruite come tali:
SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)
Non solo salva la digitazione, ma è molto più leggibile rispetto all'alternativa:
SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
Perché non chiedi al tuo insegnante?
Pensa a questo, quando tutte le tue colonne PK delle tabelle sono denominate ID
, il che li fa usare come chiavi straniere in un incubo.
I nomi delle colonne devono essere semanticamente significativi. ID
è generico.
L'ID non funziona per i seguenti motivi:
Se esegui molte query sui rapporti, devi sempre creare un alias delle colonne se vuoi vederle entrambe. Quindi diventa una perdita di tempo in cui potresti chiamarlo correttamente per cominciare. Queste query complesse sono abbastanza difficili (scrivo query che possono essere lunghe centinaia di righe) senza l'onere aggiuntivo di svolgere attività non necessarie.
È soggetto a causare errori di codice. Se si utilizza un database che consente l'utilizzo del join naturale (non che io pensi che dovresti mai usarlo, ma quando le funzionalità sono disponibili qualcuno le userà), ti unirai alla cosa sbagliata se ottieni uno sviluppatore che lo usa.
Se stai copiando i join per creare una query complessa, è facile dimenticare di cambiare l'alias con quello desiderato e ottenere un join non corretto. Se ogni id viene chiamato dopo la tabella in cui si trova, in genere viene visualizzato un errore di sintassi. È anche più facile individuare se il join in una query complessa non è corretto se il nome pPK e il nome FK corrispondono.
Ci sono alcune risposte che si avvicinano a quello che considererei il motivo più importante per non usare "id" come nome di colonna per la chiave primaria in una tabella: vale a dire coerenza e ambiguità ridotta.
Tuttavia, per me il vantaggio chiave è realizzato dal programmatore di manutenzione, in particolare uno che non è stato coinvolto nello sviluppo originale. Se si utilizzava il nome "PersonID" per l'ID nella tabella Persona e si utilizzava coerentemente quel nome come chiave esterna, è banale scrivere una query sullo schema per scoprire quali tabelle hanno PersonID senza dover dedurre quel "PersonID" è il nome usato quando è una chiave straniera. Ricorda, giusto o sbagliato, le relazioni con le chiavi esterne non sono sempre applicate in tutti i progetti.
C'è un caso limite in cui una tabella potrebbe aver bisogno di avere due chiavi esterne per la stessa tabella, ma in questi casi inserirò il nome della chiave originale come nome del suffisso per la colonna, quindi una corrispondenza con caratteri jolly,% PersonID, potrebbe facilmente trovare anche quelle istanze.
Sì, molto di questo potrebbe essere ottenuto da uno standard di avere "id" e sapere di usarlo sempre come "tableNameID", ma ciò richiede sia sapere che la pratica è a posto che a seconda degli sviluppatori originali da seguire attraverso con una pratica standard meno intuitiva.
Mentre alcune persone hanno sottolineato che richiede alcuni tratti chiave extra per scrivere i nomi delle colonne più lunghi, direi che scrivere il codice è solo una piccola parte della vita attiva del programma. Se il salvataggio delle sequenze di tasti degli sviluppatori era l'obiettivo, i commenti non dovrebbero mai essere scritti.
Come qualcuno che ha passato molti anni a gestire progetti di grandi dimensioni con centinaia di tabelle, preferirei strongmente i nomi coerenti per una chiave tra tabelle.
La pratica di usare Id come chiave primaria porta alla pratica in cui l'ID viene aggiunto a ogni tabella. Molte tabelle hanno già informazioni univoche che identificano univocamente un record. Usa THAT come chiave primaria e non come campo ID che aggiungi a ciascuna tabella. Questo è uno dei fondamenti dei database relazionali.
Ed è per questo che usare l'id è una cattiva pratica: l'ID spesso non è un'informazione solo un aumento automatico.
considera le seguenti tabelle:
PK id | Countryid | Countryname
1 | 840 | United States
2 | 528 | the Netherlands
Ciò che non va in questa tabella è che consente all'utente di aggiungere un'altra linea: Stati Uniti, con codice paese 840. Ha appena rotto l'integrità relazionale. Ovviamente puoi applicare l'unicità su singole colonne oppure puoi semplicemente utilizzare una chiave primaria già disponibile:
PK Countryid | Countryname
840 | United States
528 | the Netherlands
In questo modo usi le informazioni che hai già come chiave primaria, che è il fulcro del design del database relazionale.
Io uso sempre "id" come nome di colonna principale per ogni tabella semplicemente perché è la convenzione dei framework che uso (Ruby on Rails, CakePHP), quindi non devo sovrascriverlo tutto il tempo.
Questo non mi batterà per ragioni accademiche.
Non penso che sia una cattiva pratica se è usata correttamente. È comune avere un campo ID autoincrementante chiamato "ID" che non si deve mai toccare e utilizzare un identificatore più amichevole per l'applicazione. Può essere un po 'complicato scrivere codice come from tableA a inner join tableB b on a.id = b.a_id
ma il codice può essere nascosto.
Come preferenza personale tendo a prefisso l'ID con il nome dell'entità, ma non vedo un vero problema con l'utilizzo di Id
se è gestito interamente dal database.
L'ID è abbastanza comune, che non penso che possa confondere nessuno. Vuoi sempre conoscere il tavolo. Inserire i nomi dei campi nel codice di produzione senza includere una tabella / alias è una cattiva pratica. Se sei eccessivamente preoccupato di poter digitare rapidamente query ad hoc, sei da solo.
Spera solo che nessuno sviluppi un database sql dove ID è una parola riservata.
CREATE TABLE CAR (ID);
Si prende cura del nome del campo, della chiave primaria e degli incrementi automatici di 1 iniziando con 1 tutto in un bel pacchetto di 2 caratteri. Oh, e l'avrei chiamato CARS ma se avremmo risparmiato sui tasti e chi pensava davvero che un tavolo chiamato CAR ne avrebbe avuto uno solo?
Questa domanda è stata ripetutamente ripetuta, ma ho pensato che anch'io avrei aggiunto la mia opinione.
Uso id per indicare che si tratta dell'identificatore per ogni tabella, quindi quando mi unisco a un tavolo e ho bisogno della chiave primaria mi unisco automaticamente alla chiave primaria.
Il campo id è un autoincremento, senza segno (ovvero non devo mai impostarne il valore e non può essere negativo)
Per le chiavi esterne, uso tablenameid (sempre una questione di stile), ma la chiave primaria a cui mi unisco è il campo id della tabella, quindi la coerenza significa che posso sempre controllare facilmente le query
id è breve e dolce anche
Convenzioni aggiuntive: utilizza la lettera minuscola per tutti i nomi di tabelle e colonne, quindi non è possibile trovare problemi a causa del caso
Un'altra cosa da considerare è che se il nome della chiave primaria è diverso dal nome della chiave esterna, non è possibile utilizzare determinati strumenti di terze parti.
Ad esempio, non potresti caricare il tuo schema in uno strumento come Visio e farlo produrre ERD accurati.
Trovo che le persone qui coprano praticamente ogni aspetto ma voglio aggiungere che "id" non è e non dovrebbe essere letto come "identificatore" è più di un "indice" e sicuramente non indica o descrive l'identità della riga . (Forse ho usato un testo sbagliato qui, per favore correggimi se lo facessi)
È più o meno come le persone leggono i dati della tabella e come scrivono il loro codice. Personalmente e molto probabilmente questo è il modo più popolare che vedo più spesso è che i programmatori scrivono il riferimento completo come table.id
, anche se non hanno bisogno di fare sindacati o / e join. Ad esempio:
SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>
In questo modo puoi tradurlo in inglese come "Dammi colore e modello di quella macchina che è numerata come". e non come "Dammi colore e modello di quella macchina che viene identificata come numero". L'ID non rappresenta l'auto in alcun modo, è solo l'indice dell'auto, un numero di serie se vuoi. Proprio come quando vuoi prendere il terzo elemento da un array.
Quindi riassumendo ciò che volevo aggiungere è che è solo una questione di preferenza e il modo descritto di leggere SQL è il più popolare.
Tuttavia, ci sono alcuni casi in cui questo non viene utilizzato, ad esempio (un esempio molto più raro) quando l'ID è una stringa che sta realmente descrivendo. Ad esempio id = "RedFordMustang1970"
o qualcosa di simile. Spero davvero di poterlo spiegare almeno per avere un'idea.