The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Раздел полезных советов: Использование одного автоинкремента..."
Вариант для распечатки  
Пред. тема | След. тема 
Форум Разговоры, обсуждение новостей
Изначальное сообщение [ Отслеживать ]

"Раздел полезных советов: Использование одного автоинкремента..."  +/
Сообщение от auto_tips (??) on 14-Окт-10, 20:54 
Решение задачи сохранения единого для нескольких таблиц автоинкрементального счетчика.

Иными словами, как реализовать в MySQL аналог SEQUENCE в PostgreSQL, работающих примерно так:

   CREATE SEQUENCE next_contraсt start 1 increment 1 maxvalue 2147483647 minvalue 1 cache 1;
   CREATE TABLE contract (
    "id"  integer NOT NULL DEFAULT nextval('next_contraсt') PRIMARY KEY,
   ...
   );


++ Метод 1.

Создаем таблицу:

   CREATE TABLE option1 (id int not null primary key auto_increment) engine=innodb;

При необходимости получения очередного номера счетчика выполняем (фиктивная вставка данных, необходимая для срабатывания auto_increment):

   INSERT INTO option1 VALUES (NULL);

Получаем текущее значение идентификатора через API-вызов $connection->insert_id(), например, в PHP:

   $last_id = mysql_insert_id();


++ Метод 2:

Создаем таблицу из одного столбца:

   CREATE TABLE option2 (id int not null primary key) engine=innodb;

Инициализируем первое значение:

   INSERT INTO option2 VALUES (1); # начинаем последовательность с 1

Для получения очередного значения счетчика выполняем:

   UPDATE option2 SET id=@id:=id+1;
   SELECT @id;

По производительности первый метод заметно быстрее второго:

   Метод 1 с использованием транзакций: 19 сек на выполнение 10000 итераций
   Метод 1 без использования транзакций: 13 сек на выполнение 10000 итераций
   Метод 2 с использованием транзакций: 27 сек на выполнение 10000 итераций
   Метод 2 без использования транзакций: 22 сек на выполнение 10000 итераций

++ Метод 3.

Использовать функцию LAST_INSERT_ID(), которая возвращает последний сгенерированный через AUTO_INCREMENT на сервере идентификатор.

   UPDATE option3 SET id = LAST_INSERT_ID(id+1);

++ Метод 4.

Использование хранимых процедур и триггеров.

Создаем таблицу sequences для хранения счетчика и функцию  nextval('seqname') для возвращения следующего номера:

   CREATE TABLE IF NOT EXISTS sequences
   (name CHAR(20) PRIMARY KEY,
   val INT UNSIGNED);

   DROP FUNCTION IF EXISTS nextval;

   DELIMITER //

   CREATE FUNCTION nextval (seqname CHAR(20))
   RETURNS INT UNSIGNED
   BEGIN
   INSERT INTO sequences VALUES (seqname,LAST_INSERT_ID(1))
   ON DUPLICATE KEY UPDATE val=LAST_INSERT_ID(val+1);
   RETURN LAST_INSERT_ID();
   END
   //

   DELIMITER ;

Создаем тестовую таблицу data для последующего подключения генератора последовательности:

   CREATE TABLE IF NOT EXISTS data
   (id int UNSIGNED NOT NULL PRIMARY KEY DEFAULT 0,
   info VARCHAR(50));

Создаем триггер для автоматизации инкрементирования счетчика в таблице data:

   DROP TRIGGER nextval;
   CREATE TRIGGER nextval BEFORE INSERT ON data
   FOR EACH ROW SET new.id=IF(new.id=0,nextval('data'),new.id);
   TRUNCATE TABLE data;

Экспериментируем:

   INSERT INTO data (info) VALUES ('bla');
   INSERT INTO data (info) VALUES ('foo'),('bar');
   SELECT * FROM data;

   +----+------+
   | id | info |
   +----+------+
   |  1 | bla  |
   |  2 | foo  |
   |  3 | bar  |
   +----+------+

URL: http://www.mysqlperformanceblog.com/2010/10/04/sharing-an-au.../ http://openquery.com/blog/implementing-sequences-using-a-sto...
Обсуждается: http://www.opennet.me/tips/info/2460.shtml

Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Alexander (??) on 14-Окт-10, 20:54 
что это за детский сад? помоему любой человек понимающий SQL напишет это все с закрытими глазами.. ито как... дважды два, как соль соленая, я даже не знаю как еще выразить свое удивление к данной статьте
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

2. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от ss25 email on 15-Окт-10, 10:11 
Метод 0.
Использовать PostgreSQL и не иметь себе и людям мозг.
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

3. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от тот_самый on 15-Окт-10, 18:41 
обьясните пожалуйста зачем это вообще?
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

5. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от dry (ok) on 16-Окт-10, 01:14 
чтобы иметь unique id в пределах нескольких таблиц или даже базы/схемы. на самом деле очень немного реальных задач, где это необходимо и в корне этой необходимости как правило лежит дурное проектирование.
тем не менее, в качестве гипотетической задачи - такой хороший камень в огород mysql,
описанные костыли реально вызывают умиление.
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

6. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Админ Веня (ok) on 16-Окт-10, 12:33 
+1
Не дурное проектирование, а простое непонимание нормализации баз данных выше 2-3 уровня(коль уже возникла такая потребность).
Но вопрос еще: почему, если mysql создавался как более гибкая альтернатива для mSQL, сиквенсы тупо выкинули? Но это вопрос риторики.
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

10. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от zazik (ok) on 22-Окт-10, 11:49 
> обьясните пожалуйста зачем это вообще?

Чтобы написать совет на опеннет, нет?

Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

4. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Аноним (??) on 15-Окт-10, 19:49 
2Alexander
ну не скажи. я вот 4 вариант с ходу не написал бы. но и sql я знаю так себе
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

8. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Александр (??) on 17-Окт-10, 17:39 
ну как бе, зная pl sql, у тебя бы этот вопрос вообще не встал, тут просто вариант что из пхп версии инкрементирование перенесли в sql.. разница не велика, разве что в проихводительности
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

7. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Vanzhiganov email(??) on 16-Окт-10, 12:37 
Alexander, вы наверняка не видели костыли пострашнее. По мне так ясно сформулированная логика.
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

9. "Использование одного автоинкрементального счетчика для неско..."  +/
Сообщение от Александр (??) on 17-Окт-10, 19:46 
к своему сожалению, за имением опыта, я видел костыли и по-страшнее, но речь та не об этом )
Высказать мнение | Ответить | Правка | ^ | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру