การเพิ่มค่า MAX(Column) + 1 เข้าไปในตาราง MySQL เดียวกัน
บางครั้งอาจต้องการเพิ่มข้อมูลใหม่โดยใช้ค่าสูงสุดของคอลัมน์บวก 1 (Auto Increment แบบ Manual) สามารถทำได้โดยใช้ Subquery ในคำสั่ง INSERT
รูปแบบคำสั่ง
INSERT INTO table_name (column_name) SELECT MAX(column_name) + 1 FROM table_name;
ตัวอย่างเต็มรูปแบบ
สร้างตารางและเพิ่มข้อมูลเริ่มต้น:
CREATE TABLE DemoTable (Id INT); INSERT INTO DemoTable VALUES (100), (175), (165), (145), (170);
ข้อมูลในตารางก่อน Insert:
+------+ | Id | +------+ | 100 | | 175 | | 165 | | 145 | | 170 | +------+
คำสั่ง Insert MAX(Id) + 1
INSERT INTO DemoTable (Id) SELECT MAX(Id) + 1 FROM DemoTable;
ผลลัพธ์: Query OK, 1 row affected
ตรวจสอบข้อมูลหลัง Insert
+------+ | Id | +------+ | 100 | | 175 | | 165 | | 145 | | 170 | | 176 | ← ใหม่ (MAX=175 + 1) +------+
⚠️ ข้อควรระวังสำคัญ
🚫 ไม่แนะนำให้ใช้ใน Production จริง
- Race Condition: ในระบบ Multi-user สองคนอาจได้ค่า MAX เดียวกัน → Duplicate Key Error
- Locking Issue: ต้อง Lock ตารางทั้งตารางเพื่อป้องกันปัญหาข้างต้น
- Performance: ต้อง Scan ทั้งตารางหา MAX ทุกครั้ง
- Gaps: หากลบข้อมูลค่าสูงสุด ค่าจะไม่ต่อเนื่อง
✅ แนวทางที่ดีกว่า
| วิธี | คำอธิบาย |
|---|---|
| AUTO_INCREMENT | MySQL จัดการเองอัตโนมัติ ปลอดภัย เร็ว ไม่ต้อง Lock |
| SEQUENCE (MySQL 8.0+) | สร้าง Sequence object แยกต่างหาก |
| UUID() | สร้าง ID แบบ Unique ไม่ต้องพึ่งพาลำดับ |
| Application-level | สร้าง ID ที่ Application แล้วส่งมา Insert |
กรณีที่อาจใช้ได้
- ระบบ Single-user / Batch process แบบ Offline
- Migration ข้อมูลเก่า
- ตาราง Log / Audit ที่ไม่ต้องการ AUTO_INCREMENT
- การทดสอบ / Prototype ระยะสั้น
ตัวอย่างใช้กับ Lock (ถ้าจำเป็นต้องใช้)
LOCK TABLES DemoTable WRITE; INSERT INTO DemoTable (Id) SELECT MAX(Id) + 1 FROM DemoTable; UNLOCK TABLES;
แม้จะใช้ Lock แล้ว ก็ยังมีโอกาสเกิด Deadlock และประสิทธิภาพต่ำในระบบ High Concurrency