![]() |
|
Модераторы: skyboy |
![]()
|
|
| Trotil |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 31.7.2005 Репутация: нет Всего: нет |
Задача: получить значение автоинкремента в таблице ДО вставки записи (так что mysql_insert_id не подходит)
Цель: вставить в таблицу данные, зависящие от этого id. Сейчас мне приходится создавать новую запись, а затем ее корректировать одно поле, используя этот полученный id... Нехорошо. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
в `information_schema`.`tables`.`auto_increment` хранится значения(последнее использованное, видимо) автоинкремента для определенных таблиц определенных схем.
|
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
skyboy, это неправильный подход, разумеется.
То, как делается сейчас - правильно и хорошо. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
||||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
Да очевидное же обоснование.
Пока узнавали id - прошла другая вставка - узнали неверный. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
Feldmarschall, ну, да.
но в общем случае - и вставка с последующим чтением записи - не панацея. если есть совокупность полей с явно уникальным сочетанием значений(естественный ключ), то ещё куда ни шло. Но, раз используется искусственный ключ(автоинкремент), никто не может гарантировать, что после вставки записи до чтения соотвествующего значения автоинкремента не произойдет вставка записи с такими же значениями полей(всеми, кроме автоинкрементного поля). и при последующем использовании считанного автоинкрементного значения на одну из дублирующихся(по крайней мере, с точки зрения содержания; автоинкрементное поле и генерируемые на стороне сервера(триггеры, timestamp с on update) значения полей могут отличаться) записей будет две ссылки/связи из остальных таблиц, а на другую - ни одной. вероятность сего(вставки записей с одинаковыми значениями полей до чтения значения автоинкрементного поля), понятное дело, ниже, чем вероятность двух вставок подряд вообще. но если необходима абсолютная уверенность в корректности считанного значения автоинкрементного поля, то либо блокировать таблицы(грубое решение "в лоб"), либо при вставке в таблицу вставлять туда же некое предварительно запомненное достаточно длинное (псевдо)случайное число/строку. В последнем случае, даже две абсолютно одинаковые с точки зрения модели записи(например, два Иванова Петра Сидоровича с одинаковой датой рождения) будут отличаться на значение поля со случайной величиной. P.S. Ну, и вариант для извращенцев: отказаться от автоинкремента в пользу набора самостоятельно генерируемых на стороне клиента набора (псевдо)случайных чисел для использования в качестве ключа |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
||||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
зачем тогда выбирать запись из таблицы? если на момент вызова значение, возвращаемое last_insert_id, корректно(в смысле, этим же клиентом в пределах этого же подключения больше не производились вставки строк в таблицы с автоинкрементными полями) - то почему бы просто не вызывать last_insert_id()? я же говорил о схеме, когда вставили запись, потом считали запись(надеясь, что она - именно та, которую мы записали) и из неё вынули значение автоинкрементного поля. Добавлено через 2 минуты и 15 секунд кстати, MySQL не гарантирует, что
mysql_insert_id() производит возврат последнего вставленного в автоинкрементное поле значения с контролем того, какой клиент какое значение записывал, а какой - вызывает функцию для получения его. потому если содеинение переподключается - работать этот механизм тоже не будет. |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
А я не знаю - зачем выбирать? кто говорит о выбирании последней записи из таблицы? Автор темы говорит об апдейте, а не о выборке.
если последние два абзаца написаны для того, чтобы объяснить мне, что mysql_insert_id(), вызванная через неделю после вставки, не вернет нужное значение, то я, как бы, в курсе, спасибо. В остальном смысл поста мне неясен. Вроде бы, у автора конкетная задача. Которая корректно решается с помощью mysql_insert_id() и апдейта. Что он, я полагаю, и делает. Я сказал, что это наиоболее правильный способ. Что тут ещё обсуждать? |
|||
|
||||
| tot |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 25.12.2007 Репутация: нет Всего: нет |
А вот я mysql_insert_id() не нахожу корректных. mysql_insert_id() корректен в пределах одного подключения, а если на одном подключении несколько пользователей(например Web-приложение), тогда между вставкой в запись и вызовом mysql_insert_id() может произойти еще одна вставка и результат вызова mysql_insert_id() будет уже не тем что ожидается. |
|||
|
||||
| vi_k |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 29.12.2007 Репутация: нет Всего: нет |
SHOW TABLE STATUS ... Это ответ на заданный вопрос. Но также считаю, что расчитывать, что ваша запись будет при вставке иметь именно этот id нельзя. Только вставка записи и последующее получение LAST_INSERT_ID может что-либо гарантировать.
В задачах такого плана параллельные работы на одном соединении должны быть запрещены. Хотя не представляю как вообще возможна параллельное использование соединения. Если вы сейчас говорите о mysql_pconnect() из php, то эта функция действительно берёт уже готовое ранее использовавшееся подключение, но, имхо конечно, php никому его не передаёт, пока скрипт не выполнится, поэтому параллельное использование этого соединения не допускается и можно безбоязненно использовать mysql_insert_id(). Это сообщение отредактировал(а) vi_k - 30.12.2007, 11:26 |
||||
|
|||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |