Différence entre chaîne et texte dans les rails?

436

Je crée une nouvelle application Web à l'aide de Rails et je me demandais quelle est la différence entre stringet text? Et quand faut-il les utiliser?

Mo.
la source

Réponses:

523

La différence repose sur la façon dont le symbole est converti en son type de colonne respectif dans le langage de requête.

avec MySQL: la chaîne est mappée sur 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)

Référence:

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

Quand faut-il utiliser chacun?

En règle générale, utilisez-le :stringpour la saisie de texte court (nom d'utilisateur, e-mail, mot de passe, titres, etc.) et utilisez-le :textpour une saisie plus longue, comme les descriptions, le contenu des commentaires, etc.

TJ Koblentz
la source
11
Je pense qu'une meilleure règle de base est de toujours utiliser :text. Voir depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law
74
Pour MySQL - pas tellement, vous pouvez avoir des index sur varchars, vous ne pouvez pas sur le texte.
Omar Qureshi
12
L'implémentation de PostgreSQL préfère le texte. La seule différence pour pg string / text est la contrainte de longueur pour string. Aucune différence de performance.
Andy Bettisworth
Cela ne semble pas être toute l'histoire avec ActiveRecord. L'enregistrement de la valeur truedans un varchar (ergo, stringchamp de type) dans MySQL sérialise la valeur 1(ce qui est tout à fait juste). Cependant, sous texttype, le stockage de la valeur "true" finit par le sérialiser en tant que caractère singulier t. J'ai migré une colonne sans m'en rendre compte et toutes les lignes futures où la valeur est vraie le sont maintenant t. Quelqu'un a-t-il une idée de ce comportement?
Peter
1
@ elli0t cela signifie que vous ne pourrez pas indexer. Si cela est important, vous ne devez pas utiliser de texte sur MySQL
Omar Qureshi
157

Si vous utilisez postgres, utilisez du texte partout où vous le pouvez, sauf si vous avez une contrainte de taille car il n'y a pas de pénalité de performance pour le texte vs varchar

Il n'y a pas de différence de performances entre ces trois types, à part un espace de stockage accru lors de l'utilisation du type à remplissage vierge et quelques cycles CPU supplémentaires pour vérifier la longueur lors du stockage dans une colonne à longueur limitée. Bien que le caractère (n) présente des avantages en termes de performances dans certains autres systèmes de base de données, il n'y en a pas dans PostgreSQL; en fait, le caractère (n) est généralement le plus lent des trois en raison de ses coûts de stockage supplémentaires. Dans la plupart des situations, le texte ou les caractères variant doivent être utilisés à la place

Manuel de PostsgreSQL

Omar Qureshi
la source
4
Mais dans l'intérêt d'être indépendant des bases de données, est-ce la meilleure approche? Et si vous voulez changer la base de données? J'accorde, dans le monde réel, que cela n'arrive pas souvent, mais quand même ... s'il n'y a pas de différence de performance, pourquoi ne pas s'en tenir à l'utilisation attendue de la chaîne pour les choses courtes et du texte pour les choses plus longues? Et compte tenu de vos propres chaînes d'indexation de commentaires, semble toujours la meilleure approche.
Dan Barron
6
Il y a un certain nombre de raisons pour lesquelles cela pourrait devenir nécessaire dans le monde réel, où il est préférable de se débarrasser de l'idée qu'il existe une seule vraie solution à tout problème.
Dan Barron
14
C'est peut-être vrai, mais l'agnosticisme des bases de données est un faux prophète.
Omar Qureshi du
2
Quelqu'un a-t-il des informations pour savoir si la pénalité de performance est importante ou s'agit-il d'un cas d'optimisation prématurée? Je suppose que vous ne remarquerez jamais de différence, ce que l'ouverture du paragraphe semble confirmer: "Il n'y a pas de différence de performance entre ces trois types".
Dennis
5
Vous faites valoir un bon argument, mais je ne suis pas entièrement convaincu. Les arguments de ce billet de blog pour l'utilisation textde (n)types de données Over sont convaincants, mais l'argument pour l'utilisation textOver varcharn'est pas. Il dit que ce sont les mêmes mais préfère textparce qu'il varcharpeut être confondu avec varchar(n)et parce qu'il texty a moins de caractères à taper. Mais en utilisant textau lieu de varchar, vous perdez le contexte selon lequel les données stockées ne devraient pas être longues. Par exemple, le stockage d'un nom d'utilisateur avec textme semble trompeur.
Dennis
17

La chaîne se traduit par "Varchar" dans votre base de données, tandis que le texte se traduit par "texte". Un varchar peut contenir beaucoup moins d'éléments, un texte peut avoir (presque) n'importe quelle longueur.

Pour une analyse approfondie avec de bonnes références, consultez http://www.pythian.com/news/7129/text-vs-varchar/

Modifier: certains moteurs de base de données peuvent se charger varcharen une seule fois, mais stocker du texte (et un blob) en dehors du tableau. Un SELECT name, amount FROM productspourrait être beaucoup plus lent lors de l'utilisation textde nameque lors de l'utilisation varchar. Et depuis Rails, par défaut, les enregistrements chargés avec SELECT * FROM...vos colonnes de texte seront chargés. Ce ne sera probablement jamais un vrai problème dans votre application ou dans celle-ci (l'optimisation prématurée est ...). Mais savoir que le texte n'est pas toujours "gratuit" est bon à savoir.

berkes
la source
12

Chaîne si la taille est fixe et petite et texte si elle est variable et grande. C'est assez important parce que le texte est bien plus gros que les chaînes. Il contient beaucoup plus de kilo-octets.

Donc, pour les petits champs, utilisez toujours string (varchar). Des domaines comme. prénom, login, email, sujet (d'un article ou d'un post) et exemple de textes: contenu / corps d'un post ou d'un article. champs pour les paragraphes, etc.

Taille de chaîne 1 à 255 (par défaut = 255)

Taille du texte 1 à 4294967296 (par défaut = 65536) 2

Gurudath BN
la source
11

Comme expliqué ci-dessus, non seulement le type de données db, il affectera également la vue qui sera générée si vous êtes un échafaudage. chaîne générera un text_field texte générera un text_area

Ravi D
la source
2

Utilisez une chaîne pour un champ plus court, comme les noms, l'adresse, le téléphone, la société

Utilisez du texte pour un contenu plus large, des commentaires, du contenu, des paragraphes.

Ma règle générale, si c'est quelque chose qui est plus d'une ligne, je vais généralement pour le texte, si c'est un court 2-6 mots, je vais pour la chaîne.

La règle officielle est 255 pour une chaîne. Donc, si votre chaîne contient plus de 255 caractères, optez pour le texte.

user2012677
la source
1

Si vous utilisez oracle ... STRINGsera créé comme VARCHAR(255)colonne et TEXT, comme 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
la source
1

La réponse acceptée est impressionnante, elle explique correctement la différence entre la chaîne et le texte (principalement la taille limite dans la base de données, mais il y a quelques autres pièges), mais je voulais souligner un petit problème qui m'a permis de passer au travers de cette réponse ne l'a pas complètement fait pour moi.

La taille maximale : limit => 1 à 4294967296 ne fonctionnait pas exactement comme indiqué, je devais aller à -1 à partir de cette taille maximale. Je stocke de gros blobs JSON et ils peuvent parfois être énormes.

Voici ma migration avec la plus grande valeur en place avec la valeur dont MySQL ne se plaint pas.

Notez le 5 à la fin de la limite au lieu 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
la source
0

Si l'attribut est correspondant à f.text_fieldl'utilisation de la forme chaîne , si elle est correspondant à l' f.text_areautilisation du texte .

CodingBingo
la source