Sto sviluppando un'applicazione in Ruby on Rails con il database PostgreSQL (9.4). Nel mio caso d'uso, le colonne nelle tabelle verranno cercate molto frequentemente, poiché l'intero punto dell'applicazione è alla ricerca di attributi molto specifici su un modello.
Attualmente sto decidendo se utilizzare un integer
tipo o semplicemente utilizzare un tipo di stringa tipico (ad esempio character varying(255)
, che è l'impostazione predefinita in Rails ) per le colonne, poiché non sono sicuro di quale sarà la differenza di prestazioni nell'indice.
Queste colonne sono enumerazioni . Hanno una dimensione fissa per la quantità di possibili valori che possono avere. La maggior parte delle lunghezze di enum non supera 5, il che significa che l'indice sarebbe più o meno fisso per tutta la durata dell'applicazione ; pertanto, gli indici di numero intero e stringa sarebbero identici nel numero di nodi.
Tuttavia, la stringa che dovrebbe essere indicizzata potrebbe essere lunga circa 20 caratteri, che in memoria è all'incirca 5 volte quella dell'intero (se un numero intero è 4 byte e le stringhe sono ASCII pure a 1 byte per carattere, quindi vale). Non so come i motori di database eseguano l'indicizzazione delle ricerche, ma se deve "scansionare" la stringa fino a quando non corrisponde esattamente , allora in sostanza significa che la ricerca della stringa sarebbe 5 volte più lenta di una ricerca intera; la "scansione" fino a quando la corrispondenza per la ricerca di numeri interi sarebbe di 4 byte anziché di 20. Questo è quello che sto immaginando:
Il valore di ricerca è (intero) 4:
scansione ............................ TROVATO | ottenere record ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Il valore di ricerca è (stringa) "some_val" (8 byte):
scansione ................................................. .................................... TROVATO | ottenere record ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Spero che abbia senso. Fondamentalmente, poiché l'intero occupa meno spazio, può essere "abbinato" più velocemente della sua controparte stringa. Forse questa è una supposizione completamente sbagliata, ma non sono un esperto, quindi è per questo che te lo chiedo ragazzi! Suppongo che questa risposta che ho appena trovato sembra supportare la mia ipotesi, ma voglio essere sicuro.
Il numero di possibili valori nella colonna non cambierebbe usando nessuno dei due, quindi l'indice stesso non cambierebbe (a meno che non aggiungessi un nuovo valore all'enum). In questo caso, ci sarebbe una differenza di prestazioni nell'uso di integer
o varchar(255)
, o ha un tipo intero ha più senso?
Il motivo per cui sto chiedendo è che il enum
tipo di Rails associa numeri interi a chiavi di stringa, ma non sono pensati per essere colonne rivolte all'utente. In sostanza, non è possibile verificare che il valore enum sia valido, poiché un valore non valido ne causerà uno ArgumentError
prima che sia possibile eseguire qualsiasi convalida. L'uso di un string
tipo consentirebbe le convalide, ma se c'è un costo prestazionale preferirei semplicemente risolvere il problema della convalida.
varchar(255)
vs. esvarchar(260)
. Potrebbe essersi verificato qualcosa del genere con SQL Server 6.x ma questo non è vero da molto tempo.