2009-09-14 20 views
9

Si consideri che ci sono un sacco di tabelle che si collegano alle tabelle "paesi" o "valute".Sta usando char come chiave primaria/esterna no no no?

Per semplificare la lettura dei dati, desidero rendere il campo CHAR con codice del paese (ad esempio Stati Uniti, GB, AU) e codice valuta (USD, AUD), una chiave primaria in ciascuno di questi 2 tavoli e tutte le altre tabelle usa questo CHAR come chiave iniziale.

Il database è mysql con motore innodb.

Provocherà problemi di prestazioni? È qualcosa che dovrei evitare?

risposta

21

Le prestazioni non sono proprio il problema principale, almeno non per me. Il problema è più sulle chiavi surrogate rispetto a quelle naturali.

I codici paese non sono statici. Possono e fanno cambiare. I paesi cambiano nome (es. Etiopia in Eritrea). Esse nascono (ad esempio, la disgregazione della Jugoslavia o dell'Unione Sovietica) e cessano di esistere (ad esempio, la Germania occidentale e orientale). Quando questo accade, il codice standard ISO cambia.

Altro a Name Changes Since 1990: Countries, Cities, and More

chiavi surrogate tendono ad essere meglio perché quando questi eventi accadono le chiavi non cambiano, solo le colonne nella tabella di riferimento fanno.

Per questo motivo sarei più propenso a creare tabelle paese e valuta con una chiave primaria int invece.

Detto questo, i campi chiave varchar useranno più spazio e avere alcuni svantaggi di performance che probabilmente non sarà un problema a meno che non si sta eseguendo un numero enorme di query.

Per completezza, si può decidere di fare riferimento a Database Development Mistakes Made by AppDevelopers.

+3

L'Etiopia ha cambiato il suo nome?!? – SeanJA

+0

Accidenti al telefono, mi ha fatto alzare nel mezzo digitando questa risposta esatta. Ben detto! – Eric

+0

@SeanJA: secondo questo link, sì. Potrebbe essere stato un cambiamento temporaneo. – cletus

2

Il collegamento di James Skidmore è importante da leggere.

Se stai limitando te stesso ai codici di paese e di valuta (2 e 3 caratteri, rispettivamente), puoi benissimo essere in grado di farla franca dichiarando le colonne char (2) e char (3).

Direi che non sarebbe un no-no. Se stai usando una codifica di caratteri a 8 bit, stai osservando le colonne delle dimensioni di smallint o mediumint, rispettivamente.

0

La mia risposta è che non esiste una risposta chiara. Scegli un approccio all'interno del tuo progetto ed essere coerente. Entrambi hanno i loro vantaggi e svantaggi.

@cletus fa un buon punto sull'uso delle chiavi generate, ma quando si incontra una situazione in cui i dati sono relativamente statici, come i codici paese, l'introduzione di una chiave generata per loro sembra eccessivamente complessa. Nonostante la politica del mondo reale, l'apparizione e la scomparsa dei codici paese non costituirà un problema per la maggior parte dei problemi aziendali (ma se i tuoi dati riguardano attivamente tutti i 190-210 paesi, segui questo consiglio).

L'utilizzo di chiavi surrogate universalmente è una strategia buona e popolare. Ma ricorda, viene in risposta alla modellazione dei database utilizzando le chiavi naturali per tutto. Ack! Aprire un libro di database di 15 anni. Usare le chiavi naturali ovunque ti porta in situazioni difficili, poiché la comprensione iniziale dei domini del problema si rivela sbagliata. Vuoi avere coerenza nelle tue pratiche di modellazione, ma l'utilizzo di tecniche diverse per situazioni chiaramente diverse è OK.

Ho il sospetto che le prestazioni per la maggior parte dei database moderni sulle chiavi esterne var (2) siano uguali (o migliori) rispetto ai campi int. I database hanno supportato per anni chiavi esterne testuali.

Dato che non abbiamo altre informazioni sul progetto, se si preferisce utilizzare i codici paese come chiavi esterne e si ha la possibilità di farlo, direi che è OK. Sarà più facile lavorare con i dati. È un po 'controcorrente, ma ... in questo caso ... non ti porterà in un angolo.

+0

-1 Questo è in realtà abbastanza sbagliato. Come indicato in http://forums.mysql.com/read.php?153,243809,243818#msg-243818 da James, ci sono cose che MySQL (il database in questione) non fa con varchars che fa con chiavi int. – cletus

+0

Stavo solo supponendo che dal momento che i database l'hanno fatto per anni, sarebbe stato ottimizzato. Non sarebbe la prima volta che l'ipotesi si è rivelata sbagliata! Ma quel post è una domanda leggermente diversa ("sta usando VARCHAR (45) una buona scelta per una chiave primaria?") Questo problema è CHAR (2) su una tabella di 200 righe (il numero di paesi). Sfortunatamente quel post non discute le prestazioni dell'indice FK in generale, e se CHAR (2) sarà più efficiente di VARCHAR (2), e non potrei scoprirlo. Grazie per il collegamento. – ndp

+0

Sono d'accordo, si discute quanto sia brutto avere 45 byte di byte dato che è 4-5 volte più grande del normale int, ma con char (2) o char (3) non ci sarà molta differenza di dimensione. –