Diferença entre string e texto nos trilhos?

435

Estou criando um novo aplicativo Web usando o Rails e fiquei pensando: qual é a diferença entre stringe text? E quando cada um deve ser usado?

Mo.
fonte

Respostas:

522

A diferença depende de como o símbolo é convertido em seu respectivo tipo de coluna na linguagem de consulta.

com o MySQL: a string é mapeada para 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)

Referência:

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

Quando cada um deve ser usado?

Como regra geral, use :stringpara entradas curtas de texto (nome de usuário, email, senha, títulos etc.) e use :textpara entradas esperadas mais longas, como descrições, conteúdo de comentários etc.

TJ Koblentz
fonte
11
Eu acho que uma regra de ouro melhor é sempre usar :text. Veja depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law
74
Para o MySQL - nem tanto, você pode ter índices em varchars, não em texto.
Omar Qureshi
12
A implementação do PostgreSQL prefere texto. A única diferença para pg string / text é a restrição no comprimento da string. Sem diferenças de desempenho.
precisa saber é o seguinte
Esta não parece ser a história completa com o ActiveRecord. Salvar o valor trueem um varchar (ergo, stringtype field) no MySQL serializa o valor para 1(o que é completamente justo). No entanto, no texttipo, armazenar o valor "true" acaba sendo serializado como um caractere singular t. Migrei uma coluna sem perceber isso e todas as linhas futuras em que o valor é verdadeiro são agora t. Alguém tem alguma idéia desse comportamento?
Peter
1
@ elli0t significa que você não poderá indexar. Se isso é importante, então você não deve usar texto no MySQL
Omar Qureshi
157

Se você estiver usando o postgres, use texto sempre que puder, a menos que você tenha uma restrição de tamanho, pois não há penalidade de desempenho entre texto e varchar

Não há diferença de desempenho entre esses três tipos, além do aumento do espaço de armazenamento ao usar o tipo preenchido em branco e alguns ciclos extras de CPU para verificar o comprimento ao armazenar em uma coluna com restrição de comprimento. Embora o caractere (n) tenha vantagens de desempenho em alguns outros sistemas de banco de dados, não existe essa vantagem no PostgreSQL; de fato, o caractere (n) geralmente é o mais lento dos três devido aos seus custos adicionais de armazenamento. Na maioria das situações, a variação de texto ou caractere deve ser usada

Manual do PostsgreSQL

Omar Qureshi
fonte
4
Mas, no interesse de ser independente de banco de dados, essa é a melhor abordagem? E se você quiser alterar o banco de dados? Eu admito que, no mundo real, isso não acontece com tanta frequência, mas ainda assim ... se não há 'diferença de desempenho', por que não seguir o uso esperado de string para coisas curtas e texto para coisas mais longas? E, considerando suas próprias seqüências de indexação de comentários, ainda parece a melhor abordagem.
Dan Barron
6
Existem inúmeras razões pelas quais isso pode se tornar necessário no mundo real, onde é melhor abandonar a noção de que existe uma solução verdadeira para qualquer problema.
Dan Barron
14
Pode ser que sim, mas o agnosticismo do banco de dados é um falso profeta.
Omar Qureshi
2
Alguém tem alguma informação sobre se a penalidade de desempenho é significativa ou se trata de um caso de otimização prematura? Meu palpite é que você nunca notará uma diferença, o que a abertura do parágrafo parece confirmar: "Não há diferença de desempenho entre esses três tipos".
Dennis
5
Você faz um bom argumento, mas não estou totalmente convencido. Os argumentos nessa postagem de blog sobre o uso de tipos de dados textexcessivos (n)são convincentes, mas o argumento de uso de textexcesso de dados varcharnão é. Ele diz que eles são iguais, mas prefere textporque varcharpode ser confundido varchar(n)e porque texthá menos caracteres para digitar. Mas, em textvez de usar varchar, você perde o contexto em que os dados armazenados não devem ser longos. Por exemplo, armazenar um nome de usuário com textparece enganador para mim.
Dennis
17

String traduz para "Varchar" no seu banco de dados, enquanto texto é traduzido para "texto". Um varchar pode conter muito menos itens, um texto pode ter (quase) qualquer comprimento.

Para uma análise aprofundada com boas referências, verifique http://www.pythian.com/news/7129/text-vs-varchar/

Editar: Alguns mecanismos de banco de dados podem carregar varcharde uma só vez, mas armazenam texto (e blob) fora da tabela. A SELECT name, amount FROM productspoderia ser muito mais lento ao usar textdo nameque ao usar varchar. E como o Rails, por padrão, carrega os registros com SELECT * FROM...suas colunas de texto. Isso provavelmente nunca será um problema real no seu ou no meu aplicativo (a otimização prematura é ...). Mas saber que o texto nem sempre é "gratuito" é bom saber.

berkes
fonte
12

Seqüência de caracteres se o tamanho for fixo e pequeno e texto se for variável e grande. Isso é importante porque o texto é muito maior que as strings. Ele contém muito mais kilobytes.

Portanto, para campos pequenos, use sempre string (varchar). Campos como. first_name, login, email, assunto (de um artigo ou postagem) e exemplo de textos: conteúdo / corpo de uma postagem ou artigo. campos para parágrafos etc

Tamanho da sequência de 1 a 255 (padrão = 255)

Tamanho do texto 1 a 4294967296 (padrão = 65536) 2

Gurudath BN
fonte
11

Como explicado acima, não apenas o tipo de dados db, ele também afetará a exibição que será gerada se você estiver com andaimes. string irá gerar um campo de texto texto irá gerar uma área de texto

Ravi D
fonte
2

Use string para campos mais curtos, como nomes, endereço, telefone, empresa

Use Texto para conteúdo maior, comentários, conteúdo, parágrafos.

Minha regra geral, se é algo que tem mais de uma linha, eu normalmente uso texto, se tiverem de duas a seis palavras curtas, uso string.

A regra oficial é 255 para uma sequência. Portanto, se sua string tiver mais de 255 caracteres, vá para o texto.

user2012677
fonte
1

Se você estiver usando o oracle ... STRINGserá criado como VARCHAR(255)coluna e TEXT, como 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

Luis
fonte
1

A resposta aceita é impressionante, explica corretamente a diferença entre string e texto (principalmente o tamanho limite no banco de dados, mas existem algumas outras dicas), mas eu queria destacar um pequeno problema que me levou a resolver essa questão não fez isso completamente por mim.

O tamanho máximo : limite => 1 a 4294967296 não funcionou exatamente como foi colocado, eu precisava ir -1 desse tamanho máximo. Estou armazenando blobs JSON grandes e eles podem ser enormes demais às vezes.

Aqui está minha migração com o valor maior no lugar com o valor que o MySQL não reclama.

Observe os 5 no final do limite em vez de 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
nategurutech
fonte
0

Se o atributo estiver correspondendo f.text_fieldno formulário, use string , se estiver correspondendo, f.text_areause text .

CodingBingo
fonte