Как PDO знает последний вставленный идентификатор в MySQL?
-
28-09-2019 - |
Вопрос
РЕДАКТИРОВАТЬ: Этот вопрос изначально был: Как доктрина знает последний вставленный ID в MySQL? и был связан с Доктрина ORM Mapper. После некоторого копания я узнал, что этот вопрос не связан с Доктрина но Pdo_mysql., MySQL C API И, наконец, - для клиент-сервера MySQL. Я решил изменить название, поэтому, может быть, кто-то найдет ответ на свой вопрос.
Для тех, кто не использует доктрину: мне было любопытно, почему ниже:
mysql_query("INSERT INTO category (name) VALUES('cat')");
echo mysql_insert_id();
или похожие:
$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();
приведет к одной позиции (без отдельных SELECT LAST_INSERT_ID()
) в журнале:
1701 Query INSERT INTO category (name) VALUES ('cat')
Оригинальный вопрос:
У меня есть 2 стола:
category(id,name)
product(id, name, categoryId)
Я создал новый объект категории и объект продукта. Я присваивал объект категории к объекту продукта. Я не установил никаких идентификаторов:
$product = new Product();
$product->name = 'asdf';
$category = new Category();
$category->name = 'cat';
$product->Category = $category;
После этого я промыл соединение и проверяйте журналы MySQL:
1684 Query START TRANSACTION
1684 Query INSERT INTO category (name) VALUES ('cat')
1684 Query INSERT INTO product (name, categoryid) VALUES ('asdf', '312')
1684 Query COMMIT
Как учение знала, что недавно созданная идентификатор категории составляет 312? В журналах ничего нет.
Решение
Я сделал некоторые исследования и просматриваю какой-то исходный код, поэтому мой ответ может быть немного неправильным и не точным.
Прежде всего, это на самом деле не связано с Доктрина. Доктрина использует Pdo_mysql.. Отказ Но внутри Pdo_mysql. использует то же самое, что mysql_insert_id
Функция - родной MySQL C API функция - mysql_insert_id
.
Причина, почему нет отделения SELECT LAST_INSERT_ID()
заключается в том, что после того, как утверждение выполняется (в моем примере INSERT
), сервер отвечает с данными, а некоторые другие включены в ОК Packet), включая insert_id
. Отказ Так когда мы огонь mysql_insert_id()
Мы не подключаемся к серверу, чтобы получить insert_id
- Библиотека MySQL не должна делать это - у нее уже есть эта величина, сохраненная от последнего выполнения запроса (по крайней мере, я думаю, что после анализа файла libmysql.c
)
ОК Packet описано здесь: Пакеты общих откликов MySQL - ОК Packet
Другие советы
Вероятно, позвонив http://dev.mysql.com/doc/refman/5.0/en/getting-unique-iD.html.
last_insert_id
Работает только для AUTO_INCREMENT
столбцы. Это не будет работать, если вы введете значение вручную в AUTO_INCREMENT
столбец.
Доктрина будет работать, потому что это так же, как присвоить NULL
к нему (хотя вы никогда не специально пишу это). Это вызывает автоматическое увеличение и обеспечивает значение для last_insert_id()
.
Я включил JPG здесь, чтобы вы могли его увидеть. Надеюсь, поможет!