Non ho molta familiarità con i database e le teorie su come funzionano. Dal punto di vista delle prestazioni (inserimento / aggiornamento / interrogazione) è più lento utilizzare le stringhe per chiavi primarie rispetto ai numeri interi?
Non ho molta familiarità con i database e le teorie su come funzionano. Dal punto di vista delle prestazioni (inserimento / aggiornamento / interrogazione) è più lento utilizzare le stringhe per chiavi primarie rispetto ai numeri interi?
Risposte:
Tecnicamente sì, ma se una stringa ha senso essere la chiave primaria, probabilmente dovresti usarla. Tutto dipende dalla dimensione della tabella per cui la stai realizzando e dalla lunghezza della stringa che diventerà la chiave primaria (stringhe più lunghe == più difficili da confrontare). Non userei necessariamente una stringa per una tabella che ha milioni di righe, ma la quantità di rallentamento delle prestazioni che otterrai utilizzando una stringa su tabelle più piccole sarà minuscola per il mal di testa che puoi avere avendo un numero intero che non non significa nulla in relazione ai dati.
Un altro problema con l'utilizzo di stringhe come chiave primaria è che, poiché l'indice viene costantemente messo in ordine sequenziale, quando viene creata una nuova chiave che si troverebbe nel mezzo dell'ordine, l'indice deve essere reinviato ... se si utilizza un'auto numero intero, la nuova chiave viene appena aggiunta alla fine dell'indice.
Inserisce in una tabella con un indice cluster in cui l'inserimento avviene nel mezzo della sequenza NON causa la riscrittura dell'indice. Non provoca la riscrittura delle pagine che comprendono i dati. Se c'è spazio nella pagina in cui andrà la riga, allora viene inserito in quella pagina. La singola pagina verrà riformattata per posizionare la riga nel posto giusto nella pagina. Quando la pagina è piena, si verificherà una divisione della pagina, con metà delle righe sulla pagina che va a una pagina e metà che va sull'altra. Le pagine vengono quindi ricollegate nell'elenco di pagine collegate che comprendono una tabella di dati che ha l'indice cluster. Al massimo, finirai per scrivere 2 pagine del database.
Le stringhe sono più lente nei join e nella vita reale sono molto raramente davvero uniche (anche quando dovrebbero essere). L'unico vantaggio è che possono ridurre il numero di join se ci si unisce alla tabella primaria solo per ottenere il nome. Tuttavia, anche le stringhe sono spesso soggette a modifiche, creando così il problema di dover correggere tutti i record correlati quando il nome dell'azienda cambia o la persona si sposa. Questo può essere un enorme successo in termini di prestazioni e se tutte le tabelle che dovrebbero essere correlate in qualche modo non sono correlate (ciò accade più spesso di quanto si pensi), è possibile che anche i dati non corrispondano. Un numero intero che non cambierà mai per tutta la durata del record è una scelta molto più sicura dal punto di vista dell'integrità dei dati e dal punto di vista delle prestazioni. Le chiavi naturali di solito non sono così buone per il mantenimento dei dati.
Voglio anche sottolineare che il meglio dei due mondi è spesso usare una chiave autoincrementante (o in alcuni casi specializzati, un GUID) come PK e quindi inserire un indice univoco sulla chiave naturale. Ottieni i join più veloci, non ottieni record duplicati e non devi aggiornare un milione di record figlio perché il nome di una società è cambiato.
Non importa cosa usi come chiave primaria purché sia UNICA. Se ti interessa la velocità o una buona progettazione del database, usa int a meno che non preveda di replicare i dati, quindi usa un GUID.
Se questo è un database di accesso o qualche piccola app, allora chi se ne frega davvero. Penso che la ragione per cui la maggior parte di noi sviluppatori schiaffeggia il vecchio int o guid in primo piano è perché i progetti hanno un modo di crescere su di noi e tu vuoi lasciarti l'opzione di crescere.
Troppe variabili. Dipende dalle dimensioni della tabella, dagli indici, dalla natura del dominio della chiave stringa ...
In generale , i numeri interi saranno più veloci. Ma la differenza sarà abbastanza grande da interessarti? È difficile da dire.
Inoltre, qual è la tua motivazione nella scelta delle stringhe? Anche i tasti numerici di autoincremento sono molto più semplici . È semantica? Convenienza? Problemi di replica / disconnessione? La tua risposta qui potrebbe limitare le tue opzioni. Ciò ricorda anche una terza opzione "ibrida" che stai dimenticando: le guide.
Non preoccuparti delle prestazioni fino a quando non avrai ottenuto un design semplice e solido che concorda con l'oggetto che i dati descrivono e si adatta bene all'uso previsto dei dati. Quindi, se emergono problemi di prestazioni, è possibile gestirli modificando il sistema.
In questo caso, è quasi sempre meglio usare una stringa come chiave primaria naturale, a condizione che ci si possa fidare di essa. Non preoccuparti se si tratta di una stringa, a condizione che la stringa sia ragionevolmente corta, indica circa 25 caratteri al massimo. Non pagherai un grande prezzo in termini di prestazioni.
Le persone che inseriscono i dati o le origini dati automatiche forniscono sempre un valore per la presunta chiave naturale o talvolta vengono omesse? Occasionalmente è errato nei dati di input? In tal caso, come vengono rilevati e corretti gli errori?
I programmatori e gli utenti interattivi che specificano le query sono in grado di utilizzare la chiave naturale per ottenere ciò che desiderano?
Se non puoi fidarti della chiave naturale, inventa un surrogato. Se inventi un surrogato, potresti anche inventare un numero intero. Quindi devi preoccuparti di dove nascondere il surrogato alla comunità degli utenti. Alcuni sviluppatori che non hanno nascosto la chiave surrogata sono venuti a pentirsene.
Gli indici implicano molti confronti.
In genere, le stringhe sono più lunghe degli interi e le regole di confronto possono essere applicate per il confronto, quindi il confronto delle stringhe è di solito un'attività più intensiva dal punto di vista computazionale rispetto al confronto di interi.
A volte, tuttavia, è più veloce usare una stringa come chiave primaria che fare un ulteriore join con una string to numerical id
tabella.
Sì, ma a meno che non ti aspetti di avere milioni di righe, non usare una chiave basata su stringhe perché è più lenta è di solito "ottimizzazione prematura". Dopotutto, le stringhe vengono memorizzate come numeri grandi mentre i tasti numerici vengono generalmente memorizzati come numeri più piccoli.
Una cosa a cui prestare attenzione, tuttavia, è se si dispone di indici raggruppati su una chiave qualsiasi e si sta eseguendo un numero elevato di inserimenti non sequenziali nell'indice. Ogni riga scritta farà riscrivere l'indice. se stai eseguendo inserimenti batch, questo può davvero rallentare il processo.
Due motivi per utilizzare numeri interi per le colonne PK:
Possiamo impostare l'identità per il campo intero che viene incrementato automaticamente.
Quando creiamo PK, il db crea un indice (Cluster o Non Cluster) che ordina i dati prima che vengano archiviati nella tabella. Utilizzando un'identità su un PK, l'ottimizzatore non deve controllare il criterio di ordinamento prima di salvare un record. Ciò migliora le prestazioni su grandi tavoli.
Qual è il motivo per cui hai una stringa come chiave primaria?
Vorrei solo impostare la chiave primaria su un campo intero a incremento automatico e inserire un indice sul campo stringa.
In questo modo, se esegui ricerche sul tavolo, dovrebbero essere relativamente veloci e tutti i tuoi join e le tue normali ricerche non saranno influenzati dalla loro velocità.
Puoi anche controllare la quantità del campo stringa che viene indicizzato. In altre parole, puoi dire "indicizza solo i primi 5 caratteri" se pensi che sarà sufficiente. Oppure, se i tuoi dati possono essere relativamente simili, puoi indicizzare l'intero campo.
Dal punto di vista delle prestazioni - Sì, la stringa (PK) rallenterà le prestazioni rispetto alle prestazioni ottenute utilizzando un numero intero (PK), dove PK ---> Chiave primaria.
Dal punto di vista dei requisiti - Anche se questa non è ancora una parte della tua domanda, vorrei menzionarla. Quando gestiamo enormi dati su diverse tabelle, generalmente cerchiamo il probabile insieme di chiavi che è possibile impostare per una determinata tabella. Ciò è dovuto principalmente al fatto che ci sono molte tabelle e per lo più ciascuna o una tabella sarebbe correlata all'altra attraverso una relazione (un concetto di chiave esterna). Pertanto, non possiamo sempre scegliere un numero intero come chiave primaria, piuttosto optiamo per una combinazione di 3, 4 o 5 attributi come chiave primaria per quelle tabelle. E quelle chiavi possono essere usate come chiave esterna quando mettiamo in relazione i record con qualche altra tabella. Ciò rende utile mettere in relazione i record tra diverse tabelle quando richiesto.
Pertanto per un utilizzo ottimale: creiamo sempre una combinazione di 1 o 2 numeri interi con 1 o 2 attributi di stringa, ma di nuovo solo se necessario.
Potrebbe esserci un grosso malinteso relativo alla stringa nel database. Quasi tutti hanno pensato che la rappresentazione dei numeri nel database sia più compatta che per le stringhe. Pensano che nei numeri db-s siano rappresentati come nella memoria. Ma non è vero. Nella maggior parte dei casi la rappresentazione numerica è più vicina ad una stringa come la rappresentazione rispetto ad altre.
La velocità di utilizzo di numero o stringa dipende più dall'indicizzazione che dal tipo stesso.
Per impostazione predefinita, ASPNetUserIds sono stringhe di 128 caratteri e le prestazioni vanno bene.
Se la chiave DEVE essere univoca nella tabella, dovrebbe essere la chiave. Ecco perché;
chiave stringa primaria = relazioni DB corrette, 1 chiave stringa (primaria) e 1 indice indice (primaria).
L'altra opzione è una tipica chiave int, ma se la stringa DEVE essere univoca probabilmente dovrai comunque aggiungere un indice a causa di query non-stop per convalidare o verificare che sia univoco.
Quindi, usando una chiave di identità int = Relazioni DB errate, 1 chiave int (Primaria), 1 indice int (Primaria), Probabilmente un indice stringa univoco e dover convalidare manualmente la stessa stringa non esiste (qualcosa come un controllo sql forse ).
Per ottenere prestazioni migliori usando un int su una stringa per la chiave primaria, quando la stringa DEVE essere univoca, dovrebbe essere una situazione molto strana. Ho sempre preferito usare le chiavi di stringa. E come una buona regola empirica, non denormalizzare un database fino a quando non BISOGNO a.