Подтвердить что ты не робот

Какая проверка делает MySQL, когда включен строгий режим?

Я был очень удивлен, когда MySQL разрешил мне вставить NULL в поле, созданное с помощью NOT NULL. Я провел некоторое исследование и обнаружил, как включить строгий режим. Тем не менее, я не совсем уверен, какая проверка MySQL делает, когда STRICT_ALL_TABLES включен.

В руководстве написано:

Строгий режим определяет, как MySQL обрабатывает недопустимые или отсутствующие входные значения. Значение может быть недопустимым по нескольким причинам. (выделение мое) Например, у него может быть неправильный тип данных для столбца, или он может быть вне допустимого диапазона.

Я понимаю, что он считает отсутствующим, и как он справляется с этим. Я не понимаю, что он считает недействительным. Я провел некоторое тестирование и обнаружил следующее:

  • Строки
  • которые слишком длинны, недействительны.
  • недопустимые номера
  • NULL для столбца не NULL недействительны
  • TRUE и FALSE всегда кажутся действительными (они становятся равными 1 и 0 соответственно)
  • неверные даты недействительны
  • нулевые даты действительны (для изменения этого поведения могут быть разрешены дополнительные режимы)
  • float в целочисленном поле действительны (они округляются)
  • буквы в поле числа недействительны

Выполняет ли MySQL другие проверки валидации, отличные от того, что упоминалось выше?

В руководстве написано "неправильный тип данных для столбца", но единственная ситуация, когда я вижу, что это фактически входит в игру, - это буквы в поле чисел. Существуют ли другие примеры ошибок типа данных?

Есть ли список где-то точно, какие проверки MySQL выполняет?

РЕДАКТИРОВАТЬ:. Для записи мое приложение уже проводит обширную проверку. Я использую строгий режим как последний шанс, только в случае проверки. Если я забуду что-то проверить, я хочу, чтобы он быстро сработал, а не "молчал какими-то моими данными".

4b9b3361

Ответ 1

Хорошим ресурсом является проверка источника MySQL и чтение mysql-test/t/strict.test для просмотра всех случаев, которые они тестируют после установки режима STRICT или TRADITIONAL (что является надстрокой STRICT).

Вы отлично провели исследования и испытания, но есть еще несколько случаев, таких как:

  • Попытка вставить значение undefined ENUM.
  • Попытка вставить значение по умолчанию для столбца NOT NULL без определения DEFAULT.
  • Попытка использовать CAST() для преобразования строк в целые числа и т.д.
  • Преобразование VARCHAR в MEDIUMTEXT или LONGTEXT, если вы даете длину больше 65536.
  • Усечение строк COMMENT для таблиц и столбцов.
  • Преобразование строки в тип YEAR.
  • Определение столбца SET или ENUM с повторяющимися записями.

Также mysql-test/include/strict_autoinc.inc, потому что он проверяет переполнение, когда значение auto-inc становится слишком большим.

Есть несколько других тестовых файлов, которые используют STRICT-режим для определенных тестов, но я не рассматривал их.

Ответ 2

Я скопировал исходный код MySQL 5.5.28 (Community Server Edition), чтобы найти экземпляры используемых STRICT_ALL_TABLES.

Из того, что я увидел, похоже, что ваш список уже довольно полный, но ниже есть еще несколько вещей, которые я узнал об использовании STRICT_ALL_TABLES. Первая - это еще одна проверка, в то время как все остальные имеют дело с ошибками и предупреждениями.

  • В столбцах геометрии не может быть значения по умолчанию. (SQL/field.cc: 9394)
  • Если комментарий таблицы длиннее 2048 символов, MySQL создает ошибку, а не усекает комментарий с предупреждением. (SQL/unireg.cc: 231)
  • Если комментарий поля длиннее 1024 символов, MySQL выдает ошибку, а не усекает комментарий с предупреждением. (SQL/unireg.cc: 739)
  • При вставке или обновлении, если дублирующее значение существует в SET или ENUM MySQL, выдается ошибка, а не предупреждение. (SQL/sql_table.cc: 2503)
  • Существует множество операций, которые будут прерваны при предупреждении с помощью STRICT_ALL_TABLES, а не просто с предупреждением. Это слишком много для меня, чтобы список, и установка флага abort_on_warning слишком далека от кода, который создает предупреждения для меня, чтобы легко документировать (или даже понимать) все из них. Но если кто-то хочет замарать руки в исходном коде, несколько начальных мест будут sql/sql_update.cc: 630 и sql/sql_insert.cc: 841