Devo aggiungere un limite di lunghezza arbitraria alle colonne VARCHAR?


35

Secondo la documentazione di PostgreSQL , non c'è alcuna differenza di prestazioni tra VARCHAR, VARCHAR(n)e TEXT.

Devo aggiungere un limite di lunghezza arbitraria a una colonna di nome o indirizzo ?

Modifica: non un duplicato di:

So che il CHARtipo è una reliquia del passato e mi interessa non solo la performance, ma anche altri pro e contro come Erwin ha dichiarato nella sua straordinaria risposta.

Risposte:


45

La risposta è no .
Non aggiungere un modificatore di lunghezza a varcharse puoi evitarlo. Il più delle volte, in realtà non hai bisogno di una restrizione di lunghezza comunque. Usa solo textper tutti i dati dei personaggi. Fallo varchar(nessun modificatore di lunghezza) se devi rimanere compatibile con RDBMS che non ha text.

Le prestazioni sono quasi le stesse - textsono un po 'più veloci in rare situazioni e si salvano i cicli per il controllo sulla lunghezza.

Se effettivamente bisogno di far rispettare una lunghezza massima, ancora usare texte aggiungere un vincolo di controllo per questo:

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

Puoi modificare o eliminare tale vincolo in qualsiasi momento senza dover fare confusione con la definizione della tabella e tutti gli oggetti dipendenti (viste, funzioni, chiavi esterne, ...)

Con i modificatori di lunghezza ti imbatti in problemi come questo o questo o questo ...

PostgreSQL 9.1 ha introdotto una nuova funzionalità per alleviare un po 'il dolore. Cito qui le note di rilascio :

Consentire ALTER TABLE ... SET DATA TYPEdi evitare la riscrittura delle tabelle nei casi appropriati (Noah Misch, Robert Haas)

Ad esempio, la conversione di una varcharcolonna in testo non richiede più una riscrittura della tabella. Tuttavia, l'aumento del vincolo di lunghezza su una varcharcolonna richiede comunque una riscrittura della tabella.


Penso che questa risposta sarebbe molto meglio se fosse semplicemente "no, non aggiungere mai limiti arbitrari a un vero database". Sento che molte di queste risposte necessitano di correzioni e ulteriori informazioni, ma che sono totalmente fuori tema e distraggono dalle tue conclusioni con cui sono totalmente d'accordo.
Evan Carroll,

Sì, tutto basato sulle versioni Postgres precedenti alla 9.1 - 6 anni fa. Ormai un po 'polveroso, ma i consigli di base sono ancora buoni.
Erwin Brandstetter,

È una buona o cattiva idea aggiungere un vincolo di controllo per ogni colonna di testo ai fini di un controllo di integrità e garantire che un bug nel client non esaurisca tutto lo spazio su disco del database inserendo un testo molto grande?
Codice

@Code: è un'opzione praticabile. Se hai molte colonne con lo stesso vincolo, prendi in considerazione i domini . O varchar(n)dopotutto, per semplicità - se i lati negativi non ti riguardano in genere. (Il limite non è arbitrario nel tuo caso se vuoi imporre una lunghezza massima effettiva.)
Erwin Brandstetter

12

Se vedi il limite di lunghezza come una sorta di vincolo di controllo per assicurarti di convalidare i dati, allora sì aggiungine uno. In realtà potresti voler non usare una definizione di lunghezza ma un vero vincolo di controllo, per rendere più veloce la modifica del limite.

Per modificare (aumentare) un limite di lunghezza è necessario eseguirne uno ALTER TABLEche potrebbe richiedere molto tempo per terminare (a causa di una possibile riscrittura della tabella) durante il quale è necessario un blocco esclusivo della tabella.

La modifica (ovvero l'eliminazione e la ricostruzione di un vincolo di controllo è un'operazione molto breve e richiede solo la lettura dei dati della tabella, non cambierà alcuna riga. Quindi sarà molto più veloce (il che a sua volta significa che il blocco esclusivo della tabella verrà mantenuto per un periodo di tempo molto più breve).

Durante il funzionamento non vi è alcuna differenza tra a text, a varcharo una varchar(5000)colonna.


per pura curiosità, perché pensi che questo controllo della lunghezza non possa essere eseguito su un'applicazione client durante l'acquisizione dei dati?
PirateApp,

4
@PirateApp: perché molto spesso ci saranno più di un'applicazione o qualche fonte di dati esterna (pensate alle importazioni batch notturne). E quasi sempre il database (e i dati) vivono più a lungo di un'applicazione.
a_horse_with_no_name

2

La domanda è in particolare se aggiungere un limite di lunghezza arbitraria alle colonne VARCHAR?

Per questo, la risposta è semplicemente "no". Non c'è nulla che possa giustificare l'aggiunta di un limite arbitrario come si farebbe in database inferiori che supportano varchar(max)o utilizzano convenzioni come varchar(255). Tuttavia, se le specifiche affrontano un limite, penso che la risposta diventi molto più complessa soprattutto nelle versioni moderne di PostgreSQL. E, per quello, mi sporgerei verso .

Secondo me, il limite è una scelta saggia se le specifiche lo richiedono. Soprattutto per carichi di lavoro più ragionevoli. Se per nessun altro motivo, conservare i metadati.

Dalla mia risposta qui, indice delle prestazioni per CHAR vs VARCHAR (Postgres) , dove mi rivolgo al valore dei metadati.

Se trovassi una specifica che avesse chiavi di testo a lunghezza variabile che fossero significative e che mi fossi fidato di avere una lunghezza massima costante, lo avrei usato varcharanch'io. Tuttavia, non riesco a pensare a nulla che soddisfi questi criteri.


1

Sembra che potrebbero esserci delle differenze di prestazioni se VARCHARviene utilizzato regolarmente per memorizzare stringhe molto grandi, poiché "le stringhe lunghe vengono compresse automaticamente dal sistema" e "i valori molto lunghi vengono memorizzati anche nelle tabelle di sfondo". In teoria ciò significherebbe che un elevato volume di richieste per un campo stringa molto lungo sarebbe più lento rispetto a un campo stringa breve. Probabilmente non incontrerai mai questo problema, dal momento che nomi e indirizzi non saranno molto lunghi.

Tuttavia, a seconda di come stai usando queste stringhe al di fuori del tuo database, potresti voler aggiungere un limite pratico per prevenire l'abuso del sistema. Ad esempio, se stai visualizzando il nome e l'indirizzo su un modulo da qualche parte, potresti non essere in grado di visualizzare un intero paragrafo di testo nel campo "nome", quindi avrebbe senso limitare la colonna del nome a qualcosa come 500 personaggi.


1
AFAIK non vi è alcuna differenza nel TOASTing varchar e nei campi di testo.
dezso,

VARCHARè zucchero puramente sintattico per TEXTPostgres, non c'è differenza nella gestione della conservazione; l'archiviazione della tabella di compressione vs sfondo menzionata viene eseguita in base alla lunghezza effettiva dei dati nella colonna e non sui metadati della colonna. Le colonne TEXT sono memorizzate internamente come una varlenastruttura C (che è un array a lunghezza variabile con i primi 4 byte che memorizzano la lunghezza in creazione / aggiornamento) ed è questa struttura che è ottimizzata in base alla sua lunghezza.
Cowbert,
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.