Поиск
Расширения стандартного SQL в MySQL
Мы стараемся, чтобы MySQL в основном следовал требованиям стандартов ANSI SQL и ODBC SQL, но в приведенных ниже случаях некоторые операции MySQL выполняет иначе:
- В столбцах типа VARCHAR завершающие пробелы удаляются при сохранении зна чения (см. раздел Известные ошибки и недостатки дизайна MySQL).
- В некоторых случаях столбцы типа CHAR скрыто преобразуются в VARCHAR, когда определяется либо изменяется структура таблицы.
- Привилегии для таблицы при удалении таблицы автоматически не удаляются. Для этого необходимо явно вызвать оператор REVOKE.
Подзапросы
MySQL 4.1 поддерживает подзапросы и вторичные таблицы. Подзапрос - это оператор SELECT, вложенный в другой оператор. Вторичная таблица (неименованное представление) - это подзапрос в конструкции FROM другого оператора. Для более старых версий MySQL большинство подзапросов могут быть переписаны в виде объединений или с использованием других методов.Оператор SELECT INTO TABLE
В сервере MySQL не реализована поддержка следующего расширения SQL от Sybase: SELECT... INTO TABLE... Вместо этого MySQL поддерживает стандартный SQL-синтаксис INSERT into ... select ..., который в основном делает то же самое. INSERT INTO tbl_temp2 (fldjLd) SELECT tbl_templ.fld_order_id FROM tbl_templ WHERE tbl_templ.fld_order__id ; 100; В качестве альтернативы можно воспользоваться SELECT INTO OUTFILE... или CREATE TABLE SELECT... Начиная с версии 5.0, MySQL поддерживает SELECT... INTO с пользовательскими переменными.Транзакции и атомарные операции
Сервер MySQL (старшие выпуски версий 3.23 и все версии, начиная с 4.0) поддерживает транзакции в механизмах хранения InnoDB и BDB. InnoDB обеспечивает полную совместимость с ACID. Остальные нетранзакционные механизмы хранения MySQL (такие, как MyISAM) следуют различным парадигмам обеспечения целостности данных, которые называются ;атомарными операциями;. В терминологии транзакций таблицы MyISAM всегда работают в режиме AUTOCOMMIT=1. Атомарные операции часто предлагают сопоставимую целостность с более высокой производительностью. Поскольку сервер MySQL поддерживает обе парадигмы, вы сами решаете, будут ли ваши приложения лучше работать со скоростью атомарных операций или с использованием средств управления транзакциями. Этот выбор осуществляется на уровне таблиц. Как упоминалось ранее, различия в работе между транзакционными и нетранзакци-онными таблицами отражаются в основном на производительности. Транзакционные таблицы требуют значительно больших затрат памяти, дискового пространства и нагрузки на центральный процессор. С другой стороны, транзакционные таблицы, подобные InnoDB, также предлагают много существенных дополнительных возможностей. Модульная архитектура сервера MySQL допускает одновременное использование разных механизмов хранения для удовлетворения различным требованиям и достижения оптимальной производительности во всех ситуациях. Но как использовать средства сервера MySQL для поддержки строгих требований целостности данных даже на нетранзакционных таблицах MyISAM, и как эти средства сравнить с работой с транзакционными таблицами?- Если ваше приложение написано таким образом, что оно зависит от возможности вызывать ROLLBACK вместо COMMIT в критических ситуациях, транзакции более удобны. Транзакции также гарантируют, что незавершенные обновления или ре зультаты сбоев не будут записаны в базу данных. Сервер имеет возможность вы полнить автоматический откат и сохранить базу данных. Если же вы применяете нетранзакционные таблицы, сервер MySQL почти во всех случаях предоставляет вам возможность разрешить потенциальные проблемы, включив простые провер ки перед обновлением или, запуская простые сценарии, которые проверяют базу данных на непротиворечивость и автоматически вносят исправления либо выдают предупреждения, если обнаружены какие-то противоречия. Стоит отметить, что даже просто включая протоколирование работы MySQL или добавляя дополни тельный протокол, вы можете нормально исправить таблицы без потери целост ности.
- В большинстве случаев критические транзакционные обновления могут быть пе реписаны как атомарные операции. Вообще говоря, все проблемы целостности, которые решают транзакции, могут быть предотвращены блокировкой таблиц LOCK table или атомарными обновлениями, гарантирующими, что вы никогда не будете автоматически прерваны сервером, что является общей проблемой тран закционных систем управления базами данных.
- Даже транзакционные системы могут терять данные, если сервер отключается. Разница между системами состоит только в том, насколько мал промежуток вре мени, в течение которого возможна потеря данных. Нет систем, безопасных на 100%, а есть только ;достаточно безопасные;. Даже СУБД Oracle, имеющая репу тацию наиболее безопасной из транзакционных систем, периодически сообщает об утере данных в ситуациях подобного рода
Для безопасной работы с сервером MySQL, независимо от того используются или нет транзакционные таблицы, нужно иметь резервные копии и держать включенным бинарное протоколирование. В этом случае вы сможете восстановить данные после любой ситуации, в которую можно попасть, имея дело с другими системами. Вообще говоря, располагать актуальными резервными копиями полезно при работе с любой СУБД. Транзакционная парадигма обладает своими преимуществами и недостатками. Многие пользователи и разработчики приложений зависят от того, насколько просто можно написать код, моделирующий систему, для которой прерывание работы возможно или необходимо. Однако, даже если вы новичок в парадигме атомарных операций, либо лучше знакомы с транзакционной моделью, согласитесь, что выигрыш в производительности в 3-5 раз, который дает применение нетранзакционных таблиц по сравнению с наиболее быстрыми и оптимизированными транзакционными, весьма существенен. В ситуациях, когда целостность данных чрезвычайно важна, сервер MySQL демонстрирует надежность уровня транзакционных систем даже при работе с нетранзакционны-ми таблицами. Если выполняется блокировка таблицы командой LOCK TABLE, все обновления приостанавливаются до тех пор, пока не выполнятся все проверки целостности. Если применяется блокировка READ LOCAL (в отличие от блокировки записи) для таблицы, допускающей параллельную вставку в конец, чтение разрешено, равно как и вставка другими клиентами. Вновь добавленные записи не будут видимы клиентом, установившим блокировку чтения, до тех пор, пока он не снимет блокировку. Применяя INSERT DELAYED, вы можете вставлять записи в локальную очередь до тех пор, пока не будет снята блокировка, не заставляя клиента ожидать завершения операции вставки. Слово ;атомарный; в том смысле, в каком мы его понимаем, не несет в себе ничего сверхъестественного. Оно означает только то, что вы можете быть уверены, что пока специфическое обновление идет, никакой другой пользователь не может взаимодействовать с ним, и поэтому не будет никакого автоматического отката (что может случиться с транзакционными таблицами, если вы не проявите достаточную осторожность). Сервер MySQL также гарантирует, что не будет никаких недействительных результатов чтения (dirty read). Ниже перечислены некоторые приемы работы с нетранзакционными таблицами.
- Циклы, которые нуждаются в транзакциях, обычно могут быть закодированы с помощью LOCK TABLES; необходимости иметь дело с курсорами для обновления записей на лету нет.
- Для того чтобы избежать использования ROLLBACK, можно прибегнуть к следую щей стратегии:
- Используйте LOCK TABLES для блокировки всех таблиц, к которым нужен доступ.
- Проверяйте все условия, которые должны быть истинными до начала обнов лений.
- Выполняйте обновления только если все в порядке.
- Используйте UNLOCK TABLES для разблокирования таблиц.
Обычно это значительно более быстрый метод, чем применение транзакций с возможными откатами, хотя и не всегда. Единственная ситуация, когда это решение не удачно, это если кто-то прервет поток приложения во время обновления. В таком случае все блокировки будут сняты, но часть обновлений останется невыполненной.
- Модифицировать столбцы в соответствии с их текущими значениями.
- Обновлять только те столбцы, которые изменились.
Например, когда выполняется обновление информации о заказчиках, мы обновляем только те данные, что изменились, либо данные, зависящие от измененных данных, сравнив их новые значения с исходными. Проверка измененных данных делается в конструкции WHERE оператора UPDATE. Если в результате запись не изменилась, потребуется выдать клиенту сообщение наподобие: ;Некоторые из изменяемых вами данных изменены другим пользователем;. Затем следует отобразить старую и новую версии записи о клиенте, чтобы пользователь решил, какую из них принять. Это обеспечивает механизм, подобный блокировке столбца, но на самом деле даже лучше, потому что мы обновляем только некоторые из столбцов, используя новые значения, зависящие от их текущих значений. Это означает, что типовые операторы UPDATE должны выглядеть, как показано ниже: UPDATE tablename SET pay_back=pay_back+125; UPDATE customer SET customer_date='current_date', address='new address1, phone='new phone', money_owed_to us=money owed to us-125 WHERE customer__id=id AND address='old address1 AND phone='old phone'; Такой подход весьма эффективен и работает, даже если другой клиент изменяет значения столбцов pay__back и money_owed_to__us.
Хранимые процедуры и триггеры
Хранимые процедуры реализованы в MySQL 5.O. Триггеры запланированы к реализации в версии 5.1. Триггер - это разновидность хранимой процедуры, которая вызывается при наступлении какого-то события. Например, можно написать процедуру, которая отрабатывает каждый раз, когда запись удаляется из транзакционной таблицы, и эта процедура автоматически удаляет соответствующего заказчика из таблицы заказчиков, когда все его финансовые транзакции удалены.Внешние ключи
В сервере MySQL 3.23.44 и последующих версий механизм хранения InnoDB поддерживает проверку ограничений на внешние ключи, включая CASCADING, ON DELETE и ON UPDATE. Для других механизмов хранения MySQL анализирует синтаксис FOREIGN KEY в операторе CREATE TABLE, но не использует и не хранит его. В будущих реализациях планируется сохранять эту информацию в файле спецификаций таблиц, чтобы она могла быть извлечена с помощью mysqldump и через ODBC. На более поздней стадии ограничения внешних ключей будут реализованы и для таблиц Myl SAM. Применение внешних ключей дает разработчикам баз данных некоторые преимущества:- Если предположить, что отношения между таблицами спроектированы правиль но, ограничения внешних ключей значительно затрудняют программистам воз можность внести в базу данных какую-либо противоречивую информацию.
- Централизованная проверка ограничений со стороны сервера делает излишней эту проверку со стороны приложения. Это исключает вероятность того, что некото рые приложения могут ее выполнять, а некоторые - нет.
- Применением каскадных обновлений и удалений может существенно упростить код приложений.
- Правильно спроектированные внешние ключи упрощают документирование от ношений между таблицами.
Однако следует помнить, что эти выгоды достигаются за счет большей нагрузки на сервер баз данных, которому приходится выполнять все проверки. Это приводит к некоторому снижению производительности, что для ряда приложений может оказаться настолько нежелательным, что лучше обойтись без этого вообще. (Некоторые важные коммерческие программы по этой причине имеют встроенную проверку логики внешних ключей на уровне приложения.) MySQL дает возможность разработчикам выбирать требуемый подход. Если вам не нужны внешние ключи, и вы хотите избежать лишней нагрузки, связанной с проверками ссылочной целостности, вы можете выбрать другой тип таблиц, такой как MyI SAM. Например, механизм хранения MyISAM обеспечивает очень высокую производительность для приложений, которые выполняют только операции INSERT и SELECT, поскольку вставки могут выполняться одновременно с выборками. Если вы предпочитаете обойтись без преимуществ проверки ссылочной целостности, вам следует иметь в виду следующее:
- При отсутствии проверки отношений внешних ключей со стороны сервера этим должно заниматься само приложение.
- Если приложению требуется только ссылочная целостность типа ON DELETE, сле дует отметить, что в MySQL 4.0 имеется возможность выполнять многотабличные операции DELETE для удаления записей из многих таблиц одним оператором.
- Обходной путь, позволяющий компенсировать отсутствие ON DELETE, заключается в том, чтобы добавить соответствующие дополнительные операторы DELETE в приложение для удаления записей из таблиц, имеющих внешние ключи. На прак тике часто это работает так же быстро, как и автоматические внешние ключи, но при этом значительно более переносимо.
Не забывайте, что применение внешних ключей иногда порождает проблемы:
- Поддержка внешних ключей применима ко многим случаям, когда нужно обеспе чить ссылочную целостность, но это не отменяет необходимости очень тщатель ного проектирования отношения ключей, чтобы избегать циклических зависимо стей или некорректных комбинаций каскадного удаления.
- Не столь уж необычна ситуация, когда администратор баз данных создает такую топологию отношений между таблицами, которая затрудняет восстановление от дельных таблиц из резервной копии. (MySQL смягчает сложность ситуаций по добного рода, позволяя временно отключать проверки внешних ключей на время загрузки данных в таблицы, зависящие от других таблиц. В MySQL 4.1.1 утилита mysqldump генерирует файлы дампа, которые это делают автоматически при за грузке.)
Следует помнить, что внешние ключи в SQL применяются для проверки и поддержания ссылочной целостности, но не для объединения таблиц. Если вам нужен результат запроса к множеству таблиц от одного оператора SELECT, вы делаете это за счет описания объединения между ними: SELECT * FROM tl, t2 WHERE tl.id = t2.id; Синтаксис FOREIGN KEY без ON DELETE... часто применяется в ODBC-приложениях для автоматической генерации конструкций WHERE.