С нашей точки зрения проверка контекста столбцов должна выполняться в приложении, а не на сервере базы данных.
Если вы хотите заставить
оператор INSERT генерировать ошибку, когда не указаны явно значения для
всех столбцов таблицы, требующих не-NULL значений, можете
сконфигурировать MySQL с использованием опции DONT_USE_DEFAULT_USE.
Это возможно, только при компиляции MySQL из исходных текстов.
- Вы можете воспользоваться ключевым словом DEFAULT, чтобы явно присвоить столбцу значение по умолчанию (новая возможность в MySQL 4.0.3). Это упрощает написание операторов INSERT, которые присваивают значения всем столбцам, кроме некоторых, поскольку позволяет избежать написания неполных списков VALUES, которые не включают всех столбцов таблицы. Иначе вам пришлось бы писать список имен столбцов, соответствующих каждому элементу в списке VALUES.
- Если и список столбцов, и список значений VALUES пусты, оператор INSERT создает строку, в которой все столбцы принимают значения по умолчанию.
mysql> INSERT INTO имятаблицы () VALUES();
- Выражение выражение может ссылаться на любой столбец,
который упомянут ранее в списке значений. Например, вы можете делать это
потому, что значение для col2 ссылается на coll, значение которого уже
установлено:
- Если вы указываете ключевое слово DELAYED, сервер помещает строку или строки, которые подлежат вставке, в буфер, и клиент, приславший этот оператор, может продолжать свою работу. Если таблица занята, сервер удерживает строки. Когда таблица освободится, он начнет их вставку, проверяя периодически, нет ли новых запросов на чтение этой таблицы. Если они есть, обслуживание очереди отложенных строк для вставки приостанавливается до тех пор, пока таблица не освободится вновь. См. раздел Синтаксис INSERT DELAYED
- Если указано ключевое слово LOW_PRIORITY, выполнение вставки откладывается до тех пор, пока все другие клиенты не завершат чтение таблицы. Это касается также клиентов, которые начали чтение в то время, когда существующие клиенты уже читали, и тех, что обратились к таблице во время ожидания оператора INSERT LOW_PRIORITY. Таким образом, есть вероятность, что клиент, приславший запрос insert LOW_PRIORITY, будет ожидать весьма длительное время (или даже бесконечно долго) в среде с высокой нагрузкой по чтению. (Это отличается от оператора INSERT DELAYED, который позволяет клиенту продолжать работу.) См. раздел Синтаксис INSERT DELAYED Имейте в виду, что LOW_PRIORITY обычно не должно использоваться с таблицами MyISAM, поскольку это препятствует параллельным вставкам.
- Если указано ключевое слово IGNORE в операторе INSERT со многими строками, любая строка, в которой дублируется значение столбцов уникального индекса или первичного ключа, игнорируется и не вставляется. Если вы не указываете IGNORE, операция вставки прерывается при обнаружении дублированных строк. Количество строк, вставленных в таблицу, можно определить вызовом функции С API mysqlinfo ().
- При попытке вставить NULL в столбец, объявленный как NOT NULL. Для многострочных операторов INSERT или INSERT.. .SELECT таким столбцам присваиваются значения по умолчанию, в соответствии с их типом. Это 0 для числовых типов, пустая строка ('') для строковых типов и "нулевые" значения для типов времени и даты.
- При присвоении числовому столбцу значения, лежащего вне пределов допустимого диапазона. Такие значения смещаются к ближайшим границам в рамках до пустимого диапазона.
- При присвоении значения вроде '10.34 а' числовым столбцам. Завершающие нецифровые символы отбрасываются, а оставшаяся цифровая часть вставляется.
- При вставке символьных значений в строковые столбцы (CHAR, VARCHAR, TEXT или BLOB), которые превышают максимальную длину столбца. Такие значения усекаются до максимальной длины столбца.
- При вставке в столбец даты или времени значения, которое недопустимо для данного типа столбца. В этом случае в столбец записывается соответствующее этому типу нулевое значение.
- До версии MySQL 4.0.1 INSERT.. .SELECT неявно работал в режиме IGNORE. Начиная с MySQL 4.0.1, следует явно указывать IGNORE, чтобы игнорировать строки, которые нарушают условия уникальности ключей.
- Не ИСПОЛЬЗОВать DELAYED С INSERT. . . SELECT.
- До MySQL 4.0.14 целевая таблица оператора INSERT не могла встречаться в конструкции FROM части SELECT. Это ограничение снято в версии 4.0.14.
- Столбцы AUTO_INCREMENT работают как обычно.
- INSERT DELAYED работает только с таблицами MyISAM и ISAM. Для таблиц MyISAM если нет свободных блоков в середине файла данных, то поддерживаются параллельные операторы INSERT и SELECT. В таких условиях вам очень редко понадобится использовать INSERT DELAYED с таблицами MyISAM.
- INSERT DELAYED должен применяться только с операторами INSERT, в которых указаны списки значений. Это требование введено в MySQL 4.0.18. Сервер игнорирует DELAYED ДЛЯ INSERT DELAYED...SELECT.
- Сервер игнорирует DELAYED В операторах INSERT DELAYED... ON DUPLICATE UPDATES.
- Поскольку оператор возвращает управление немедленно, до того как строки фактически будут вставлены, вы не можете использовать LAST_INSERT_ID() для получения последнего значения AUTO_INCREMENT, которое может быть сгенерировано оператором.
- Когда поток выполняет DELAYED-оператор на конкретной таблице, создается поток обработчика для выполнения всех этих отложенных операторов для таблицы, если только она еще не существовала на этот момент.
- Поток проверяет, получил ли обработчик DELAYED-блокировку. Если нет, он дает команду потоку обработчика сделать это. DELAYED-блокировка может быть получена, даже если другие потоки имеют на этой таблице блокировку чтения или записи. Однако обработчик будет ожидать блокировок ALTER TABLE или FLUSH TABLES, чтобы гарантировать, что структура таблицы синхронизирована.
- Поток выполняет оператор INSERT, но вместо записи строки в таблицу помещает ее копию в очередь в памяти, которая управляется потоком обработчика. Любые синтаксические ошибки потоком отмечаются и сообщаются клиентской программе.
- Клиент не может получить от сервера количество дублированных строк или значение AUTO_INCREMENT результирующей строки, потому что insert возвращает управление прежде, чем вставка строки будет выполнена. (Если вы используете
- Бинарный журнал обновляется потоком обработчика, когда строка вставляется в таблицу. В случае многострочной вставки бинарный журнал обновляется, когда вставляется первая строка.
- После того, как delayed_insert_limit строк вставлено, обработчик проверяет, нет ли ожидающих операторов SELECT. Если есть, он позволяет им выполниться, прежде чем продолжит свою работу.
- Когда обработчик больше не имеет строк в очереди, блокировка с таблицы снимается. Если больше никаких новых операторов INSERT DELAYED не получено в течение delayed_insert_timeout секунд, то поток обработчика прерывается.
- Если в конкретной очереди накапливается более delayed_queue_size строк, то поток, который запрашивает выполнение очередного оператора INSERT delayed, ожидает, пока не освободится место в очереди. Это делается для того, чтобы гарантировать, что сервер raysqld не захватит всю свободную память под эту очередь.
- Следующие переменные состояния предоставляют информацию об операторах
INSERT DELAYED:
Однако следующий оператор выполнить невозможно, так как coll ссылается на со12, значение которого присваивается после coll:
mysql> INSERT INTO имя_таблицы (coll,col2) VALUES(col2*2,15); Оператор INSERT поддерживает следующие модификаторы:
Если вы используете конструкцию ON DUPLICATE KEY UPDATE (новая в
MySQL 4.1.0), и вставляется строка с дублированным значением ключа
уникального индекса или первичного ключа, то выполняется операция
update старой строки. Например, если столбец а объявлен как UNIQUE и
уже содержит значение 1, то два следующих оператора дадут один и тот же
эффект:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=c+l;
mysql> UPDATE table SET c=c+l WHERE a=l;
На заметку!
Если столбец b тоже уникальный, то INSERT будет эквивалентен такому оператору UPDATE: mysql> UPDATE table SET c=c+l WHERE a=l OR b=2 LIMIT 1;
Если условию а=1 OR b=2 соответствуют несколько строк, то обновляется только одна строка.
Вообще вам следует избегать применения конструкции ON DUPLICATE KEY с
таблицами, у которых несколько уникальных ключей.
Начиная с MySQL 4.1.1, в конструкции UPDATE вы можете использовать
функцию VALUES {имя_столбца), чтобы сослаться на значения столбцов из
части INSERT оператора INSERT.. .UPDATE. Другими словами, VALUES
{имя_столбца) в конструкции UPDATE ссылается на значение имя_ столбца,
которое должно быть вставлено, если не обнаружится никаких конфликтов
дублирования ключей. Эта функция особенно удобна при многострочных
вставках. Функция VALUES имеет смысл только в операторе INSERT..
.UPDATE, и возвращает NULL во всех остальных случаях.
Ниже представлен пример:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
Этот оператор идентичен следующим двум:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
-> ON DUPLICATE KEY UPDATE c=3; mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)
-> ON DUPLICATE KEY UPDATE c=9;
Когда вы используете ON DUPLICATE KEY UPDATE, опция DELAYED игнорируется.
Вы можете получить значение, использованное для присвоения столбцу с
атрибутом AUTO_INCREMENT, обратившись к функции LAST_INSERT_ID (). В
программном интерфейсе С API для этого предусмотрена
функция mysql_insert_id (). Однако, помните, что эти две функции ведут
себя не во всех случаях одинаково. Поведение операторов INSERT со
столбцами AUTO_INCREMENT обсуждается далее в разделе Информационные
функции.
Если вы применяете оператор INSERT.. .VALUES с множественными
списками значений или INSERT.. .SELECT, этот оператор возвращает
информационную строку в следующем формате:
Records: 100 Duplicates: 0 Warnings: 0
Records (записи) обозначает количество строк, обработанных
оператором. (Это не обязательно будет количество действительно
вставленных строк. Duplicates может быть ненулевым.) Duplicates
(дубликаты) означает количество строк, которые не могут быть вставлены
из-за того, что они дублируют какие-то уникальные значения индексов.
Warnings (предупреждения) означает количество попыток вставки значений
столбцов, которые оказались по каким-то причинам проблематичными.
Предупреждения могут возникать при следующих условиях:
Если строчное значение не имеет ведущих цифровых символов, то столбцу присваивается 0.
Если вы используете программный интерфейс С API, информационная строка может быть получена с помощью функции mysql_inf o ().
Синтаксис INSERT...SELECT
INSERT [LOW_PRIORITY] [IGNORE] [INTO] имя_таблицы [(списокстолбцов)}
SELECT ...
С помощью INSERT ... SELECT можно быстро вставить множество строк в одну таблицу из другой или других. Например:
INSERT INTO tbl temp2 (fld__ id) SELECT tbl_templ.fld_order_id
FROM tbl_templ WHERE tbl_templ. fld_order__id > 100;
В отношении оператора INSERT... SELECT соблюдаются следующие условия:
а Чтобы гарантировать, что бинарный журнал сможет быть использован
для пересоздания оригинальных таблиц, MySQL не разрешает параллельные
вставки во время выполнения INSERT.. .SELECT.
Вы можете использовать REPLACE вместо INSERT, чтобы перезаписывать
старые строки. REPLACE - это дополнение к INSERT IGNORE при обработке
новых строк, которые содержат значения уникальных ключей, дублирующих
старые строки. Новые строки используются для замены старых вместо
того, чтобы просто отвергаться.
Синтаксис INSERT DELAYED
INSERT DELAYED ...
Опция DELAYED оператора INSERT - это расширение MySQL стандарта SQL, которое очень удобно, если у вас есть клиенты, которые не могут ждать завершения выполнения INSERT. Это общая проблема, когда MySQL используется для регистрации в журнале с параллельным периодическим выполнением операторов SELECT и UPDATE, которые работают подолгу. DELAYED было представлено в MySQL 3.22.15.
Когда клиент применяет INSERT DELAYED, он получает от сервера
подтверждение сразу, а вставляемая строка становится в очередь с тем,
чтобы реально добавиться в таблицу, когда она не будет занята другими
потоками.
Другая существенная выгода использования INSERT DELAYED состоит в
том, что вставки от многих клиентов связываются вместе и записываются в
один блок. Это намного быстрее, чем выполнять множество отдельных
вставок.
Существуют некоторые ограничения при использовании DELAYED:
Строки DELAYED невидимы для SELECT до тех пор, пока они действительно не будут вставлены в таблицу.
Следует отметить, что поставленные в очередь записи хранятся только
в памяти до того, как будут вставлены в таблицу. Это означает, что
если вы прервете работу mysqld принудительно (например, командой kill
-9), либо он завершит работу аварийно, то все записи, поставленные в
очередь, будут утеряны!
Ниже приведено детальное описание того, что происходит, если
применять опцию DELAYED к операторам INSERT или replace. В этом описании
под "потоком" имеется в виду поток сервера, принимающий оператор
INSERT DELAYED, а "обработчик" (handler) -это поток, который
обрабатывает все операторы insert DELAYED для отдельной таблицы.
м Поток обработчика показывается в списке процессов MySQL со
значением столбца Command, равным delayed_insert. Он будет прерван,
если выполнить оператор FLUSH TABLES или прервать его посредством KILL идентификатор_потока. Однако
перед выходом поток сначала запишет все строки, находящиеся в очереди,
в таблицу. В это время он не будет принимать никаких операторов
INSERT от других потоков. Если выдать оператор INSERT DELAYED после
этого, будет создан новый поток обработчика.
Следует отметить, что это означает, что операторы INSERT DELAYED
имеют более высокий приоритет, чем нормальные операторы INSERT, если
существует работающий поток обработчика INSERT DELAYED. Все остальные
операторы обновления данных должны будут ожидать до тех пор, пока
очередь INSERT DELAYED не очистится, либо кто-нибудь не прервет поток
обработчика (с помощью kill идентификатор_потока), либо же будет выполнен оператор FLUSH TABLES.
Вы можете просмотреть эти переменные, выполнив оператор SHOW STATUS либо команду mysqladmin extend-status.
Оператор INSERT delayed медленнее, чем обычный insert, если таблица не используется. Поддерживать отдельный поток для каждой таблицы, для которой существуют отложенные операторы вставки - это создает дополнительную нагрузку на сервер. Это значит, что вы должны применять INSERT DELAYED только в случаях, когда вы действительно уверены, что это необходимо!