Чому текстовий стовпець не може мати значення MySQL за замовчуванням?


184

Якщо ви спробуєте створити стовпчик TEXT на таблиці і надати йому значення за замовчуванням у MySQL, ви отримаєте помилку (принаймні в Windows). Я не бачу жодної причини, чому текстовий стовпець не повинен мати значення за замовчуванням. Пояснення документацією на MySQL не дається. Мені це здається нелогічним (і дещо розчаровує, так як я хочу значення за замовчуванням!). Хтось знає, чому це не дозволено?


1
Чи можемо ми побачити використаний вами запит?
Роберт

2
Ви впевнені, що хочете колонку ТЕКСТ, а не ВАРХАР? СТЕКСТОВІ стовпці призначені для речей, довжина яких може перевищувати 255 байт.
scy

5
Це має бути коментар. Крім того, так, він має на увазі TEXT- ці стовпці не можуть мати значення за замовчуванням. VARCHARможе.
Pekka

1
Якщо ви використовуєте phpmyadmin для налаштування вашої бази даних, можливо, захочете дослідити інструменти mysql gui / workbench ...;)
dmp

1
Так, мені, на жаль, потрібно понад 255 символів.
Русс

Відповіді:


92

Windows MySQL v5 видає помилку, але Linux та інші версії викликають лише попередження. Це потрібно виправити. WTF?

Також дивіться спробу виправити це як помилку № 19498 в MySQL Bugtracker:

Брайс Несбітт 4 квітня 2008 р. 16:36:
У MS Windows правило "без DEFAULT" є помилкою, а на інших платформах це часто попередження. Хоча це не помилка, можливо, в цьому потрапити в пастку, якщо ви пишете код на поблажливій платформі, а пізніше запустите його на суворій платформі:

Особисто я вважаю це помилкою. Якщо шукати "BLOB / TEXT стовпець не може мати значення за замовчуванням", у Google з’являється близько 2940 результатів. Більшість з них - це повідомлення про несумісність при спробі встановлення сценаріїв БД, які працювали в одній системі, але не в іншій.

Зараз я зіткнувся з тією ж проблемою на веб-сайті, який я модифікую для одного з своїх клієнтів, спочатку розгорнутого в Linux MySQL v5.0.83-log. Я запускаю Windows MySQL v5.1.41. Навіть намагаючись використовувати останню версію phpMyAdmin для витягування бази даних, вона не повідомляє про типовий стовпець тексту, про який йде мова. Тим не менш, коли я намагаюся запустити вставку в Windows (це добре працює при розгортанні Linux), у колонці ABC я отримую помилку без замовчування. Я намагаюся відтворити локальну таблицю з явним за замовчуванням (на основі вибору унікальних значень для цього стовпця) і в кінцевому підсумку отримую о-настільки корисний стовпчик BLOB / TEXT не може мати значення за замовчуванням .

Знову ж таки, не підтримка базової сумісності на платформах є неприйнятною і є помилкою.


Як відключити суворий режим у MySQL 5 (Windows):

  • Відредагуйте /my.ini і шукайте рядок

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
  • Замініть його на

    sql_mode='MYSQL40'
  • Перезапустіть службу MySQL (якщо припустити, що це mysql5)

    net stop mysql5
    net start mysql5

Якщо у вас є доступ до root / admin, можливо, ви зможете виконати

mysql_query("SET @@global.sql_mode='MYSQL40'");

3
Якщо у вас є кореневий доступ і ви використовуєте phpMyAdmin, перейдіть на головну сторінку (натисніть логотип phpMyAdmin), перейдіть на вкладку Змінні, знайдіть змінну sql_mode та натисніть кнопку Змінити.
Гавін

1
Я перебуваю на CentOS 5.8 та MySQL v 14.14. Distrib 5.1.71 видає помилку замість попередження при спробі встановити значення TEXT у полі за замовчуванням. Просто хотілося б зауважити, що він працює не на кожній платформі Linux.
Алекс

OS X як мінімум, здається, призведе до помилок у ці дні. Документи dev.mysql.com/doc/refman/5.7/en/blob.html говорять: " Стовпці BLOB і TEXT не можуть мати значення ЗАМЕЧАННЯ ." FWIW (але не чому)
rogerdpack

31

Не маючи глибокого знання двигуна mySQL, я б сказав, що це звучить як стратегія збереження пам'яті. Я припускаю, що причина лежить в цьому пункті в документах :

Кожне значення BLOB або TEXT представлено внутрішньо окремо виділеним об'єктом. Це на відміну від усіх інших типів даних, для зберігання яких виділяється один раз на стовпчик при відкритті таблиці.

Схоже, попереднє заповнення цих типів стовпців призведе до штрафу за використання пам'яті та ефективність роботи.


5
-1: Зберігання даних, таких як назви міст, у колонці TEXT фактично займає менше загальної пам'яті, ніж зберігання тих же даних у стовпці CHAR або VARCHAR.
Девід Кері

5
@david керівництво, яке я цитую, стосується не пам’яті, а пошуку.
Pekka

1
Я не бачу, як це призведе до ненормального використання пам'яті та ефективності покарання. Очевидно, що коли користувач визначає значення за замовчуванням, він очікує, що показник буде досягнутий ефективності, незалежно від типу даних (особливо для масових операцій). Однак наскільки я розумію, ви стверджуєте, що для поля BLOB / TEXT цей показник продуктивності порівняно високий порівняно з іншими типами даних? І як це пов'язано з тим, що BLOB / TEXT зберігається внутрішньо як окремий об'єкт? Це не має для мене сенсу.
фрік

27
IMHO - це не стратегія збереження пам'яті. Це або помилка, або люди, які її написали, божевільні. І я думаю, що це остання, оскільки вони не можуть виправити це принаймні 8 років. Основний функціонал, який має кожна інша база даних.
фрік

2
Не важливо, все одно це має бути варіант для людей, які хочуть ним користуватися.
jurchiks

15

Ви можете отримати той же ефект, що і значення за замовчуванням, використовуючи тригер

create table my_text

(
   abc text
);

delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
   if (NEW.abc is null ) then
      set NEW.abc = 'default text';
   end if;
end
//
delimiter ;

14

Основне питання:

Хтось знає, чому це не дозволено?

як і раніше не відповіли, я здійснив швидкий пошук і знайшов порівняно нове доповнення від розробника MySQL в MySQL Bugs :

[17 березня 2017 15:11] Ståle Deraas

Опублікував розробник:

Це дійсно дійсний запит на функції, і на перший погляд це може здатися тривіальним. Але значення TEXT / BLOBS не зберігаються безпосередньо в буфері записів, який використовується для читання / оновлення таблиць. Тож присвоювати їм значення за замовчуванням трохи складніше.

Це не є однозначною відповіддю, але принаймні відправною точкою для того, чому питання.

Тим часом я просто зашифрую його навколо або зроблю стовпцем нульовим або явно призначуму (за замовчуванням '') значення для кожного insertз коду програми ...


13

"Підтримка DEFAULT у стовпцях TEXT / BLOB" - це запит на функцію в Mytrab Bugtracker (Помилка № 21532) .

Я бачу, що я не єдиний, хто хотів би поставити значення за замовчуванням у стовпець TEXT. Я думаю, цю функцію слід підтримувати в більш пізній версії MySQL.

Це неможливо виправити у версії 5.0 MySQL, оскільки, очевидно, це призведе до несумісності та втрати даних, якби хтось намагався перенести базу даних назад і назад між (поточними) базами даних, які не підтримують цю функцію, та будь-якими базами даних, які підтримували ця особливість.


Мені здається, ви повинні мати можливість змінити його між "" і NULL для стовпця "TEXT", який дозволяє "null". Це здається неможливим.
phpguru

6

Я зазвичай запускаю сайти в Linux, але також розвиваюсь на локальній машині Windows. Я багато разів стикався з цією проблемою і просто виправляв таблиці, коли стикався з проблемами. Вчора я встановив додаток, щоб допомогти комусь, і звичайно знову зіткнувся з проблемою. Отже, я вирішив, що настав час розібратися, що відбувається - і знайшов цю тему. Мені дуже не подобається ідея змінити sql_mode сервера на попередній режим (за замовчуванням), тому я придумав просте (мені здається) рішення.

Це рішення, звичайно, вимагатиме від розробників обгортати свої сценарії створення таблиць, щоб компенсувати випуск MySQL, що працює в Windows. Ви побачите подібні поняття у файлах дампа. Одним із застережень BIG є те, що це може / спричинить проблеми при використанні перегородки.

// Store the current sql_mode
mysql_query("set @orig_mode = @@global.sql_mode");

// Set sql_mode to one that won't trigger errors...
mysql_query('set @@global.sql_mode = "MYSQL40"');

/**
 * Do table creations here...
 */

// Change it back to original sql_mode
mysql_query('set @@global.sql_mode = @orig_mode');

Ось про це.


1
Це не стосується питання, чому MySQL взагалі має поведінку, але дякуємо, що поділилися своїм підходом, щоб і інші могли отримати користь. Ласкаво просимо до переповнення стека!
GargantuChet

1
Я знаю ... Мені доведеться далі заглянути в режим STRICT, щоб зрозуміти, чи є це сенсом - оскільки MySQL накидає попередження на вікна Nix, але не працює на вікнах Windows. Це вказівка ​​на те, що з реалізацією може бути щось не так, незалежно від платформи. Ви помітите, що в документації MySQL є таке повідомлення: "Стовпці BLOB і TEXT не можуть мати значення DEFAULT". Тож логічно виявляється, що реалізація у версіях до 5 насправді була порушена на всіх платформах.
Парник Даррелл

3

Для Ubuntu 16.04:

Як відключити суворий режим у MySQL 5.7:

Редагувати файл /etc/mysql/mysql.conf.d/mysqld.cnf

Якщо в mysql.cnf існує рядок нижче

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Потім замініть його

sql_mode='MYSQL40'

Інакше

Просто додайте нижній рядок у mysqld.cnf

sql_mode='MYSQL40'

Це вирішило проблему.

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