Почему текстовый столбец не может иметь значение по умолчанию в MySQL?

Если вы попытаетесь создать текстовый столбец в таблице и дать ему значение по умолчанию в MySQL, вы получите ошибку (по крайней мере, в Windows). Я не вижу причин, по которым текстовый столбец не должен иметь значения по умолчанию. Никакое объяснение не дается документацией MySQL. Это кажется мне нелогичным (и несколько разочаровывает, так как я хочу значение по умолчанию!). Кто-нибудь знает, почему это запрещено?

8 ответов


Windows MySQL v5 выдает ошибку, но Linux и другие версии только вызывают предупреждение. Это нужно исправить. WTF?

Также см. попытку исправить это как ошибку #19498 в MySQL Bugtracker:

Брайс Несбитт 4 апреля 2008 в 4:36pm:
В MS Windows правило "нет по умолчанию" является ошибкой, в то время как на других платформах это часто предупреждение. Хотя это не ошибка, можно попасть в ловушку, если вы пишете код на мягкой платформе, а позже запустите его на строгой платформе:

лично я рассматриваю это как ошибку. Поиск "BLOB/TEXT column не может иметь значения по умолчанию" возвращает около 2,940 результатов в Google. Большинство из них-сообщения о несовместимости при попытке установить сценарии БД, которые работали в одной системе, но не в других.

я сталкиваюсь с той же проблемой сейчас на веб-приложении, которое я изменяю для одного из моих клиентов, первоначально развернутого на Linux MySQL v5.0.83-log. Я бегу Окна в MySQL версии 5.1.41. Даже пытаясь использовать последнюю версию phpMyAdmin для извлечения базы данных, он не сообщает о значении по умолчанию для рассматриваемого текстового столбца. Тем не менее, когда я пытаюсь запустить вставку в Windows (которая отлично работает в развертывании Linux), я получаю ошибку без значения по умолчанию в столбце ABC. Я пытаюсь воссоздать таблицу локально с очевидным значением по умолчанию (на основе выбора уникальных значений для этого столбца) и в конечном итоге получить oh-so-useful столбец BLOB/TEXT не может иметь значение по умолчанию значение.

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


Как отключить строгий режим в MySQL 5 (Windows):

  • Edit / 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'");

без каких-либо глубоких знаний о движке mySQL, я бы сказал, что это звучит как стратегия сохранения памяти. Я предполагаю, что причина стоит за этим абзацем из docs:

каждый BLOB или текстовое значение представляется внутри отдельно выделенного объекта. Это отличие от всех других типов данных, для которых хранилище выделяется один раз на столбец при открытии таблицы.

похоже, что предварительное заполнение этих типов столбцов приведет в памяти и снижения производительности.


вы можете получить тот же эффект, что и значение по умолчанию, используя триггер

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 ;

" поддержка по умолчанию в Столбцах TEXT/BLOB" это запрос функции в MySQL Bugtracker (ошибка #21532).

Я вижу, что я не единственный, кто хотел бы поместить значение по умолчанию в текстовый столбец. Я думаю, что эта функция должна поддерживаться в более поздней версии MySQL.

Это не может быть исправлено в версии 5.0 MySQL, потому что, по-видимому, это вызовет несовместимость и dataloss, если кто-то попытается передать базу данных туда и обратно между (текущие) базы данных, которые не поддерживают эту функцию, и любые базы данных, которые поддерживали эту функцию.


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

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

// 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');

вот и все.


а самый главный вопрос:

кто-нибудь знает, почему это не допускается?

все еще не ответил, я сделал быстрый поиск и нашел относительно новое дополнение от разработчика MySQL в MySQL Ошибки:

[17 Mar 2017 15: 11] Ståle Deraas

опубликовано разработчик:

это действительно действительный запрос функции, и на первый взгляд может показаться тривиальным добавить. Но значения TEXT/BLOBS не хранится непосредственно в буфере записи, используемом для чтения / обновления таблиц. Поэтому немного сложнее назначить им значения по умолчанию.

это не определенный ответ, но, по крайней мере, отправная точка для почему вопрос.

в то же время я просто закодирую его и либо сделаю столбец nullable, либо явно назначу (default '') значение для каждого insert из кода приложения...


Для Ubuntu 16.04:

Как отключить строгий режим в MySQL 5.7:

редактировать файл / etc/mysql / mysql.conf.д/тузды.cnf

Если ниже строка существует в mysql.cnf

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

затем замените его на

sql_mode='MYSQL40'

иначе

просто добавьте строку ниже в mysqld.cnf

sql_mode='MYSQL40'

эта проблема решена.


что именно вы делаете? Быстрый тест здесь показал, что текстовый столбец вполне может иметь значение по умолчанию:

    mysql> create table test (a char(32) not null default 'this works', b char(32) not null);
    Query OK, 0 rows affected (0.03 sec)
    mysql> insert into test (b) values('hello');
    Query OK, 1 row affected (0.01 sec)
    mysql> select * from test;

+------------+-------+
| a          | b     |
+------------+-------+
| this works | hello |
+------------+-------+
1 row in set (0.00 sec)