Колонка автоинкремента MySql увеличивается на 10 проблем - PullRequest
1 голос
/ 11 ноября 2009

Я пользователь какой-то хост-компании, которая обслуживает мою базу данных MySql. Из-за их проблемы с репликацией значения автоинкремента увеличиваются на 10, что, похоже, является распространенной проблемой.

Мой вопрос: как я могу (безопасно) имитировать функцию автоинкремента, чтобы столбец имел последовательный идентификатор?

Моя идея заключалась в том, чтобы реализовать какой-то механизм последовательности для решения моей проблемы, но я не знаю, является ли это лучшим вариантом. Я нашел такой фрагмент кода через Интернет:

DELIMITER ;;

DROP TABLE IF EXISTS `sequence`;;
CREATE TABLE `sequence` (
  `name` CHAR(16) NOT NULL,
  `value` BIGINT UNSIGNED NOT NULL,
  PRIMARY KEY  (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;;

DROP FUNCTION IF EXISTS `nextval`;
CREATE FUNCTION `nextval`(thename CHAR(16) CHARSET latin1)
RETURNS BIGINT UNSIGNED
MODIFIES SQL DATA
SQL SECURITY DEFINER
BEGIN
  INSERT INTO `sequence` 
    SET `name`=thename, 
        `value`=(@val:=@@auto_increment_offset)+@@auto_increment_increment
   ON DUPLICATE KEY 
    UPDATE `value`=(@val:=`value`)+@@auto_increment_increment;
  RETURN @val;
END ;;

DELIMITER ;

что кажется вполне правильным. Мой второй вопрос: является ли это решение безопасным одновременно? Конечно, оператор INSERT есть, но как насчет обновления ON DUPLICATE KEY?

Спасибо!

Ответы [ 2 ]

6 голосов
/ 11 ноября 2009

Зачем вам это нужно?

Даже при auto_increment_increment == 1 вам не гарантируется, что поле автоинкремента в таблице будет иметь последовательные значения (что, если строки будут удалены, хмм?).

С автоинкрементом двигатель db просто гарантирует, что поле будет уникальным, на самом деле ничего.

РЕДАКТИРОВАТЬ: Я хочу повторить: На мой взгляд, не хорошая идея, чтобы принять такие вещи, как параллельные значения столбца автоинкремента, потому что это собирается укусить вас позже.

EDIT2: Во всяком случае, это можно «решить» с помощью триггера «on insert»

create trigger "sequence_b_ins" before insert on `sequence`
for each row
begin
    NEW.id = select max(id)+1 from `sequence`;
end

Или что-то в этом роде (извините, не проверено)

0 голосов
/ 11 ноября 2009

Другой вариант - использовать хранимый процесс для вставки и заставить его либо выбрать максимальный идентификатор из вашей таблицы, либо оставить другую таблицу с текущим используемым идентификатором и обновить ее, используя идентификаторы.

...