Пакет · cdo

Вставка записей

Как вставить одну строку, эффективно вставить тысячи и прочитать id, который сгенерировала база — плюс два правила, определяющие, что именно записывается.

Вставка одной строки

insert() принимает имя таблицы и массив (или объект) пар «колонка → значение». Он возвращает сгенерированный первичный ключ.

php
$id = $cdo->insert('users', [
  'name'  => 'Alice',
  'email' => 'alice@example.com',
]);

Возвращаемый id — это значение первого ключа переданной сущности, полученное через RETURNING на PostgreSQL/MariaDB или lastInsertId() на MySQL. См. Определение драйвера — почему существуют оба пути.

Первичный ключ — это первый ключ

insert() выводит возвращаемую колонку из array_key_first() вашей сущности — до отбрасывания NULL. Ставьте колонку первичного ключа первой (даже как 'id' => null), чтобы вернулось правильное значение. Колонка авто-id со значением null/отсутствующая всё равно вернёт сгенерированный id через драйвер.

Два правила о том, что записывается

  1. Значения null выбрасываются. Любая колонка со значением null удаляется из INSERT, поэтому она принимает значение по умолчанию из базы или автогенерируемое.
  2. Объекты «разворачиваются». Сущность-объект преобразуется через get_object_vars(), поэтому её публичные свойства становятся колонками.
php
$user = new stdClass();
$user->name  = 'Bob';
$user->email = 'bob@example.com';
$user->note  = null;   // выброшено — колонка сохраняет значение по умолчанию

$id = $cdo->insert('users', $user);

Пакетная вставка

insertGroup() записывает много строк с гораздо меньшим числом обращений к базе. Он автоматически разбивает вход на чанки и выдаёт один многострочный INSERT на каждый чанк.

php
$users = [
  ['name' => 'Alice', 'email' => 'alice@example.com'],
  ['name' => 'Bob',   'email' => 'bob@example.com'],
  // ... тысячи ещё
];

$cdo->insertGroup('users', $users);              // размер чанка по умолчанию 1000
$cdo->insertGroup('users', $users, chunkSize: 500);

insertGroup() ничего не возвращает — это массовая запись, а не получение id. Пустой входной массив — это no-op (ничего не делает).

Держите форму строк одинаковой внутри чанка

Каждый чанк строит список колонок из содержащихся в нём строк. Давайте каждой строке одни и те же ключи, чтобы порождённый многострочный INSERT совпадал. Значения null в отдельных строках по-прежнему выбрасываются поштучно. Подробности в Пакетах и чанках.

Выбор размера чанка

chunkSize ограничивает, сколько строк попадает в один запрос, что удерживает вас под лимитами базы на число связанных параметров и размер пакета. Меньшие чанки используют меньше памяти на запрос; большие означают меньше обращений к базе. Значение по умолчанию 1000 — безопасная отправная точка; уменьшайте его, если строки очень широкие (много колонок).

Обработка дубликатов ключей

Обычный insert в строку, нарушающую уникальное ограничение, бросает CDOException. Если вам нужно вставить-или-обновить (или вставить-или-игнорировать), используйте upsert / upsertGroup.

Связанное