Differenza tra stringa e testo nelle rotaie?


436

Sto realizzando una nuova app Web utilizzando Rails e mi chiedevo, qual è la differenza tra stringe text? E quando dovrebbero essere usati ciascuno?

Risposte:


523

La differenza dipende dal modo in cui il simbolo viene convertito nel rispettivo tipo di colonna nel linguaggio di query.

con MySQL: la stringa è mappata su VARCHAR (255) - http://guides.rubyonrails.org/migrations.html

:string |                   VARCHAR                | :limit => 1 to 255 (default = 255)  
:text   | TINYTEXT, TEXT, MEDIUMTEXT, or LONGTEXT2 | :limit => 1 to 4294967296 (default = 65536)

Riferimento:

http://www.packtpub.com/article/Working-with-Rails-ActiveRecord-Migrations-Models-Scaffolding-and-Database-Completion

Quando dovrebbero essere usati ciascuno?

Come regola generale, utilizzare :stringper brevi input di testo (nome utente, e-mail, password, titoli, ecc.) E utilizzare :textper input più lunghi previsti come descrizioni, contenuti dei commenti, ecc.


11
Penso che una migliore regola empirica sia quella di usare sempre :text. Vedi depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law

74
Per MySQL - non tanto, puoi avere indici su varchars, non puoi su testo.
Omar Qureshi,

12
L'implementazione di PostgreSQL preferisce il testo. L'unica differenza per la stringa / testo pg è il vincolo sulla lunghezza della stringa. Nessuna differenza di prestazioni.
Andy Bettisworth,

Questa non sembra essere l'intera storia di ActiveRecord. Salvare il valore truesu un varchar (ergo, stringtype field) in MySQL serializza il valore su 1(che è completamente corretto). Tuttavia, sotto texttype, la memorizzazione del valore "true" finisce per serializzarlo come un carattere singolare t. Ho migrato una colonna senza rendermene conto e tutte le righe future in cui il valore è vero è ora t. Qualcuno ha qualche idea su questo comportamento?
Peter,

1
@ elli0t significa che non sarai in grado di indicizzare. Se questo è importante, non dovresti usare il testo su MySQL
Omar Qureshi il

157

Se stai usando Postgres usa il testo ovunque tu sia, a meno che tu non abbia un limite di dimensioni poiché non vi è alcuna penalità prestazionale per text vs varchar

Non vi è alcuna differenza di prestazioni tra questi tre tipi, a parte un maggiore spazio di archiviazione quando si utilizza il tipo con riempimento vuoto e alcuni cicli CPU aggiuntivi per controllare la lunghezza durante l'archiviazione in una colonna con vincoli di lunghezza. Sebbene il carattere (n) presenti vantaggi in termini di prestazioni in alcuni altri sistemi di database, PostgreSQL non offre tali vantaggi; infatti il ​​carattere (n) è di solito il più lento dei tre a causa dei suoi costi di archiviazione aggiuntivi. Nella maggior parte dei casi, invece, è necessario utilizzare testo o caratteri diversi

Manuale PostsgreSQL


4
Ma nell'interesse di essere indipendenti dal database, è questo l'approccio migliore? Cosa succede se si desidera modificare il database? Concedo, nel mondo reale che non accade così spesso, ma comunque ... se non c'è "nessuna differenza di prestazione", perché non attenersi all'uso previsto della stringa per cose brevi e testo per cose più lunghe? E dato il tuo commento indicizzando le stringhe, sembra ancora l'approccio migliore.
Dan Barron,

6
Esistono diversi motivi per cui potrebbe essere necessario nel mondo reale, dove è meglio abbandonare l'idea che esiste una vera soluzione a qualsiasi problema.
Dan Barron,

14
Potrebbe essere così, ma l'agnosticismo del database è un falso profeta.
Omar Qureshi,

2
Qualcuno ha qualche informazione sul fatto che la penalità delle prestazioni sia significativa o è un caso di ottimizzazione prematura? Suppongo che non noterai mai una differenza, che l'apertura del paragrafo sembra confermare: "Non c'è differenza di prestazioni tra questi tre tipi".
Dennis,

5
Hai un buon punto, ma non sono del tutto convinto. Gli argomenti in questo post del blog per l'utilizzo di textpiù di (n)tipi di dati sono convincenti, ma l'argomento per l'utilizzo di textsopra varcharnon è. Dice che sono gli stessi, ma preferisce textperché varcharpuò essere confuso varchar(n)e perché textè meno caratteri da digitare. Usando textinvece di varchar, perdi il contesto in cui i dati memorizzati non dovrebbero essere lunghi. Ad esempio, la memorizzazione di un nome utente con textmi sembra fuorviante.
Dennis,

17

String si traduce in "Varchar" nel database, mentre il testo si traduce in "testo". Un varchar può contenere molti meno elementi, un testo può avere (quasi) qualsiasi lunghezza.

Per un'analisi approfondita con buoni riferimenti, consultare http://www.pythian.com/news/7129/text-vs-varchar/

Modifica: alcuni motori di database possono essere caricati varcharin una volta sola, ma memorizzano il testo (e il BLOB) all'esterno della tabella. A SELECT name, amount FROM productspotrebbe, essere molto più lento quando si utilizza textper namerispetto a quando si utilizza varchar. E poiché Rails, per impostazione predefinita SELECT * FROM...verranno caricati i record con le colonne di testo. Questo probabilmente non sarà mai un vero problema nella tua o nella mia app (l'ottimizzazione prematura è ...). Ma sapere che il testo non è sempre "libero" è bene sapere.


12

Stringa se la dimensione è fissa e piccola e testo se è variabile e grande. Questo è molto importante perché il testo è molto più grande delle stringhe. Contiene molti più kilobyte.

Quindi per i campi piccoli usare sempre string (varchar). I campi piacciono. nome, login, e-mail, oggetto (di un articolo o post) ed esempio di testi: contenuto / corpo di un post o articolo. campi per paragrafi ecc

Dimensioni stringa da 1 a 255 (impostazione predefinita = 255)

Dimensioni del testo da 1 a 4294967296 (impostazione predefinita = 65536) 2


11

Come spiegato sopra, non solo il tipo di dati db influirà anche sulla vista che verrà generata se si utilizza il ponteggio. string genererà un campo_testo il testo genererà un'area_testo


2

Usa una stringa per campi più corti, come nomi, indirizzo, telefono, azienda

Usa il testo per contenuti più grandi, commenti, contenuti, paragrafi.

La mia regola generale, se è qualcosa che è più di una riga, di solito vado per il testo, se sono brevi 2-6 parole, vado per la stringa.

La regola ufficiale è 255 per una stringa. Quindi, se la stringa contiene più di 255 caratteri, cerca il testo.


1

Se stai usando l'oracolo ... STRINGverrà creato come VARCHAR(255)colonna e TEXT, come a CLOB.

NATIVE_DATABASE_TYPES = {
    primary_key: "NUMBER(38) NOT NULL PRIMARY KEY",
    string: { name: "VARCHAR2", limit: 255 },
    text: { name: "CLOB" },
    ntext: { name: "NCLOB" },
    integer: { name: "NUMBER", limit: 38 },
    float: { name: "BINARY_FLOAT" },
    decimal: { name: "DECIMAL" },
    datetime: { name: "TIMESTAMP" },
    timestamp: { name: "TIMESTAMP" },
    timestamptz: { name: "TIMESTAMP WITH TIME ZONE" },
    timestampltz: { name: "TIMESTAMP WITH LOCAL TIME ZONE" },
    time: { name: "TIMESTAMP" },
    date: { name: "DATE" },
    binary: { name: "BLOB" },
    boolean: { name: "NUMBER", limit: 1 },
    raw: { name: "RAW", limit: 2000 },
    bigint: { name: "NUMBER", limit: 19 }
}

https://github.com/rsim/oracle-enhanced/blob/master/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb


1

La risposta accettata è fantastica, spiega correttamente la differenza tra stringa e testo (principalmente la dimensione limite nel database, ma ci sono alcuni altri trucchi), ma volevo sottolineare un piccolo problema che mi ha fatto superare come risposta non l'ha fatto completamente per me.

La dimensione massima : limite => 1 a 4294967296 non ha funzionato esattamente come indicato, avevo bisogno di andare -1 da quella dimensione massima. Sto memorizzando grandi BLOB JSON e potrebbero essere pazzi enormi a volte.

Ecco la mia migrazione con il valore maggiore in atto con il valore di cui MySQL non si lamenta.

Nota il 5 alla fine del limite anziché il 6

class ChangeUserSyncRecordDetailsToText < ActiveRecord::Migration[5.1]
  def up
    change_column :user_sync_records, :details, :text, :limit => 4294967295
  end

  def down
    change_column :user_sync_records, :details, :string, :limit => 1000
  end
end

0

Se l'attributo corrisponde f.text_fieldnel modulo, utilizza la stringa , se corrisponde f.text_areautilizza il testo .

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.