Chiavi primarie carattere vs intero


30

Sto progettando un database con più tabelle di ricerca contenenti possibili attributi delle entità principali. Sto pensando di utilizzare una chiave di 4 o 5 caratteri per identificare questi valori di ricerca anziché un numero intero auto-incrementante in modo che quando memorizzo questi ID attributo nelle tabelle principali vedrò valori significativi anziché solo numeri casuali.

Quali sono le implicazioni sulle prestazioni dell'utilizzo di un campo di caratteri come chiave primaria anziché come numero intero?

Sto usando MySQL se è importante.

[Modifica]
Queste tabelle di ricerca hanno nuovi record aggiunti di rado. Vengono gestiti manualmente e anche le chiavi basate sui caratteri vengono create manualmente. Ecco un esempio:

      CUISINES
 ID      Description
-----  --------------
CHNSE  Chinese
ITALN  Italian
MXICN  Mexican

Risposte:


22

Dipende dal tuo motore. La saggezza comune è che le letture sono economiche, pochi byte qui e non avranno un impatto significativo sulle prestazioni di un database di dimensioni medio-piccole.

Ancora più importante, dipende dagli usi ai quali verrà inserita la chiave primaria. I periodici interi hanno il vantaggio di essere semplici da usare e da implementare. Inoltre, a seconda dell'implementazione specifica del metodo di serializzazione, hanno il vantaggio di essere rapidamente derivabili, poiché la maggior parte dei database memorizza semplicemente il numero seriale in una posizione fissa, anziché derivarlo Select max(ID)+1 from fooal volo.

La domanda diventa: in che modo una chiave di 5 caratteri presenta un "valore significativo" per te e per l'applicazione? Come viene creato questo valore e richiede più o meno tempo rispetto alla ricerca di un numero seriale incrementale. Mentre c'è una quantità banale di spazio risparmiato in alcuni numeri interi, la stragrande maggioranza dei sistemi ignorerà questo risparmio di spazio.

Non ci sono implicazioni in termini di prestazioni, a parte il fatto che la combinazione di caratteri richiede che non ci sia mai un motore automatico, poiché le tue "chiavi" non sono accettabili. Per il tuo dominio specifico, non preoccuparti delle chiavi artificiali e usa solo cinese, giapponese e tailandese come nomi di chiavi. Sebbene non sia possibile garantire l'unicità rispetto a qualsiasi possibile applicazione, nel proprio ambito è molto più ragionevole utilizzarli al posto di abbreviazioni orribili e forzate di 5 caratteri. Non ci sono impatti significativi sulle prestazioni finché non si arriva a milioni di tuple.

In alternativa, se stai solo monitorando per paese di origine e non specifiche cucine regionali (cantonese, sichuan, siciliano, umbro, calabrese, yucatecan, Oaxacan, ecc.), Puoi sempre utilizzare solo i codici ISO 3166 .

Se ho 10.000 ricette, la differenza tra una chiave di 5 caratteri e 20 caratteri non inizia a sommare?

Lo spazio è economico . Quando stai parlando di 10.000.000 di ricette su cui stai eseguendo operazioni OLAP, allora, forse. Con 10k ricette, stai guardando 150k di spazio.

Ma di nuovo dipende. Se hai molti milioni di dischi e ti stai unendo, allora ha senso denormalizzare la ricerca di qualcosa di così banale (in una visione materializzata). Per tutti gli scopi pratici, l'efficienza relativa del join su una macchina moderna tra una chiave a 5 caratteri e una chiave a lunghezza variabile è così simile da essere identica. Fortunatamente, viviamo in un mondo di CPU abbondante e disco abbondante. Quelli cattivi sono troppi join e inefficienza delle query, piuttosto che un confronto carattere per carattere. Detto questo, prova sempre .

Le cose P&T di questo livello sono così dipendenti dal database che le generalizzazioni sono estremamente difficili. Costruisci due modelli di esempio del database, popolali con il numero stimato di record, quindi vedi quale è più veloce. Nella mia esperienza, la lunghezza dei caratteri non fa una differenza enorme rispetto a buoni indici, buone configurazioni di memoria e altri elementi critici di ottimizzazione delle prestazioni.


@ BrianBallsun-Stanton se si dispone di ingombranti dati sequenziali relativi a queste tabelle di ricerca, lo spazio di archiviazione non è economico (in termini di velocità della query) perché la velocità di lettura del disco è il collo di bottiglia in qualsiasi RDB che non può essere memorizzato nella cache interamente nella RAM. Ho scoperto questo mentre cercavo di sviluppare uno schema RDB in grado di competere con i migliori nel business delle serie storiche. Divulgazione completa, non ho alcuna relazione con Skyspark, tranne che fanno pagare molto al mio datore di lavoro per l'uso del loro DB molto efficiente.
Piani cottura

8

Penso che non ci siano problemi con le prestazioni per la tabella cambiata raramente. Forse avrai problemi con il design in futuro. Ti suggerisco di non utilizzare i dati aziendali come chiave primaria a causa di cambiamenti aziendali. Utilizzare qualsiasi chiave primaria aggiuntiva per "collegare" le tabelle nel modello. Eventuali modifiche aziendali NON avranno alcun impatto sulle relative a questa tabella.


3

La vera domanda è se le prestazioni della query DB sono assolutamente significative per la tua applicazione (dimensione dei dati). Se la query richiede microsecondi, il salvataggio di alcuni di quei microsecondi utilizzando le Intchiavi non vale la penalità di leggibilità / manutenibilità. Tuttavia, se la tua query richiede pochi minuti, salvare alcuni di quei minuti può valere la pena delle Intchiavi.

Di seguito è il motivo per cui penso che i numeri interi possano farti risparmiare tempo di query (in percentuale del tempo di query complessivo), ma i fondatori di SkySpark possono spiegarlo meglio di me . Informativa completa, il mio datore di lavoro paga SkySpark un sacco di soldi per usare il proprio DB e sto cercando di costruire qualcosa di meglio / più veloce.

Se disponi di molti dati sequenziali (file di registro, serie temporali, analisi, corpora di testo o vocali) che hanno collegamenti (relazioni) con una qualsiasi delle tue tabelle di ricerca, scoprirai che lo spazio di archiviazione è fondamentale per la velocità delle query, nonostante @ La corretta analisi di Ballsun-Stanton su quanto lo spazio economico sia in $. Poiché la maggior parte del tempo di query (per dati sequenziali) viene impiegato per la lettura del disco, lo spazio non è economico in termini di tempo (come percentuale del tempo di query complessivo). Quindi, a meno che il tuo RDB non comprima / decomprima automaticamente ed efficientemente tutte le chiavi esterne (chiavi per i record correlati), vorrai tutte le tue chiavi Int, che sono le più efficienti in termini di spazio su disco (e velocità di lettura) per unità di informazioni contenuto (entropia). FYI MyISAM in MySql pone restrizionisu cosa è possibile fare con le righe di dati compressi (sola lettura). In altre parole, i numeri interi con incremento automatico sono già compressi per quanto è teoricamente possibile , data la limitazione di dimensioni minime basse sulla maggior parte dei campi di numeri interi DB. E quella compressione arriva senza:

  1. penalità di compressione / decompressione al momento dell'interrogazione
  2. penalità di lettura del disco al momento dell'interrogazione
  3. restrizioni di sola lettura o di altri DB su record o chiavi di dati compressi

C'è un motivo per cui gli ORM popolari ed efficienti come Django impostano per impostazione predefinita gli interi auto-incrementanti per i PK e perché altre domande SO sono arrivate alla stessa conclusione.

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.