Задавайте вопросы, мы ответим
Вы не зашли.
Привет! Нужна ваша помощь в таком нерешенном вопросе:
У меня есть такая вот таблица:
id (auto_increment) | name | url |
------------------------------------------
1 | Ян | http://ya.ru/1|
------------------------------------------
2 | Rj | http://ya.ru/2 |
------------------------------------------
3 | jj | http://ya.ru/3 |
-------------------------------------------
Поле id имеет свойство auto_increment, а url зависит от id.
Возможно ли одним инсертом вставить в таблицу запись, чтобы url изменялся под номер id.
Сейчас я делаю так: вставляю запись (name=Jj, url=http://ya.ru/) => потом по имени получаю id => потом по id делаю апдейт на запись с уже нормальным url (http://ya.ru/3).
Как мне оптимизировать эти запросы? Думаю, что это возможно сделать через один запрос...
Неактивен
Вижу два простых способа:
1. Временно игнорировать то, что id автоинкрементальный, и вставить с нужными
значениями.
2. Вставить нужное количество строк сразу, а потом обновить URL в соответствии
с id.
Также стоит рассмотреть вариант «не сохранять URL вообще, т.к. он однозначно
определяется из id».
Неактивен
paulus, спасибо за ответ. Урла в базе может иногда меняться, так что не могу отказаться.
Код, полностью удовлетворяющий мой запрос, дал http://twitter.com/alekseyrybalkin.
Вот код:
insert into tst(name, url) select 'nm', concat('ya.ru/', Auto_increment) from information_schema.tables where table_name='tst';
Неактивен
Ну что ж, два Алексею Рыбалкину за незнание жизни. Подумайте, что будет
при большой нагрузке (например, два запроса пришли одновременно).
И, кстати, INFORMATION_SCHEMA будет сильно тормозить на этих запросах,
тоже, возможно, следует учесть.
Неактивен
paulus, если вы Алексею поставили два, то мне можете ставить 0. В мускуль полез без основной базы знаний.
Поэтому то я не могу просчитать что будет при нагрузке.
Я считал так: если решить проблему в два или более запроса, то во время выполнения одного из них, другой скрипт сможет что-то нарушить. Из-за этого искал решение в один запрос, считая что пока выполняется один запрос, второй не будет обрабатываться.
P.S. базу делал не я. База от готового движка. Этой мой метод "интеграции" с этим двигом.
Неактивен
При работе INFORMATION_SCHEMA — не документировано, как оно относится к блокировкам
на таблице. Собственно, пути всего два — или блокирует, или нет.
Если оно блокирует таблицу, то в случае с InnoDB Вы получите производительность MyISAM
на вставке из-за блокировок. Если оно не блокирует таблицу, то в случае с InnoDB Вы
получите, что два потока одновременно смогут прочитать одно и то же значение auto_increment
и, соответственно, у Вас будут вставлены две одинаковые строки.
Я бы рекомендовал всё же придерживаться разумного способа вставки вида «вставил и
переименовал»:
INSERT INTO tablename (name) VALUES ('name', '');
UPDATE tablename SET url = CONCAT('ya.ru/', LAST_INSERT_ID()) WHERE id = LAST_INSERT_ID();
Или даже триггером AFTER_INSERT, который будет делать то же самое.
Неактивен
В триггере не получится, к сожалению (сталкивался уже с такой проблемой).
Неактивен