Я гарантированно получить последовательные идентификаторы с одним оператором вставки в MySQL? - PullRequest
0 голосов
/ 05 марта 2019

Я вставляю 1000 строк одним запросом INSERT.Запрос возвращает идентификатор первой вставленной строки.Можно ли предположить, что все остальные строки имеют идентификатор firstId + i, учитывая, что, возможно, одновременно выполняется несколько запросов вставки?

1 Ответ

0 голосов
/ 05 марта 2019

Может быть. Обычно да, но есть ряд случаев, когда это ненадежно.

Драйвер MySQL JDBC предполагает, что пакет сгенерированных значений автоинкремента является последовательным при выполнении пакетной вставки.

См. Код в java.com.mysql.cj.jdbc.StatementImpl.getGeneratedKeysInternal ()

Упрощая логику, соответствующие биты:

long beginAt = getLastInsertID();
for (int i = 0; i < numKeys; i++) {
    row[0] = StringUtils.getBytes(Long.toString(beginAt));
    beginAt += this.connection.getAutoIncrementIncrement();
}

Таким образом, он начинается с идентификатора первой вставленной строки и предполагает, что последующие сгенерированные значения идентификатора - это просто следующие numKeys значения, увеличивающиеся на значение конфигурации auto_increment_increment (по умолчанию 1).

Может ли это пойти не так? Да, в нескольких случаях. Например:

  • Если вы делаете многорядную INSERT, указав NULL для некоторых строк и действительное целочисленное значение для других строк в том же операторе INSERT, предположение драйвера JDBC о том, что все значения будут последовательными значения после значения, возвращенного LAST_INSERT_ID(), неверны.

  • Если вы сделаете многорядную INSERT...ON DUPLICATE KEY UPDATE или REPLACE, где некоторые строки существуют, а другие нет, он будет неверно сообщать набор последовательно сгенерированных ключей.

  • Если вы установите innodb_autoinc_lock_mode = 2 («чередующийся» режим блокировки), то многострочные операторы INSERT, которые выполняются одновременно, могут не быть последовательными. Каждый из них будет генерировать значения идентификаторов всякий раз, когда это возможно, и это будет непредсказуемо чередоваться, как перетасовывание двух половинок колоды карт. См https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...