Bạn mua vé xem phim, trên mỗi vé sẽ có số in sẵn. Sau đó, hệ thống sẽ đánh số vé tiếp theo liền kề (ví dụ: vé 001, 002, 003) cho các vé tiếp theo. Không bao giờ có hai vé trùng số.
Hôm nay bạn tạo bảng:usersDữ liệu:
| id | username |
|---|---|
| 1 | admin |
| 2 | nam |
| 3 | hoa |
| 4 | linh |
| 5 | hung |
Mọi thứ đều ổn.
😎
Bạn quyết định xóa:
DELETE FROM users
WHERE id=5;Bảng còn:
| id | username |
| 1 | admin |
| 2 | nam |
| 3 | hoa |
| 4 | linh |
Sau đó thêm user mới:
INSERT INTO users(username)
VALUES('tuan');Bạn mong đợi:
ID = 5😎
Nhưng MySQL trả về:
ID = 6🤡
Người mới:
"Ủa?"
"Số 5 còn trống mà?"
😵
Vì sao chuyện này xảy ra?
Trong MySQL, cột AUTO_INCREMENT thường không sử dụng lại các ID đã bị xóa.
Thay vào đó MySQL tiếp tục tăng từ giá trị lớn nhất đã từng cấp phát.
Ví dụ:
Đã dùng tới 5
↓
Xóa 5
↓
Bản ghi mới nhận 6Đây là hành vi hoàn toàn bình thường.
Ví dụ đời thường 🍜
Bạn đi khám bệnh.
Lấy số:
001
002
003
004
005Người số:
005bỏ về.
😄
Bệnh viện không làm:
005mới rồi phát lại cho người kế tiếp.
Thay vào đó:
006Đơn giản hơn.
Ít rủi ro hơn.
AUTO_INCREMENT cũng suy nghĩ như vậy.
😎
MySQL nhớ điều gì?
Nhiều người nghĩ:
MySQL đếm số dòngKhông.
MySQL nhớ:
Số tiếp theo sẽ cấp phátVí dụ:
1
2
3
4
5Nó ghi nhớ:
Lần tới là 6Cho dù:
5 bị xóavẫn vậy.
😄
Một hiểu lầm cực phổ biến 🤡
Người mới:
"Nếu bảng còn 4 dòng thì ID mới phải là 5."
Không.
MySQL không quan tâm bảng còn bao nhiêu dòng.
Nó chỉ quan tâm:
Lần cấp phát cuối cùng là bao nhiêu😎
Ví dụ đau lòng 😭
Bảng:
| id | username |
| 1 | admin |
| 2 | nam |
| 3 | hoa |
Bạn xóa:
2Còn:
| id | username |
| 1 | admin |
| 3 | hoa |
Thêm mới:
linhKết quả:
| id | username |
| 1 | admin |
| 3 | hoa |
| 4 | linh |
Người mới:
"ID số 2 đâu?"
😵
MySQL:
"Đó là lịch sử."
😎
Tại sao MySQL không tái sử dụng ID?
Nếu tái sử dụng liên tục:
5
↓
xóa
↓
5
↓
xóa
↓
5Có thể gây:
💀 Nhầm dữ liệu
💀 Nhầm log
💀 Nhầm liên kết
💀 Nhầm báo cáo
Đặc biệt ở hệ thống lớn.
Ví dụ thực tế 😄
User:
ID = 500đã từng tồn tại.
Log hệ thống ghi:
User 500 đăng nhậpNếu sau này:
500được cấp cho người khác.
Bạn sẽ rất khó phân biệt.
😵
Có phải ID bị nhảy số là lỗi?
👉 Không.
Ví dụ:
1
2
5
8
12Hoàn toàn bình thường.
😄
Rất nhiều website lớn cũng vậy.
InfinityFree Case 😅
Nhiều bạn upload website.
Nhìn thấy:
1
2
4
7
9Hoảng hốt:
"Database lỗi rồi!"
😭
Không.
Đây là hành vi bình thường của:
AUTO_INCREMENTCó nên reset AUTO_INCREMENT?
Ví dụ:
ALTER TABLE users
AUTO_INCREMENT = 1;Nghe có vẻ hấp dẫn.
😎
Nhưng thực tế:
👉 Hiếm khi cần.
Và nếu dữ liệu vẫn còn:
💀 Có thể gặp:
Duplicate EntryKhi nào nên reset?
Thường chỉ khi:
Bảng test
Bảng demo
Bảng rỗngVí dụ:
TRUNCATE TABLE users;Sau đó:
AUTO_INCREMENTthường quay về đầu.
Nhưng với dữ liệu thật:
👉 Thường không cần.
😄
Sự thật biết rồi, khổ lắm, nói mãi 😎
Nhiều người nghĩ:
ID phải liên tụcThực tế:
Các hệ thống lớn thường có:
ID nhảy sốThậm chí có nơi:
1001
1050
1200
3000Và không ai quan tâm.
😄
Điều quan trọng là:
ID duy nhấtKhông phải:
ID đẹp🤡
Debug kiểu dev thật 😎
✅ 1. Kiểm tra AUTO_INCREMENT
SHOW CREATE TABLE users;✅ 2. Kiểm tra giá trị tiếp theo
Trong phpMyAdmin:
Auto Increment✅ 3. Dùng COUNT(*) để đếm dữ liệu
Đừng dùng:
SELECT MAX(id)Hãy dùng:
SELECT COUNT(*)😎
Checklist chuẩn không cần chỉnh 😎
☑ Xóa dữ liệu không làm ID quay lại
☑ AUTO_INCREMENT không đếm số dòng
☑ ID nhảy số là bình thường
☑ Không cần reset AUTO_INCREMENT thường xuyên
☑ COUNT(*) mới là số lượng dữ liệu
☑ MAX(id) không phải số user
FAQ nhanh
Vì sao xóa ID số 5 nhưng user mới nhận số 6?
→ Vì AUTO_INCREMENT tiếp tục tăng.
ID bị nhảy số có phải lỗi?
→ Không 😄
Có nên sửa cho ID liên tục không?
→ Thường không.
MAX(id) có phải số lượng dữ liệu không?
→ Không 😅
Bạn có thể cũng đang gặp 😭
👉 AUTO_INCREMENT hoạt động ra sao?
👉 LIMIT trong MySQL là gì?
👉 Pagination là gì?
👉 JOIN là gì?
👉 Duplicate Entry là gì?
👉 Backup database đúng cách
Tổng kết
AUTO_INCREMENT không hoạt động theo kiểu:
Tiết kiệm từng con số😄
Nó hoạt động theo kiểu:
Đã dùng rồi
↓
Cho nghỉ hưu luônVì vậy:
1
2
3
4
5xóa:
5Thêm mới:
6là hoàn toàn bình thường.
😎
Và hãy nhớ:
MySQL không quan tâm ID có đẹp hay không.
Nó chỉ quan tâm:
"Có duy nhất hay không."
Còn chuyện số 5 đang trống...
MySQL ngủ rất ngon và không hề bận tâm. 🤡