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


210

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 colonna PK della tabella "Id" è considerata una cattiva pratica?


27
Bene, in realtà non è una descrizione e Id significa "identità" che si spiega da sé. Questa è la mia opinione
Jean-Philippe Leclerc,

49
Sono sicuro che ci sono molti negozi che usano Id come nome PK. Personalmente uso TableId come convenzione di denominazione, ma non direi a nessuno che è THE ONE TRUE WAY. Sembra che la tua insegnante stia solo cercando di presentare la sua opinione come best practice ampiamente accettata.

22
Sicuramente il tipo di cattiva pratica che non è poi così male. Il punto è diventare coerenti. Se usi id, usalo ovunque o non usarlo.
deadalnix,

57
Hai una tabella ... Si chiama Persone, ha una colonna, si chiama Id, che cosa pensi che sia? Un'automobile? Una barca? ... no, è l'ID persone, tutto qui. Non penso che non sia una cattiva pratica e non è necessario nominare la colonna PK in modo diverso da Id.
jim

38
Quindi l'insegnante si mette di fronte alla classe e ti dice che questa è una cattiva pratica senza una sola ragione? Questa è una pratica peggiore per un insegnante.
JeffO,

Risposte:


247

Sto per uscire e dirlo: non è davvero una cattiva pratica (e anche se lo è, non è poi così male).

Potresti argomentare (come ha sottolineato Chad ) 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 piccoli 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 usare SEMPRE le abbreviazioni di 3 lettere mi sembra molto peggio che usare il nome della colonna id. (Caso in questione: chi abbrevia effettivamente il nome della tabella carscon l'abbreviazione car? A che fine serve?)

Il punto è: essere coerenti. Se la tua azienda utilizza Id e in genere commetti l'errore sopra, prendi l'abitudine di utilizzare nomi di tabella completi. Se la tua azienda vieta la colonna ID, prendi il passo e usa la convenzione di denominazione che preferisce.

Concentrati sull'apprendimento di cose che sono REALMENTE cattive pratiche (come più query secondarie correlate nidificate) piuttosto che rimuginare su problemi come questo. Il problema di nominare le tue colonne "ID" è più vicino ad essere una questione di gusti che a essere una cattiva pratica.


NOTA PER GLI EDITORI: l'errore in questa query è intenzionale e viene utilizzato per indicare un punto. Si prega di leggere la risposta completa prima della modifica.


1
@Chad, era un riferimento al fatto che in quella particolare query hai usato 3 lettere per gli alias per i nomi delle tabelle, anche quando non aveva senso ( cars-> car. Grazie a Dio - mi hai salvato le dita). Non leggere troppo in profondità.
riwalk

3
peggio dei miei nomi alias, era il mio mix di pluralità carse manufacturer. Uno è plurale, l'altro no. Se la gente vuole scegliere nel db, questa è la cattiva pratica che dovrebbe essere presa in considerazione.
CaffGeek,

3
Penso che sia una cattiva pratica. Ovviamente, per quanto riguarda le cattive pratiche non è terribile .. ma è così facile da evitare, perché non farlo? Ora, sono d'accordo, per una lezione introduttiva, è questa la cosa su cui concentrarsi? Probabilmente no ....
user606723,

2
@ user606723, in realtà, penso che per una lezione di introduzione sia una cosa importante da chiarire. Insegnare le migliori pratiche dovrebbe essere fondamentale. Solo quando hai esperienza capisci le conseguenze, i compromessi e quando dovresti deviare dalle migliori pratiche.
CaffGeek,

5
@Chad, accetta di non essere d'accordo. Cercare di insegnare agli studenti le "migliori pratiche" senza permettere loro di capire perché quelle sono le migliori pratiche è uno sforzo inutile. E dal momento che non puoi coprire tutto, superare questo punto con "Non dovresti farlo, capirai perché in seguito" è una scelta piuttosto sana dal punto di vista di un professore. Gli studenti curiosi possono postare qui o speriamo che questa domanda abbia già risposto. (O chiedi dopo la lezione)
user606723,

123

Perché quando si dispone di una tabella con una chiave esterna non è possibile denominare la chiave esterna "Id". Hai nome tabella TableId

E poi il tuo join sembra

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, anche se sembra ridondante nominare l'ID come ManufacturerId, è meno probabile che tu abbia degli errori nelle condizioni di partecipazione, poiché gli errori diventano evidenti.

Sembra semplice, ma quando ti unisci a più tavoli, diventa più probabile che tu commetta un errore, trova quello qui 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

Considerando che con una corretta denominazione, l'errore sporge ...

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 cui denominarli Id è "errato" è che quando si richiedono informazioni da più tabelle, è necessario 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 un problema


174
Non sono sicuro che questa sia una spiegazione abbastanza buona per me. Non c'è niente di sbagliato nel dire SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. Ho usato idper anni e non ho mai trovato quello che hai descritto come un vero problema.
riwalk

61
Direi che la cattiva pratica qui è di alias le tabelle con nome come mfg o mod. produttori.id = cars.manufacturer_id è molto leggibile e anche l'errore si spegne.
deadalnix,

5
@Chad> Ho già avuto problemi con i nomi delle variabili stupide. Molte volte. Per il reccord, ecco cosa direi a un dev che fa questo nel mio team «mfg non significa produttore, significa che devi essere pigro per digitare produttore».
deadalnix,

9
@ Stargazer712: facendo SELECT * da 2 tabelle si ottengono 2 colonne ID. L'ID ora è ambiguo: fai riferimento per ordinale o nome? SELECT * non è neanche una buona pratica. Poveri argomenti. Codice fragile. Il Ciad ha ragione: codifica difensiva fondamentalmente
gbn

6
@gbn, ancora una volta, tutte le ambiguità se ne vanno semplicemente SELECT manufacturer.id FROM .... Ogni difficoltà derivante idpuò essere superata molto facilmente, rendendola semplicemente una questione di gusti.
riwalk

67

La libreria ActiveRecord di Ruby e GORM di Groovy usano "id" per la chiave surrogata per impostazione predefinita. Mi piace questa pratica. La duplicazione del nome della tabella in ciascun nome di colonna è ridondante, noiosa da scrivere e più noiosa da leggere.


30
+1 per "e più noioso da leggere". - le convenzioni di denominazione non dovrebbero essere considerate come un cerotto per il codice sciatto, dovrebbero migliorare la leggibilità come preoccupazione primaria.
ocodo

12
ID è molto più noioso da leggere
HLGEM,

5
@HLGEM: si può sempre qualificare il nome della colonna con il nome della tabella.
Kevin Cline,

2
Concordo, tranne per i più noiosi da leggere. In realtà preferisco leggere nomi di colonna più descrittivi e passare meno tempo a capire a cosa serve quella colonna.
Devin Dixon,

2
+1, odio vedere tabelle con colonne come Posts.postID, Posts.postName in cui semplicemente usare post.id e post.name è molto più bello.
Doug,

40

I nomi di colonne comuni o chiave come "Nome" o "Id" devono essere preceduti da TableName.

Elimina l'ambiguità, più facile da cercare, significa molto meno alias di colonna quando sono necessari entrambi i valori "Id".

Una colonna o chiave non utilizzata meno utilizzata o di controllo (ad esempio LastUpdatedDateTime) non ha importanza


57
Se lo fai, ti odio per avermi fatto scrivere di più !!!! Il nome della tabella è Person, cosa pensi che sarà l'Id? Auto? no, è la persona.
jim

16
@jim, non ti conosco, ma scrivere 6 caratteri extra mi richiede circa mezzo secondo. E considerando che raramente seleziono mai da una tabella, e quindi finirei con due colonne denominate 'Id' e dovrò comunque includere il nome tabella / alias, non ci sono risparmi nel numero di caratteri digitati.
CaffGeek,

21
@Chad lo trovo superfluo. se sto facendo un join, c.id = m.manufacturerid, va bene con me. Queste colonne sono in genere "mappate" su una classe in qualche modo e avere una classe con Person.PersonId mi fa venire voglia di vomitare ... Sì, sono pienamente consapevole di avere dei problemi.
jim

20
Non sono d'accordo anche con questo. Perché fermarsi a namee id? Perché non avere ogni colonna con il prefisso con il nome della sua tabella? Sembra arbitrario scegliere quei due nomi per imporre un prefisso. Concettualmente, è necessario disporre della tabella per avere comunque il contesto di una colonna. Perché non usare semplicemente il nome della tabella per chiarire la query: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY non è sempre appropriato nello sviluppo del database. Nei database ciò che è importante è la prestazione e fare in modo che il database faccia un lavoro extra per riempire i principi DRY (come usare funzioni scalari o viste che richiamano viste o query che restituiscono troppe colonne o usare un cursore per aggiungere 1000000 record per usare un proc esistente) è spesso controindicato. Non pensare che solo perché qualcosa di buono nel mondo orientato agli oggetti sia appropriato nella progettazione del database. Il tuo downvote è stato inappropriato. L'uso dell'ID è un modello SQL noto.
HLGEM,

31

Questo thread è morto, ma vorrei aggiungere che IMO non usando Idè una cattiva pratica. La Idcolonna è 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 vengono chiamate tutte le chiavi primarie Id, non appena si guarda la tabella si conosce esattamente quale colonna è la chiave primaria.

Credetemi, da mesi ho passato tutto il giorno ogni giorno 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 sull'unire una chiave primaria a una chiave esterna perché viene chiamato PK Id. Un'altra cosa che la gente non ha menzionato è che le tabelle possono avere nomi lunghi e sciocchi Table_ThatDoesGood_stuff__c; quel nome è abbastanza brutto perché l'architetto ha avuto i postumi di una sbornia la mattina ha pensato a quella tabella, 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 in generale sensibili al maiuscolo / minuscolo).

Ad essere onesti, i problemi con la maggior parte delle persone che insegnano la programmazione informatica sono che non scrivono una riga di codice di produzione da anni, se non mai, e non hanno idea di cosa faccia effettivamente un ingegnere del software funzionante. Aspetta di iniziare a lavorare e poi decidi cosa pensi sia una buona idea o no.


2
Questo è solo il caso se nessuna delle tue chiavi primarie è una chiave composita, il che è, sfortunatamente, troppo spesso il caso. Bisogna davvero usare le chiavi surrogate solo in circostanze particolari.
nicodemus13

6
Usando Id in questo modo si finisce con una situazione in cui, senza pensare, gli sviluppatori aggiungono l'id chiave primaria a ogni tabella che creano. Uno dei fondamenti dei database relazionali è l'uso di chiavi primarie significative e aggregate e l'utilizzo di id non aiuta.
Pieter B,

Questa risposta sembra proprio che tu stia dicendo "Preferisco Id" con argomentazioni supposte. Il tuo argomento è che puoi vedere immediatamente quale chiave è la chiave primaria trovando quella chiamata Id. Bene, è esattamente lo stesso con tableId . Posso garantire che non mi confondo mai quale sia la chiave primaria. Cerco solo quello che ha il nome della tabella prima dell'id. Non solo, ma con che tipo di tabelle pagane stai lavorando dove la prima colonna non è la chiave primaria? Sento che tutti i tuoi argomenti in questa risposta sono puramente preferenziali e affini a "tableId mi sembra sbagliato".
dallin

@dallin tutte le risposte sono supposte, altrimenti qualcuno si limiterebbe a collegarsi allo standard ufficiale e non ce n'è uno!
James,

@James Mi sento come l'obiettivo dei siti StackExchange è di ridurre le risposte supposte. Ecco perché le domande vengono chiuse perché troppo supposte. Certo, penso che sia un po 'il motivo per cui questa domanda è stata chiusa, perché suscita risposte supposte, ma ritengo che questa risposta specifica sia stata eccessivamente espressa senza alcun reale supporto o argomento basato su fatti. L'intera risposta può essere riassunta dicendo: "In secondo me, dovresti usare Id, solo perché è quello che mi piace ". Questa non è una risposta preziosa.
dallin

24

Non la considero una cattiva pratica. La coerenza è re, come al solito.

Penso che sia tutto basato sul contesto. Nel contesto della tabella a sé stante, "id" significa esattamente ciò che ti aspetti, un'etichetta che aiuti a identificarlo in modo univoco rispetto ad altri che potrebbero altrimenti essere (o apparire) identici.

Nel contesto dei join, è tua responsabilità costruire i join in modo tale da renderli leggibili a te e al tuo team. Così come è possibile rendere le cose difficili con frasi o denominazioni scadenti, è altrettanto 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 sentirti obbligato a mettere in prefisso i tuoi ID tabella con i nomi delle tabelle. Di solito è chiaro nel contesto quale sia l'ID a cui si fa riferimento.


5
Le tabelle del database relazionale non sono classi .
Adam Robinson,

1
Sono comunque strutture di dati e sono analoghi alle classi PODO. Si applicano gli stessi problemi di denominazione.
ocodo

4
@Slomojo: No, non sono analoghi a oggetti semplici. La progettazione orientata agli oggetti e la progettazione del database non sono uguali e non sono neppure correlate. Sebbene possano, in alcuni casi, produrre un design simile (o anche lo stesso), ciò non indica che siano correlati. Ad esempio, le relazioni m: m sono banali nelle classi, ma sono impossibili avere tra due tabelle senza una terza tabella di associazione.
Adam Robinson,

1
Non so come questo si riferisca a una strategia di denominazione. La mia analogia è (chiaramente?) Portata solo in quella misura.
ocodo

2
Mi dispiace che il mio significato implicito non fosse molto chiaro, avrei dovuto dire " in questo senso sono analoghi alle classi". Ad ogni modo, non penso che essere eccessivamente pedanti su questo sia particolarmente costruttivo. In termini di denominazione, tabelle e classi condividono una quantità significativa di somiglianze. Le migliori pratiche che si sviluppano in un vicolo cieco sono un gioco equo per la revisione, o almeno sono aperte alla discussione. C'è un sacco di domande e risposte che lo illustrano efficacemente, non ho altro da aggiungere.
ocodo

24

Da data.stackexchange.com

Id nei post

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


8
La mia ipotesi ai FKS, in base ai nomi: PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Perché una pratica così facile dovrebbe essere considerata "cattiva"?
Sjoerd,

3
In che modo ciò dimostra esattamente le migliori pratiche?
GBa,

5
Il fatto che qualcosa sia usato in pila o no non dimostra se si tratta di una pratica buona o cattiva.
Pieter B,

2
Ciò che dimostra è che questa pratica non vieta in alcun modo la scalabilità e l'utilità di un'applicazione.
Cypher,

1
In realtà la pratica SO non è perfetta. Vorrei usare questo nome: PostType -> PostType.Id; AcceptedAnswer -> Answer.Id; OwnerUser -> User.Id
alpav

17

Rende difficile (e confuso) eseguire un join naturale sul tavolo, quindi sì, è male se non molto male.

Natural Join è un antico manufatto di SQL Lore (ovvero l'algebra relazionale) che potresti aver visto uno di questi: ⋈ forse in un libro di database. Quello che voglio dire è che Natrual Join non è una nuova idea SQL confusa, anche se sembrava che ci fosse voluta un'eternità per l'implementazione da parte di DBMS, quindi non è una nuova idea complicata per implementarla, potrebbe anche essere irragionevole ignorarla la sua esistenza al giorno d'oggi.

Bene, se assegni un nome a tutto l'ID della tua chiave primaria, perdi la facilità e la semplicità del join naturale. select * from dudes natural join carsdovrà essere scritto select * from dudes inner join cars where cars.dudeid = dudes.ido select * from dudes inner join cars where dudes.carid = cars.id. Se sei in grado di fare un join naturale, puoi ignorare qual è la relazione in realtà, che, credo, è piuttosto fantastica.


A meno che tu non stia scrivendo una procedura memorizzata quando è l'ultima volta come sviluppatore di applicazioni, hai effettivamente scritto un selettore SQL completamente formattato? Le lingue moderne includono tutte una sorta di funzionalità ORM che gestisce questa relazione per te. Il nome della colonna è molto più importante che poter scrivere SQL manuale pulito.
Bill Leeper,

4
@Bill Lo faccio sempre, molte, molte volte al giorno, dipende più dalla tua base di codice che dalla lingua che stai sviluppando. E, per la diagnostica, se vuoi fare delle relazioni buone e profonde puoi mettere insieme quei join naturali ed evitare completamente di cercare gli ID dei campi. E, come diceva San Girolamo, "L'ignoranza di SQL è ignoranza dei database".
Peter Turner,

A parte il fatto che i join naturali non sono universalmente supportati, IMO, i join naturali sono più difficili da leggere. Ci sono due colonne in relazione o solo una? Molto meglio essere espliciti ed evitare i join naturali.
Thomas,

1
@Thomas, non inserirò neanche i join naturali nel codice, ma per la diagnostica li ho trovati piuttosto utili quando il database è modellato in modo che funzionino davvero.
Peter Turner,

16

C'è una situazione in cui attaccare "ID" su ogni tabella non è la migliore idea: la USINGparola chiave, se è supportata. Lo usiamo spesso in MySQL.

Ad esempio, se hai fooTablecon colonna fooTableIde barTablecon chiave esterna fooTableId, 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)

Questa è la risposta che sporge di più per me. La USINGparola chiave è supportata dal database postgres / mysql / sqlite, significa meno digitazioni che alcune delle altre risposte elencano come motivo per l'uso id, e infine secondo la mia opinione soggettiva è più leggibile.
Michael Barton,

11

Perché non chiedere semplicemente al tuo insegnante?

Pensa a questo, quando tutte le colonne PK delle tue tabelle vengono denominate ID, il loro uso come chiavi esterne è un incubo.

I nomi delle colonne devono essere semanticamente significativi. IDè generico.


8
troppo generico per cosa? l'id di un tavolo?
jim

3
@Jim di quale tavolo? idda solo non significa nulla, specialmente nel contesto di una chiave esterna per un'altra tabella. Questo non ha nulla a che fare con classestutto e ha a che fare con una buona progettazione di base del database relazionale fondamentale.

10
Per essere leggermente fatuo, il tavolo a cui appartiene. table.idè un modo perfettamente accettabile di riferirsi a un idcampo. Prefisso il nome del campo con il nome della tabella è ridondante.
ocodo

2
@Slomoj non sta più digitando che includere il nome nella colonna e più esplicito quando si aliasano i nomi delle tabelle in abbreviazioni a lettera singola o doppia in join di mostri.

6
Di quale incubo ti riferisci? Supponiamo di avere una struttura autoreferenziale di dipendenti con una colonna che rappresenta il loro manager. Come si chiama la chiave esterna? Non puoi chiamarlo EmployeeId in quanto presumibilmente è il tuo PK. Il nome dell'FK non deve corrispondere al PK. Dovrebbe essere chiamato per ciò che rappresenta per l'entità in cui è contenuto.
Thomas,

7

L'ID è errato per i seguenti motivi:

Se esegui molte query sui rapporti devi sempre aliasare le colonne se vuoi vederle entrambe. Quindi diventa una perdita di tempo quando potresti nominarlo correttamente per cominciare. Queste query complesse sono abbastanza difficili (scrivo query che possono essere lunghe centinaia di righe) senza l'onere aggiuntivo di eseguire lavori inutili.

È soggetto a causare errori di codice. Se usi un database che consente l'uso del join naturale (non che penso che dovresti mai usare, ma quando le funzionalità sono disponibili qualcuno li utilizzerà), ti unirai alla cosa sbagliata se ottieni uno sviluppatore che lo utilizza.

Se si stanno copiando i join per creare una query complessa, è facile dimenticare di cambiare l'alias con quello desiderato e ottenere un join errato. Se ogni ID prende il nome dalla tabella in cui si trova, di solito si verifica un errore di sintassi. È anche più facile individuare se l'unione in una query complessa non è corretta se il nome pPK e il nome FK corrispondono.


+1: Questi sono motivi convincenti secondo me, mentre le altre risposte contrastanti IDnon mi convincono affatto.
phoog

Ri: "Se stai copiando i join per creare una query complessa", il tuo problema è il copia e incolla. Ferma copia e incolla e vedrai quanto è conveniente la denominazione di car.id Per unirti a FK usa car.mfg = mfg.id, car.color = color.id, car.model = model.id - molto semplice e corrisponde a ciò che scriveresti in LINQ.
alpav,

Prova a scrivere qualcosa con 30 join e vedrai perché è un antipattern.
HLGEM,

L'aliasing è la ragione principale e soprattutto - è un tale mal di testa quando si eseguono report complessi di grandi dimensioni. I join naturali sono solo un dolce bonus. È incredibile come le altre risposte ignorino questi punti. Penso che l'aggiunta di alcuni esempi chiarirebbe il punto e salverebbe questa risposta più in alto dove dovrebbe essere.
Lulu,

5

Ci sono alcune risposte che si avvicinano a ciò che considererei il motivo più importante per non usare "id" come nome della colonna per la chiave primaria in una tabella: coerenza e ridotta ambiguità.

Tuttavia, per me il vantaggio chiave è realizzato dal programmatore di manutenzione, in particolare uno che non è stato coinvolto nello sviluppo originale. Se hai usato il nome "PersonID" per l'ID nella tabella Person e hai sempre usato 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 esterna. Ricorda, giusto o sbagliato, le relazioni con le chiavi esterne non sono sempre applicate in tutti i progetti.

Esiste un caso limite in cui una tabella potrebbe aver bisogno di avere due chiavi esterne nella 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 questi casi.

Sì, gran parte di questo potrebbe essere realizzato da uno standard di avere "id" e sapendo di usarlo sempre come "tableNameID", ma ciò richiede sia sapere che la pratica è in atto sia che, a seconda degli sviluppatori originali, seguire con meno pratica standard intuitiva.

Mentre alcune persone hanno sottolineato che per scrivere i nomi delle colonne più lunghe sono necessari alcuni tasti in più, direi che scrivere il codice è solo una piccola parte della vita attiva del programma. Se l'obiettivo era salvare le sequenze di tasti dello sviluppatore, i commenti non dovrebbero mai essere scritti.

Come qualcuno che ha trascorso molti anni a gestire progetti di grandi dimensioni con centinaia di tabelle, preferirei fortemente nomi coerenti per una chiave su più tabelle.


Supponiamo che una Companiestabella abbia 2 chiavi esterne in una Personstabella. Uno rappresenta il presidente dell'azienda; l'altro rappresenta il tesoriere dell'azienda. Chiamereste davvero le colonne PersonID1e PersonID2? Sarebbe molto più descrittivo chiamarli PresidentIDe TreasurerID. Trovo molto più facile da leggere inner join Person AS Presidents ON Company.PresidentID = Presidents.IDrispetto ainner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
No. Nel tuo esempio probabilmente avrei una CompanyOfficero una CompanyPersontabella che consente una relazione molti-a-molti con Companye Personcon informazioni aggiuntive sulla natura della relazione. Se dovessi implementarlo all'interno della Companytabella, utilizzerei i nomi delle colonne PresidentPersonIDe TreasurerPersonIDper preservare la parte * PersonID del nome durante l'aggiunta del descrittore aggiuntivo. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachi,

5

La pratica di utilizzare Id come campo chiave primaria porta alla pratica in cui l'id viene aggiunto a ogni tabella. Molte tabelle hanno già informazioni uniche che identificano in modo univoco un record. Usa QUESTO come chiave primaria e non un campo ID che aggiungi a ogni singola tabella. Questa è una delle basi dei database relazionali.

Ed è per questo che usare id è una cattiva pratica: id spesso non è solo un aumento automatico delle informazioni.

considerare 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 riga: gli Stati Uniti, con il codice paese 840. Ha appena rotto l'integrità relazionale. Ovviamente puoi applicare l'univocità su singole colonne oppure puoi semplicemente usare 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 è al centro della progettazione di database relazionali.


1
Capirai perché le persone aggiungono una colonna chiave generica a ogni tabella quando hai dovuto migrare database tra sistemi diversi o hai avuto il piacere di unire i database insieme.
Cypher,

1
Questo è occasionalmente il caso, ma nella mia esperienza è abbastanza raro avere una chiave unica e immutabile. Ma anche nel tuo esempio hai un numero univoco insignificante per identificare i paesi, solo uno assegnato dall'ISO non dal tuo database.
CodesInChaos,

E ora quando il nome del paese cambia, devi aggiustarlo in tutto il tuo database per risolvere. Se avessi semplicemente usato una chiave surrogata (come ... "id"), l'aggiornamento sarebbe banale. Le chiavi naturali sono fantastiche - quando sono completamente immutabili e non cambiano mai. In realtà ci sono pochissimi casi in cui questo è vero.
Gerrat,

@Gerrat: se il nome di un paese cambia, il codice numerico ISO 3166-1 rimane invariato, cambiano solo i codici ISO 3166-1 alpha-2 e alpha-3. Questo è successo con la Birmania / Myanmar, per esempio. Allo stesso modo, se un Paese cambia il suo territorio ma mantiene il suo nome, il codice numerico ISO 3166-1 cambia, ma i codici ISO 3166-1 alpha-2 e alpha-3 rimangono. Ciò è accaduto quando il Sud Sudan si è separato dal Sudan e l'Eritrea si è separato dall'Etiopia. Quando la Germania orientale e occidentale si riunirono, mantennero i codici alpha-2 e alpha-3 della Germania occidentale ma ottennero un nuovo codice numerico. Quando i paesi si dissolvono o si trasformano completamente (pensa ...
Jörg W Mittag

... risultato delle guerre balcaniche degli anni '90), ottengono entrambi nuovi codici numerici e alpha-2 e alpha-3.
Jörg W Mittag,

4

Uso sempre "id" come nome di colonna principale per ogni tabella semplicemente perché è la convenzione dei framework che utilizzo (Ruby on Rails, CakePHP), quindi non devo sostituirlo continuamente.

Ciò non batterà le ragioni accademiche per me.


2

Non penso che sia una cattiva pratica se usato correttamente. È comune avere un campo ID a incremento automatico chiamato "ID" che non si deve mai toccare e utilizzare un identificatore più amichevole per l'applicazione. Scrivere codice può essere un po 'complicato, from tableA a inner join tableB b on a.id = b.a_idma quel codice può essere nascosto.

Come preferenza personale tendo a aggiungere l'ID al nome dell'entità, ma non vedo un vero problema con il solo utilizzo Idse è gestito interamente dal database.


Non uniresti mai due tabelle per ciascuna chiave primaria, in particolare un ID di incremento automatico. L'esempio sopra verrebbe dalla tabella A un join interno tableB b su a.id = b.table_a_id.
Bill Leeper,

Sì, questo è ciò che intendevo. Quasi all'ora di pranzo e ho bisogno di energia.
Wayne Molina,

2

L'identità è abbastanza comune, che non penso che confonderebbe nessuno. Avrai sempre voglia di conoscere il tavolo. Inserire i nomi dei campi nel codice di produzione senza includere una tabella / alias è una cattiva pratica. Se sei troppo preoccupato di poter digitare rapidamente query ad hoc, sei da solo.

Spero solo che nessuno sviluppi un database sql in cui ID sia una parola riservata.

CREATE TABLE CAR (ID);

Si prende cura del nome del campo, della chiave primaria e degli incrementi automatici di 1 a partire da 1 tutto in un bel pacchetto di 2 caratteri. Oh, e l'avrei chiamato CARS ma se vogliamo risparmiare sui tasti e chi crede davvero che un tavolo chiamato CAR ne avrà solo uno?


1
questo dimostra perché la conoscenza della teoria relazionale formale è importante, il nome della tabella rappresenta ciò che è una singola riga . La tabella Carrappresenta un punto in Tablecui ognuno Rowrappresenta un singolo Car. Richiamare Carscambia il semantico e mostra una completa mancanza di comprensione dei principi di base della teoria relazionale formale. Rails è un ottimo esempio di qualcuno che sapeva abbastanza per essere pericoloso .

2

Questa domanda è stata ripetutamente ribadita, ma ho pensato che avrei aggiunto anche la mia opinione.

  1. Uso id per indicare che si tratta dell'identificatore di ogni tabella, quindi quando mi unisco a una tabella e ho bisogno della chiave primaria, mi unisco automaticamente alla chiave primaria.

  2. Il campo ID è un autoincremento, senza segno (nel senso che non devo mai impostare il suo valore e non può essere negativo)

  3. Per le chiavi esterne, uso tablenameid (di nuovo 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. l'id è anche breve e dolce

  5. Convenzione aggiuntiva: utilizzare le lettere minuscole per tutti i nomi di tabelle e colonne, quindi non sono stati rilevati problemi dovuti al caso


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 sarebbe possibile caricare lo schema in uno strumento come Visio e farlo produrre ERD accurati.


Sarebbe comunque colpa dello strumento di terze parti. Le convenzioni di denominazione delle colonne non sostituiscono le chiavi esterne effettive, che lo strumento dovrebbe introspettare.
Gerrat,

1

Trovo che le persone qui trattino praticamente ogni aspetto, ma voglio aggiungere che "id" non è e non dovrebbe essere letto come "identificatore", è più un "indice" e sicuramente non indica o descrive l'identità della riga. (Potrei aver usato una formulazione sbagliata qui, per favore correggimi se l'ho fatto)

È 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ù frequentemente è che i programmatori scrivono il riferimento completo come table.id, anche se non hanno bisogno di fare sindacati o / e join. Per esempio:

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

In questo modo puoi tradurlo in inglese come "Dammi il colore e il modello di quella macchina che è numerata come". e non come "Dammi il colore e il modello di quell'auto identificata come numero". L'ID non rappresenta l'auto in alcun modo, è solo l'indice dell'auto, un numero di serie se lo desideri. Proprio come quando vuoi prendere il terzo elemento da un array.

Quindi per riassumere 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, come (un esempio molto più raro) quando l'ID è una stringa che sta veramente descrivendo. Ad esempio id = "RedFordMustang1970"o qualcosa di simile. Spero davvero di poterlo spiegare almeno per avere l'idea.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.