Разница между строкой и текстом в рельсах?


436

Я делаю новое веб-приложение с использованием Rails, и мне было интересно, в чем разница между stringи text? И когда каждый должен использоваться?

Ответы:


523

Разница заключается в том, как символ преобразуется в соответствующий тип столбца на языке запросов.

с MySQL: строка сопоставлена ​​с 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)

Ссылка:

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

Когда каждый должен быть использован?

Как общее практическое правило, используйте :stringдля краткого ввода текста (имя пользователя, адрес электронной почты, пароль, заголовки и т. Д.) И используйте :textдля более продолжительного ввода, такого как описания, комментарии и т. Д.


11
Я думаю, что лучшее правило - всегда использовать :text. См. Depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Рид Дж. Закон

74
Для MySQL - не так много, вы можете иметь индексы для varchars, вы не можете для текста.
Омар Куреши

12
Реализация PostgreSQL предпочитает текст. Единственное отличие для pg string / text - это ограничение длины для строки. Нет различий в производительности.
Энди Беттисворт

Похоже, это не вся история с ActiveRecord. Сохранение значения trueв varchar (ergo, stringполе типа) в MySQL сериализует значение в 1(что совершенно справедливо). Однако при textтипе сохранение значения «true» приводит к его сериализации в виде единственного символа t. Я перенес столбец, не осознавая этого, и все будущие строки, где значение true, сейчас t. У кого-нибудь есть понимание этого поведения?
Питер

1
@ elli0t это означает, что вы не сможете индексировать. Если это важно, то вы не должны использовать текст на MySQL
Омар Куреши

157

Если вы используете postgres, используйте текст везде, где только можете, если только у вас нет ограничений по размеру, так как для текста и varchar не снижается производительность

Между этими тремя типами нет разницы в производительности, за исключением увеличения места для хранения при использовании типа с пробелом и нескольких дополнительных циклов ЦП для проверки длины при сохранении в столбце с ограниченной длиной. Хотя символ (n) имеет преимущества в производительности в некоторых других системах баз данных, в PostgreSQL такого преимущества нет; на самом деле символ (n) обычно самый медленный из трех из-за дополнительных затрат на хранение. В большинстве случаев вместо текста следует использовать различные символы или символы.

Руководство по PostsgreSQL


4
Но в интересах быть независимым от базы данных, это лучший подход? Что делать, если вы хотите изменить базу данных? Я допускаю, что в реальном мире это случается не так часто, но все же ... если нет «разницы в производительности», почему бы не придерживаться ожидаемого использования строки для коротких вещей и текста для более длинных вещей? И учитывая ваши собственные строки индексации комментариев, по-прежнему кажется лучшим подходом.
Дэн Баррон,

6
Существует множество причин, по которым это может понадобиться в реальном мире, где лучше отказаться от идеи, что существует единственное верное решение для любой проблемы.
Дэн Баррон

14
Это может быть так, но агностицизм базы данных - это лжепророк.
Омар Куреши

2
Есть ли у кого-нибудь какая-либо информация о значительном снижении производительности или это преждевременная оптимизация? Полагаю, вы никогда не заметите разницу, которую, как кажется, подтверждает открытие параграфа: «Между этими тремя типами нет разницы в производительности».
Деннис

5
Вы делаете хорошее замечание, но я не совсем убежден. Аргументы в этом посте для использования textнад (n)типами данных убедительны, но аргумент для использования textнад varcharне. Он говорит, что они одинаковы, но предпочитает, textпотому что varcharих можно спутать varchar(n)и потому, что textменьше символов для ввода. Но textвместо этого varcharвы теряете контекст, в котором хранящиеся данные не должны быть длинными. Например, сохранение имени пользователя с помощью textмне кажется вводящим в заблуждение.
Деннис

17

Строка переводится как «Varchar» в вашей базе данных, а текст переводится как «текст». Varchar может содержать гораздо меньше элементов, текст может быть (почти) любой длины.

Для углубленного анализа с хорошими ссылками проверьте http://www.pythian.com/news/7129/text-vs-varchar/

Редактировать: некоторые движки базы данных могут загружаться varcharза один раз, но хранить текст (и большие двоичные объекты) вне таблицы. А SELECT name, amount FROM productsможет быть намного медленнее при использовании textдля, nameчем когда вы используете varchar. А так как Rails по умолчанию загружает записи с SELECT * FROM...вашими текстовыми колонками, будут загружены. Это, вероятно, никогда не будет реальной проблемой в вашем или моем приложении, хотя (преждевременная оптимизация ...). Но знание того, что текст не всегда «бесплатный», полезно знать.


12

Строка, если размер фиксированный и маленький, и текст, если он переменный и большой. Это очень важно, потому что текст больше строк. Он содержит намного больше килобайт.

Поэтому для небольших полей всегда используйте строку (varchar). Поля как. имя, логин, адрес электронной почты, тема (статьи или сообщения) и пример текстов: содержание / текст сообщения или статьи. поля для абзацев и т. д.

Размер строки от 1 до 255 (по умолчанию = 255)

Размер текста от 1 до 4294967296 (по умолчанию = 65536) 2


11

Как объяснено выше, не только тип данных db, это также повлияет на представление, которое будет сгенерировано, если вы создаете леса. строка сгенерирует текстовое поле текст сгенерирует текстовое поле


2

Используйте строку для более короткого поля, как имена, адрес, телефон, компания

Используйте текст для большего содержания, комментариев, контента, абзацев.

Мое общее правило: если речь идет о чем-то, что больше чем одна строка, я обычно иду за текстом, если это короткие 2-6 слов, я иду за строкой.

Официальное правило - 255 для строки. Итак, если ваша строка содержит более 255 символов, перейдите к тексту.


1

Если вы используете оракул ... STRINGбудет создан как VARCHAR(255)столбец и TEXT, как 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

Принятый ответ удивителен, он правильно объясняет разницу между строкой и текстом (в основном это предельный размер в базе данных, но есть несколько других ошибок), но я хотел указать на небольшую проблему, которая заставила меня пройти через этот ответ не полностью сделал это для меня.

Максимальный размер : limit => 1 до 4294967296 не работает точно так, как положено, мне нужно было перейти -1 от этого максимального размера. Я храню большие капли JSON, и иногда они могут быть сумасшедшими.

Вот моя миграция с большим значением на месте со значением, на которое MySQL не жалуется.

Обратите внимание на 5 в конце лимита вместо 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

Если атрибут соответствует f.text_fieldв форме, используйте строку , если он соответствует, f.text_areaиспользуйте текст .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.