2016-11-09 2 views
0

Я бег запроса SQL, выглядит немного как этотдублирование KEY UPDATE ID = LAST_INSERT_ID (идентификатор) без увеличения AUTOINDEX

INSERT INTO people (Name, Role) 
VALUES('{$Name}', '{$Occupation') 
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id) 

В таблице «люди» имеет суррогатный ключ ID в качестве первичного, что устанавливается MySQLs Autoindex.

«Имя» и «Роль» объединены как составной уникальный ключ.

Проблема заключается в том, что когда я запускаю этот запрос и ударяю кого-то с тем же именем и ролью и получаю соответствующий идентификатор, автоиндекс все равно увеличивается.

Возможно ли это предотвратить, или мне нужно запустить 2 отдельных запроса, чтобы проверить, существует ли уже и затем вставить?

+0

Этот код выглядит так, как будто он отчаянно нуждается в использовании * placeholder values ​​*. Существует большая вероятность того, что эти две вещи [дыры SQL-инъекций] (http://bobby-tables.com/). – tadman

+0

Вам также, вероятно, придется нормализовать эту таблицу и лучше справиться с столкновениями. Что, если есть два человека по имени «Дейв Тейлор», которые оба доктора? – tadman

ответ

2

Во-первых, вы не должны волноваться, если автоинкремент увеличивается. По общему признанию, это эстетически «уродливое», но пробелы в последовательности не должны иметь значения. И разрыв может появиться по другим причинам.

Но, если это имеет значение, вы можете уменьшить вероятность этого происходит путем проверки в запросе:

INSERT INTO people (Name, Role) 
    SELECT name, role 
    FROM (SELECT '{$Name}' as name, '{$Occupation}' as role) x 
    WHERE NOT EXISTS (SELECT 1 FROM people p WHERE p.name = x.name) 
    ON DUPLICATE KEY UPDATE name = VALUES(name); -- no op; 

Вы все еще можете получить условия гонки, где могут возникнуть пробелы, но это делает, что гораздо менее вероятно.

+0

Не из-за эстетики, просто из-за того, как часто выполняется запрос, я боялся потенциально поразить максимальное значение id в течение года, что стало бы довольно головоломкой. Спасибо, пробовал это – PeaceDealer

+0

@ пользователь3853973. , , Если это так, возможно, вы должны использовать значение «bigint» для значения столбца. –

1

В тузде документации по insert ... on duplicate key update говорит:

Например, если столбец объявлен как UNIQUE и содержит значение 1, следующие два оператора имеет аналогичный эффект:

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE 
c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 

(Эффекты не идентичны для таблицы InnoDB, где a - столбец с автоматическим приращением. С помощью столбца auto-increment оператор INSERT увеличивает значения автоинкрементного но UPDATE не делает.)

Таким образом, для таблиц InnoDB это ожидаемое поведение. Либо вы выбираете другой механизм таблицы для своей таблицы, либо не можете использовать предложение on duplicate key update, если вы не хотите, чтобы ваше поле автоматического увеличения увеличилось в случае обновления. Примечание: нет ничего неправильного, чтобы иметь пробелы в последовательности идентификаторов auto_increment. Если есть бизнес-требование непрерывно увеличивающегося серийного номера, то вы не должны использовать автоматическое увеличение в любом случае.

Update:

Если вы беспокоитесь о исчерпывает BIGINT диапазона в ближайшее время, а затем использовать функцию uuid() MySQL или что-то подобное из PHP для создания уникальных идентификаторов для вас. Но максимальный диапазон unsigned bigint довольно большой ...

Смежные вопросы