Perché la denominazione della colonna chiave primaria di una tabella "Id" è considerata una cattiva pratica? [chiuso]

201

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?

    
posta Jean-Philippe Leclerc 17.10.2011 - 19:22
fonte

19 risposte

238

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.

    
risposta data 12.04.2017 - 09:31
fonte
120

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

    
risposta data 19.10.2011 - 15:21
fonte
63

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.

    
risposta data 20.10.2011 - 19:15
fonte
40

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

    
risposta data 17.10.2011 - 18:48
fonte
28

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.

    
risposta data 19.10.2011 - 21:34
fonte
23

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.

    
risposta data 18.10.2011 - 01:10
fonte
22

Da data.stackexchange.com

BOOM, risposta alla domanda.
Ora vai a dire al tuo insegnante che SO pratica la cattiva progettazione del database.

    
risposta data 17.04.2012 - 14:47
fonte
17

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.

    
risposta data 17.10.2011 - 22:28
fonte
16

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)
    
risposta data 17.04.2012 - 17:40
fonte
11

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.

    
risposta data 06.05.2015 - 21:45
fonte
7

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.

    
risposta data 19.04.2012 - 23:22
fonte
5

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.

    
risposta data 18.10.2011 - 17:19
fonte
5

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.

    
risposta data 20.10.2012 - 16:53
fonte
4

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.

    
risposta data 15.02.2012 - 12:39
fonte
2

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.

    
risposta data 18.10.2011 - 18:07
fonte
2

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?

    
risposta data 19.10.2011 - 16:26
fonte
2

Questa domanda è stata ripetutamente ripetuta, ma ho pensato che anch'io avrei aggiunto la mia opinione.

  1. 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.

  2. Il campo id è un autoincremento, senza segno (ovvero non devo mai impostarne il valore e non può essere negativo)

  3. 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

  4. id è breve e dolce anche

  5. Convenzioni aggiuntive: utilizza la lettera minuscola per tutti i nomi di tabelle e colonne, quindi non è possibile trovare problemi a causa del caso

risposta data 17.04.2012 - 16:23
fonte
1

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.

    
risposta data 20.10.2012 - 14:36
fonte
1

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.

    
risposta data 27.12.2012 - 19:09
fonte

Leggi altre domande sui tag