Tôi đồng ý với @Aaron Digulla và @Shane N. Những khoảng trống là vô nghĩa. Nếu họ LÀM nghĩa là gì đó, đó là một thiết kế cơ sở dữ liệu thiếu sót. Khoảng thời gian.
Điều đó đang được nói, nếu bạn hoàn toàn CẦN lấp những lỗ này, VÀ bạn đang chạy ít nhất MySQL 3.23, bạn có thể sử dụng BẢNG TẠM THỜI để tạo một bộ ID mới. Ý tưởng ở đây là bạn sẽ chọn tất cả các ID hiện tại của mình, theo thứ tự, vào một bảng tạm thời như sau:
CREATE TEMPORARY TABLE NewIDs
(
NewID INT UNSIGNED AUTO INCREMENT,
OldID INT UNSIGNED
)
INSERT INTO NewIDs (OldId)
SELECT
Id
FROM
OldTable
ORDER BY
Id ASC
Điều này sẽ cung cấp cho bạn một bảng ánh xạ Id cũ của bạn với một Id hoàn toàn mới sẽ có tính chất tuần tự, do thuộc tính AUTO INCREMENT của cột NewId.
Khi việc này được thực hiện, bạn cần cập nhật bất kỳ tham chiếu nào khác đến Id trong "OldTable" và bất kỳ khóa ngoại nào mà nó sử dụng. Để thực hiện việc này, có thể bạn sẽ cần phải XÓA bất kỳ ràng buộc khóa ngoại nào mà bạn có, cập nhật bất kỳ tham chiếu nào trong các bảng từ OldId đến NewId, sau đó thiết lập lại các ràng buộc khóa ngoại của bạn.
Tuy nhiên, tôi tranh luận rằng bạn không nên làm BẤT KỲ về điều này, và chỉ cần hiểu rằng trường Id của bạn tồn tại với mục đích duy nhất là tham chiếu bản ghi và KHÔNG ĐƯỢC có bất kỳ mức độ liên quan cụ thể nào.
CẬP NHẬT:Thêm ví dụ về cập nhật Id
Ví dụ:
Giả sử bạn có 2 lược đồ bảng sau:
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)
)
Bây giờ, các khoảng trống đang xuất hiện trong bảng Gốc của bạn.
Để cập nhật các giá trị của bạn trong Parent and Child, trước tiên bạn tạo một bảng tạm thời với các ánh xạ:
CREATE TEMPORARY TABLE NewIDs
(
Id INT UNSIGNED AUTO INCREMENT,
ParentID INT UNSIGNED
)
INSERT INTO NewIDs (ParentId)
SELECT
ParentId
FROM
Parent
ORDER BY
ParentId ASC
Tiếp theo, chúng ta cần yêu cầu MySQL bỏ qua ràng buộc khóa ngoại để chúng ta có thể CẬP NHẬT các giá trị của mình một cách chính xác. Chúng tôi sẽ sử dụng cú pháp này:
SET foreign_key_checks = 0;
Điều này khiến MySQL bỏ qua kiểm tra khóa ngoại khi cập nhật giá trị, nhưng nó vẫn sẽ thực thi loại giá trị chính xác được sử dụng (xem Tham chiếu MySQL để biết chi tiết).
Tiếp theo, chúng ta cần cập nhật bảng Gốc và Bảng con với các giá trị mới. Chúng tôi sẽ sử dụng câu lệnh CẬP NHẬT sau đây cho việc này:
UPDATE
Parent,
Child,
NewIds
SET
Parent.ParentId = NewIds.Id,
Child.ParentId = NewIds.Id
WHERE
Parent.ParentId = NewIds.ParentId AND
Child.ParentId = NewIds.ParentId
Bây giờ chúng tôi đã cập nhật tất cả các giá trị ParentId của chúng tôi một cách chính xác thành các Id mới, có thứ tự từ bảng tạm thời của chúng tôi. Khi quá trình này hoàn tất, chúng tôi có thể tiến hành kiểm tra lại khóa ngoại của mình để duy trì tính toàn vẹn của tham chiếu:
SET foreign_key_checks = 1;
Cuối cùng, chúng tôi sẽ xóa bảng tạm thời của mình để dọn dẹp tài nguyên:
DROP TABLE NewIds
Và đó là điều đó.