Поиск
Как MySQL работает с ограничениями
MySQL позволяет работать как с транзакционными таблицами, для которых возможен откат, так и с нетранзакционными, для которых откат не предусмотрен, поэтому работа с ограничениями (constraints) в MySQL несколько отличается от того, как это делается в других СУБД. Нам приходится иметь дело с ситуацией, когда нужно обновить множество строк в нетранзакционной таблице, причем нет возможности выполнить откат при возникновении ошибки. Базовая философия состоит в том, чтобы попытаться сгенерировать ошибку для всего, что можно обнаружить во время компиляции, но попытаться восстановиться после любой ошибки, возникшей во время выполнения. Мы достигаем этого в большинстве случаев, но пока еще не во всех (см. раздел Новые средства, запланированные на ближайшее будущее). Выбор, который стоит перед MySQL сводится к тому, что в случае возникновения ошибки необходимо остановить выполнение оператора на полпути или восстановить данные настолько хорошо, насколько возможно, и продолжать работу. В последующих разделах описано, что происходит в этих случаях с различными типами ограничений.
Ограничение PRIMARY KEY/UNIQUE
Нормально, если генерируется ошибка при попытке вставить или обновить запись, которая приводит к нарушению ограничений первичного ключа, внешнего ключа или уникального ключа. Если используется транзакционный механизм хранения, подобный InnoDB, MySQL автоматически выполнит откат транзакции. Если же применяется не-транзакционный механизм хранения, MySQL остановится на некорректной записи и оставит все оставшиеся записи неизмененными. Чтобы облегчить жизнь, MySQL поддерживает ключевое слово IGNORE для большинства команд, которые могут привести к нарушению ключей (например, INSERT IGNORE или UPDATE IGNORE). В этих случаях MySQL просто игнорирует любые нарушения ограничений ключей и продолжает обрабатывать остальные строки. Информация о том, что предпринял MySQL, доступна через функцию mysql_info() API-интерфейса С. В MySQL 4.1 и последующих версиях можно также воспользоваться командой SHOW WARNINGS. Стоит напомнить, что на данный момент внешние ключи поддерживают только таблицы InnoDB. Реализация внешних ключей для таблиц MylSAM запланирована в версии MySQL 5.1.Ограничения NOT NULL и значения DEFAULT
Чтобы обеспечить простое управление нетранзакционными таблицами, все столбцы таблиц в MySQL имеют значения по умолчанию. Если вы вставляете ;неправильное; значение в столбец, такое как NULL в столбец, объявленный как NOT NULL, или же слишком большое значение в числовой столбец, MySQL установит его значение в ;лучшее из возможных; вместо того, чтобы выдавать ошибку:- Если вы попытаетесь сохранить в числовом столбце значение, выходящее за пределы допустимого диапазона, сервер MySQL вставит вместо него ноль, минимально возможное либо максимально возможное значение для этого столбца.
- В строковом столбце сервер MySQL сохранит либо пустую строку, либо самую длинную, которая может поместиться в данный столбец.
- Если вы попытаетесь вставить строку, начинающуюся не с цифры, в числовой столбец, MySQL запишет туда 0.
- Если попытаться вставить значение NULL в столбец, не допускающий значений NULL, MySQL вставит вместо этого 0 в числовой столбец и пустую строку - в символьный. (Однако такое поведение при вставке одиночных записей может быть изменено, если скомпилировать сервер MySQL с опцией компиляции -dont_use_default_fields.) Это заставит операторы INSERT генерировать ошибки, если только вы явно не зададите значения для всех столбцов, которые требуют значений NOT NULL.
- MySQL позволит сохранить некоторые неправильные значения даты в столбцы типа DATE и DATETIME (например '2000-02-31' или '2000-02-00'). Идея состоит в том, что проверка корректности дат не является обязанностью сервера SQL. Если MySQL может сохранять значение даты и извлекать точно такое значение, он со храняет его таким, как получил. Если дата абсолютно неправильная (за пределами возможностей сервера сохранить ее), то вместо нее сохраняется специальное значения
Причина существования изложенных правил заключается в том, что мы не можем проверить эти условия до тех пор, пока не начнется выполнение запроса. Мы не можем выполнить откат изменений, если сталкиваемся с проблемой после того, как несколько строк уже обновлены, поскольку данный тип таблиц может не поддерживать транзакции. Выбор в пользу прерывания выполнения оператора представляется неудачным - в этом случае получается, что обновление выполнено наполовину, что приводит к наихудшему сценарию. В этом случае предпочтительнее сделать ;лучшее из возможного; и затем продолжить, как будто ничего не произошло. Это означает, что не стоит полагаться на MySQL в смысле проверки корректности данных столбцов. Вместо этого приложение само должно заботиться о том, чтобы отправлять серверу MySQL только правильные данные. В MySQL 5.0 мы планируем провести улучшения, выдавая предупреждения, когда происходит автоматическое преобразование столбцов, плюс опцию, позволяющую откатить оператор, который пытается выполнить запрещенное присваивание данных до тех пор, пока используются только транзакционные таблицы. <р5> Ограничения ENUM и SET
В MySQL 4,x ЕШМ не является настоящим ограничением, а просто наиболее эффективным способом определения столбцов, которые могут содержать значения только из заданного набора возможных значений. Если вы вставляете некорректное значение в столбец типа ENUM, оно устанавливается в зарезервированное перечислимое значение 0, которое отображается как пустая строка в строчном контексте. При попытке вставки некорректного значения в столбец типа SET это значение игнорируется. Например, если столбец может содержать значения 'а', 'Ь' и 'с', попытка сохранить в столбце значения 'а,х,Ь,у' приведет к сохранению 'a,b'.