Чим відрізняються типи даних MySQL VARCHAR від TEXT?


19

Після версії 5.0.3 (яка дозволила VARCHAR скласти 65535 байт і перестала обрізати пробіли), чи є якась значна різниця між цими двома типами даних?

Я читав список відмінностей, і єдині дві примітки:

Для індексів у стовпцях BLOB та TEXT потрібно вказати довжину префікса індексу. Для CHAR та VARCHAR довжина префікса необов’язково. Див. Розділ 7.5.1, “Індекси стовпців”.

і

Стовпці BLOB і TEXT не можуть мати значення DEFAULT.

Отже, через ці два обмеження на тип даних TEXT, чому б ви використовували його над varchar (65535)? Чи є наслідки ефективності роботи одна над іншою?


1
коли вам потрібно більше 65535 символів у даних?
BlackICE

Ось досить гарна тема форуму про орієнтири між varchar та текстом: http://forums.mysql.com/read.php?24,105964,105964
розділено

Оскільки в цьому списку дійсно добре розгортаються чіткі деталі, і оскільки у вас вже є перерахований перелік відмінностей, я не впевнений, що це питання, яке нам потрібно для DBA. Чи є причина, що список, який ви цитували, та причини, які ви наводили , недостатньо хороші в цьому випадку? Інакше я їду до VtC
jcolebrand

1
Я оновив своє запитання, але одна очевидна причина, в якій я не впевнений, - це виконання одного над іншим. Не впевнений, чи є інші не зовсім очевидні причини
Дерек Дауні

Тож чи справедливо те, що ви запитуєте - це характеристики продуктивності однієї над іншою?
jcolebrand

Відповіді:


13

розділена пов'язаною з деякою інформацією, яка пояснює основну проблему (є відмінності в продуктивності), але це не так просто, щоб сказати, що один завжди кращий за інший. (інакше не було б причини мати і те й інше.) Також у MyISM розмір не більше 64 к для VARCHAR не на поле - це на запис.

В основному, є 4 способи зберігання рядків у записах баз даних:

  1. фіксованої довжини
  2. Струни в стилі C (позначені символом NULL або подібним символом в кінці рядка)
  3. Рядки в стилі Pascal (кілька байт для позначення довжини, а потім рядок)
  4. Покажчики (рядок зберігайте десь в іншому місці)

MyISM використовує щось подібне до №3 для VARCHAR, а гібридний підхід для TEXT, де він зберігає початок рядка в записі, а потім решту рядка деінде. InnoDB схожий на VARCHAR, але зберігає повне поле TEXT поза записом.

З 1 і 4 матеріал у записі завжди однакової довжини, тому його простіше пропустити, якщо рядок вам не потрібна, але потрібні речі після неї. І №2, і №3 не надто погані для коротких рядків ... # 2 повинен продовжувати шукати маркер, тоді як №3 може пропуститись вперед ... у міру збільшення рядків довше, №2 стає гіршим для цього конкретного використання справа.

Якщо вам потрібно прочитати рядок, # 4 повільніше, як і ви повинні прочитати запис, а потім прочитайте рядок, який може зберігатися в іншому місці на диску, залежно від того, як обробляє цю базу даних. # 1 завжди досить простий, і знову ви стикаєтеся з подібними проблемами, коли для # 2 стає гірше, чим довше струна, тоді як №3 трохи гірше, ніж №2 для дуже маленьких струн, але краще, чим вона стає довшою.

Тоді є вимоги до зберігання ... # 1 - це завжди фіксована довжина, тому воно може роздуватися, якщо більшість рядків не є максимальною довжиною. №2 має 1 додатковий байт; # 3 зазвичай має 2 додаткові байти, якщо довжина макс = 255, 4 додаткові байти, якщо макс. 64 к. №4 має довжину вказівника, плюс правила для №3, як правило.

Для конкретних реалізацій в MySQL 5.1, документи для стану MyISM :

  • Підтримка справжнього типу VARCHAR; стовпець VARCHAR починається з довжини, збереженої в одному або двох байтах.
  • Таблиці зі стовпцями VARCHAR можуть мати фіксовану або динамічну довжину рядків.
  • Сума довжин стовпців VARCHAR та CHAR в таблиці може бути до 64 КБ.

У той час як для InnoDB :

  • Частина заголовка запису змінної довжини містить бітовий вектор для вказівки стовпців NULL. Якщо кількість стовпців в індексі, який може бути NULL, дорівнює N, бітовий вектор займає байт CEILING (N / 8). (Наприклад, якщо є десь від 9 до 15 стовпців, які можуть бути NULL, бітовий вектор використовує два байти.) Стовпці, які мають NULL, не займають іншого простору, ніж біт у цьому векторі. Частина заголовка змінної довжини також містить довжини стовпців змінної довжини. Кожна довжина займає один або два байти, залежно від максимальної довжини стовпця. Якщо всі стовпці в індексі НЕ NULL і мають фіксовану довжину, заголовок запису не має частини змінної довжини.
  • Для кожного поля без змінної довжини NULL заголовок запису містить довжину стовпця в одному або двох байтах. Два байти знадобляться лише в тому випадку, якщо частина стовпця зберігається зовні на переливних сторінках або максимальна довжина перевищує 255 байт і фактична довжина перевищує 127 байт. Для стовпця, що зберігається зовні, двобайтова довжина вказує довжину внутрішньо збереженої частини плюс 20-байтовий покажчик на зовнішньо збережену частину. Внутрішня частина - 768 байт, тому довжина - 768 + 20. 20-байтовий покажчик зберігає справжню довжину стовпця.

...

як і з багатьма іншими речами при роботі з базами даних, якщо ви не впевнені, що найкраще підходить для ваших потреб, спробуйте порівняти їх із подібними даними та використанням, і подивіться, як вони ведуть себе.


Нитка розділених зв’язків
Майкл Міор

1
Nitpick ... Для будь-яких практичних цілей не існує жодного обмеження в 64 Кб для ряду Двигуна. LONGTEXTі LONGBLOBє конкретним випадком. Струни в стилі C ніде не використовуються MySQL (про що я знаю). InnoDB використовує "гібридний" підхід, але він є більш складним, залежно від розміру рядка, row_format і т.д. . InnoDB має 4 ROW_FORMATs; текст обговорює лише 1 або 2 з них.
Рік Джеймс

2

Коли SELECT потрібно створити тимчасову таблицю (наприклад, для сортування результатів), вона створить або таблицю MEMORY, або таблицю MyISAM. ПАМ’ЯТКА ефективніша. Існують обмеження на ПАМ'ЯТЬ - одне - заборонити TEXT і BLOB. Тому SELECT може працювати повільніше з TEXT, ніж VARCHAR.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.