Різниця між рядком і текстом у рейках?


435

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

Відповіді:


522

Різниця залежить від того, як символ перетворюється у відповідний тип стовпця мовою запиту.

за допомогою 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
Закон Reed G.

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

12
Реалізація PostgreSQL віддає перевагу тексту. Єдина відмінність для рядка / тексту pg - це обмеження довжини для рядка. Відмінності у виконанні відсутні.
Енді Беттісворт

Здається, це не вся історія з ActiveRecord. Збереження значення trueв varchar (ergo, stringполе типу) в MySQL серіалізує значення to 1(що цілком справедливо). Однак під textтипом зберігання значення "true" закінчується серіалізацією його як особливого символу t. Я перемістив стовпчик, не усвідомлюючи це, і всі майбутні рядки, де значення є істинним, є зараз t. Хтось має уявлення про таку поведінку?
Петро

1
@ elli0t це означає, що ви не зможете індексувати. Якщо це важливо, тоді вам не слід використовувати текст на MySQL
Омар Куреші

157

Якщо ви використовуєте postgres, використовуйте текст куди завгодно, якщо тільки ви не маєте обмеження розміру, оскільки не існує штрафу за ефективність тексту проти varchar

Немає різниці в продуктивності між цими трьома типами, окрім збільшення місця на зберігання при використанні пустого типу та декількох додаткових циклів процесора для перевірки довжини під час зберігання в стовпчику з обмеженою довжиною. Хоча персонаж (n) має переваги у роботі в деяких інших системах баз даних, у PostgreSQL такої переваги немає; насправді персонаж (n), як правило, найповільніший з трьох через його додаткові витрати на зберігання. У більшості ситуацій замість цього слід використовувати текст чи символи, що змінюються

Посібник погрешної поштиSQL


4
Але в інтересах бути агностиком бази даних, це найкращий підхід? Що робити, якщо ви хочете змінити базу даних? Я реалізую, що в реальному світі це трапляється не так часто, але все ж ... якщо немає "різниці між показниками", чому б не дотримуватися очікуваного використання рядка для коротких речей та тексту для довших речей? А враховуючи власні рядки індексації коментарів, все ще здається найкращим підходом.
Ден Баррон

6
Існує будь-яка кількість причин, чому це може стати необхідним у реальному світі, де найкраще пролити поняття про те, що існує одне справжнє рішення будь-якої проблеми.
Ден Баррон

14
Це може бути так, але агностицизм бази даних - це хибний пророк.
Омар Куреші

2
Хтось має якусь інформацію про те, чи є покарання за ефективність чи це випадок передчасної оптимізації? Я здогадуюсь, що ви ніколи не помітите різниці, що, здається, відкриття абзацу підтверджує: "Існує різниця в продуктивності серед цих трьох типів".
Денніс

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

17

Рядок перекладається на "Varchar" у вашій базі даних, а текст - на "text". Варчар може містити набагато менше елементів, текст може бути (майже) будь-якої довжини.

Для глибокого аналізу з хорошими посиланнями перевірте 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, це також вплине на представлення, яке буде сформовано, якщо ви будуєте ліси. рядок буде генерувати текст_польового тексту, генерує text_area


2

Використовуйте рядок для коротшого поля, як-от імена, адреса, телефон, компанія

Використовуйте текст для збільшення вмісту, коментарів, змісту, абзаців.

Моє загальне правило, якщо це щось більше, ніж один рядок, я зазвичай іду за текстом, якщо це короткі 2-6 слів, я переходжу до рядка.

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


1

Якщо ви використовуєте oracle ... 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.