Как удалить при обновлении текущей метки времени из существующего столбца?

Я сделал дамп базы данных mysql 5.5 и загрузил ее на сервер 5.6.

дамп добавлен при обновлении CURRENT_TIMESTAMP в кучу столбцов, которые не имели его ранее.

Я ищу ALTER TABLE оператор, который удалит правило ON UPDATE CURRENT_TIMESTAMP без внесения каких-либо других изменений. В моем воображении это должно быть что-то вроде ON UPDATE NOOP или ON UPDATE NO_CURRENT_TIMESTAMP.

ON UPDATE JUST_BE_A_NORMAL_COLUMN?

Я попытался использовать опцию "очистить по умолчанию" в mysql workbench и он сделал противоположное тому, что он должен был сделать - он дал столбцу значение по умолчанию!

я смог избавиться от значения по умолчанию с помощью ALTER TABLE t ALTER COLUMN c DROP DEFAULT, поэтому столбец является обязательным во вставках (так же, как это было до дампа/перезагрузки, как я хотел), но нежелательное поведение при обновлениях остается.

Я не включил . Если бы я начинал с нуля, я бы определенно использовал этот вариант, так как он кажется намного более разумным. Но так как у меня уже были колонки настроенный так, как я хотел их в 5.5, я ожидал, что они сохранят ту же семантику при передаче в 5.6. Очевидно, mysqldump просто не был достаточно умен.

на данный момент я не уверен, что понимаю, какие эффекты будут результатом включения explicit_defaults_for_timestamp. Изменит ли этот параметр поведение существующих таблиц или изменит только интерпретацию будущих команд CREATE TABLE? Включил бы его, как-нибудь, помог бы мне исправить сломанное? колонны?

обновление:

аналогичный вопрос здесь но это касается создания новой таблицы, а не изменения существующего столбца. На самом деле этот вопрос я использовал в качестве руководства при создании таблиц на сервере 5.5. Я использовал 2 этапов: Создание с 0 и подавить на ТЕКУЩАЯ_ОТМЕТКА_ВРЕМЕНИ обновление, затем опускаем по умолчанию.

2-ступенчатая процедура определенно не дает правильного результата на сервере 5.6 без explicit_defaults_for_timestamp; это признак того, что либо 5.6 не полностью имитирует старое поведение в этом режиме, либо старый сервер никогда не делал то, что я думал, что он делает. Не могу сказать точно.

4 ответов


ALTER TABLE mytable
     CHANGE mycolumn
            mycolumn TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

Я верить это сбросит и аннулирует ON UPDATE. Это эффективно сделало бы это определение:

CREATE TABLE mytable (
  # Other Columns
  mycolumn timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
)

изменить на этот:

CREATE TABLE mytable (
  # Other Columns
  mycolumn timestamp NOT NULL default CURRENT_TIMESTAMP
)

если вы хотите сбросить столбец полностью, вы должны быть в состоянии просто переопределить его, как:

ALTER TABLE mytable
     CHANGE mycolumn
            mycolumn TIMESTAMP NOT NULL;

используя идеи из других ответов и пару недавно установленных экземпляров сервера mysql, я сделал сравнение поведения нескольких разных команд CREATE и ALTER на 3 разных конфигурациях сервера:

  • mysql 5.5.45
  • mysql 5.6.26 без explicit_defaults_for_timestamp
  • mysql 5.6.26 с explicit_defaults_for_timestamp

самый простой для объяснения-5.6 с explicit_defaults_for_timestamp. Все в порядке. Тип timestamp не заметно отличается от любого другого типа. Столбцы, созданные до включения флага explicit_defaults_for_timestamp, сохраняют свои старые значения по умолчанию и обновление magic.

в 5.5 неявные значения по умолчанию возникают при создании столбца timestamp (если это первый столбец timestamp в таблице). Они уже хорошо задокументированы. Поведение обновления magic можно избежать, установив явное значение по умолчанию, и затем значение по умолчанию может быть удалено, оставив столбец с 3 желаемыми атрибутами: не-nullable, no default, no magic update. Это результат CREATE TABLE t (TIMESTAMP c NOT NULL DEFAULT 0) и ALTER TABLE t ALTER COLUMN c DROP DEFAULT.

это состояние не может быть воссоздано с помощью одной команды CREATE TABLE, и оно не переживает mysqldump.

5.6 без explicit_defaults_for_timestamp-самый интересный случай. Это почти то же самое, что и 5.5, но - разному. Если вы попробуете " создать с 0 по умолчанию, затем отбросьте последовательность "по умолчанию", атрибут Magic update появляется как побочный эффект капли. Но если вы сделаете ТЕКУЩАЯ_ОТМЕТКА_ВРЕМЕНИ по умолчанию вместо 0, тогда падение по умолчанию работает без побочных эффектов. (Должно быть, Жук. Я не могу представить, почему он намеренно ведет себя так.)

поэтому эта пара команд будет иметь тот же результат на всех конфигурациях сервера я проверил:

ALTER TABLE t CHANGE COLUMN c c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE t ALTER COLUMN c DROP DEFAULT;

столбец теперь не имеет значения по умолчанию и обновления magic.


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

ALTER TABLE `table` CHANGE COLUMN `col` `col` TIMESTAMP NOT NULL;

если я понимаю документация правильно включение explicit_defaults_for_timestamp является обязательным для определения TIMESTAMP столбцы, объявленные как NOT NULL и без явного DEFAULT.


для вашего случая использования я думаю, что вам будет лучше служить с DATETIME, например:

ALTER TABLE `my_table`
    CHANGE `my_col` `my_col` DATETIME NOT NULL DEFAULT NOW();

по умолчанию это значение NOW() on insert, но остаются неизменными при обновлении.

см. этот вопрос для хорошего объяснения разницы: должен ли я использовать поле "datetime" или "timestamp"?