Я согласен с @Aaron Digulla и @Shane N. Пробелы не имеют смысла. Если они DO что-то значат, это неверный дизайн базы данных. Период.
При этом, если вам абсолютно НЕОБХОДИМО заполнить эти дыры, И вы используете по крайней мере MySQL 3.23, вы можете использовать ВРЕМЕННЫЙ СТОЛ для создания нового набора идентификаторов. Идея заключается в том, что вы собираетесь выбрать все свои текущие идентификаторы по порядку во временной таблице как таковой:
CREATE TEMPORARY TABLE NewIDs
(
NewID INT UNSIGNED AUTO INCREMENT,
OldID INT UNSIGNED
)
INSERT INTO NewIDs (OldId)
SELECT
Id
FROM
OldTable
ORDER BY
Id ASC
Это даст вам таблицу, отображающую ваш старый Id на новый Id, который будет иметь последовательный характер, благодаря свойству AUTO INCREMENT столбца NewId.
Как только это будет сделано, вам нужно обновить любую другую ссылку на Id в «OldTable» и любой внешний ключ, который он использует. Для этого вам, вероятно, потребуется сбросить все имеющиеся у вас ограничения внешнего ключа, обновить любую ссылку в таблицах с OldId на NewId, а затем заново установить ограничения внешнего ключа.
Однако я бы сказал, что вы не должны делать ЛЮБОГО этого, а просто понимать, что ваше поле Id существует исключительно для ссылки на запись и должно иметь НЕ любое конкретное отношение.
ОБНОВЛЕНИЕ: добавление примера обновления идентификаторов
Например:
Допустим, у вас есть следующие 2 схемы таблиц:
CREATE TABLE Parent
(
ParentId INT UNSIGNED AUTO INCREMENT,
Value INT UNSIGNED,
PRIMARY KEY (ParentId)
)
CREATE TABLE Child
(
ChildId INT UNSIGNED AUTO INCREMENT,
ParentId INT UNSIGNED,
PRIMARY KEY(ChildId),
FOREIGN KEY(ParentId) REFERENCES Parent(ParentId)
)
Теперь, пробелы появляются в вашей родительской таблице.
Чтобы обновить ваши значения в Parent и Child, вы сначала создаете временную таблицу с отображениями:
CREATE TEMPORARY TABLE NewIDs
(
Id INT UNSIGNED AUTO INCREMENT,
ParentID INT UNSIGNED
)
INSERT INTO NewIDs (ParentId)
SELECT
ParentId
FROM
Parent
ORDER BY
ParentId ASC
Далее, мы должны указать MySQL игнорировать ограничение внешнего ключа, чтобы мы могли правильно ОБНОВИТЬ наши значения. Мы будем использовать этот синтаксис:
SET foreign_key_checks = 0;
Это заставляет MySQL игнорировать проверки внешнего ключа при обновлении значений, но все равно будет принудительно использовать правильный тип значения (подробности см. Справочник по MySQL ).
Далее нам нужно обновить наши родительские и дочерние таблицы новыми значениями. Для этого мы будем использовать следующий оператор UPDATE:
UPDATE
Parent,
Child,
NewIds
SET
Parent.ParentId = NewIds.Id,
Child.ParentId = NewIds.Id
WHERE
Parent.ParentId = NewIds.ParentId AND
Child.ParentId = NewIds.ParentId
Теперь мы корректно обновили все наши значения ParentId до новых упорядоченных идентификаторов из нашей временной таблицы. Как только это будет завершено, мы сможем восстановить наши проверки внешнего ключа для сохранения ссылочной целостности:
SET foreign_key_checks = 1;
Наконец, мы удалим нашу временную таблицу для очистки ресурсов:
DROP TABLE NewIds
И это все.