MySQL AUTO_INCREMENT พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

MySQL AUTO_INCREMENT จะสร้างหมายเลขลำดับโดยอัตโนมัติสำหรับคอลัมน์ตัวเลขทุกครั้งที่มีการแทรกแถวใหม่ คุณสมบัตินี้ช่วยลดความจำเป็นในการคำนวณตัวระบุที่ไม่ซ้ำกันด้วยตนเอง ทำให้เป็นวิธีมาตรฐานในการกำหนดค่าคีย์หลัก

  • 🔢 พฤติกรรมหลัก: AUTO_INCREMENT จะกำหนดหมายเลขถัดไปในลำดับเมื่อมีการแทรกแถวใหม่ โดยเริ่มต้นที่ 1 และเพิ่มขึ้นทีละขั้นping โดย 1
  • 🔑 บทบาทหลักสำคัญ: คุณลักษณะนี้รับประกันตัวระบุที่ไม่ซ้ำกันโดยไม่ต้องใช้การค้นหา ดังนั้นจึงเป็นตัวเลือกมาตรฐานสำหรับคีย์หลักทดแทน
  • 🧱 ข้อกำหนดของคอลัมน์: คอลัมน์ต้องเป็นชนิดข้อมูลจำนวนเต็มและต้องมีการสร้างดัชนี ซึ่งการประกาศ PRIMARY KEY นั้นตรงตามข้อกำหนดนี้อยู่แล้ว
  • ใส่แพทเทิร์น: ไม่ต้องใส่คอลัมน์ตัวระบุในคำสั่ง INSERT และ MySQL ระบุค่า จากนั้นฟังก์ชัน LAST_INSERT_ID() จะส่งคืนค่านั้น
  • 🎚️ ค่าเริ่มต้นที่กำหนดเอง: คำสั่ง CREATE TABLE หรือ ALTER TABLE ยอมรับค่า AUTO_INCREMENT = 10 เพื่อเริ่มต้นลำดับที่หมายเลขที่เลือกไว้
  • 🕳️ คาดการณ์ช่องว่าง: แถวที่ถูกลบและธุรกรรมที่ถูกยกเลิกจะใช้หมายเลขอย่างถาวร ดังนั้นลำดับจึงยังคงไม่ซ้ำกันแต่ไม่ต่อเนื่องกัน

MySQL AUTO_INCREMENT

การเพิ่มอัตโนมัติคืออะไร?

Auto Increment คือฟังก์ชันที่ดำเนินการกับประเภทข้อมูลตัวเลข โดยจะสร้างค่าตัวเลขตามลำดับโดยอัตโนมัติทุกครั้งที่มีการแทรกเรกคอร์ดลงในตารางสำหรับฟิลด์ที่กำหนดให้เป็นการเพิ่มอัตโนมัติ

คุณสมบัตินี้ใช้ได้กับชนิดข้อมูลจำนวนเต็มทุกประเภท ตั้งแต่ TINYINT ไปจนถึง BIGINT คอลัมน์นั้นจะต้องมีการสร้างดัชนีด้วย ซึ่งจะเกิดขึ้นโดยอัตโนมัติเมื่อประกาศเป็นคีย์หลัก

เมื่อใช้การเพิ่มขึ้นอัตโนมัติ?

ในบทเรียนเรื่อง การทำให้ฐานข้อมูลเป็นมาตรฐานเราได้พิจารณาถึงวิธีการจัดเก็บข้อมูลโดยลดความซ้ำซ้อนให้น้อยที่สุด โดยการจัดเก็บข้อมูลลงในตารางขนาดเล็กจำนวนมาก ซึ่งเชื่อมโยงกันโดยใช้คีย์หลักและคีย์รอง

MySQL AUTO_INCREMENT พร้อมตัวอย่าง

คีย์หลักต้องมีค่าที่ไม่ซ้ำกัน เนื่องจากใช้ระบุแต่ละแถวในฐานข้อมูลได้อย่างเฉพาะเจาะจง แต่เราจะมั่นใจได้อย่างไรว่าคีย์หลักนั้นมีค่าไม่ซ้ำกันเสมอ?

หนึ่งในวิธีแก้ปัญหาที่เป็นไปได้คือการใช้สูตรเพื่อสร้างคีย์หลัก ซึ่งจะตรวจสอบว่าคีย์นั้นมีอยู่ในตารางหรือไม่ก่อนที่จะเพิ่มข้อมูล วิธีนี้อาจได้ผล แต่เป็นวิธีที่ซับซ้อนและไม่สมบูรณ์แบบ การแทรกข้อมูลสองครั้งพร้อมกันอาจยังคงอ่านค่าสูงสุดเดียวกันและทำให้เกิดการชนกันได้

เพื่อหลีกเลี่ยงความซับซ้อนดังกล่าว และเพื่อให้แน่ใจว่าคีย์หลักนั้นไม่ซ้ำกันเสมอ เราสามารถใช้ MySQL คุณสมบัติการเพิ่มค่าอัตโนมัติ (Auto Increment) ใช้สำหรับสร้างคีย์หลัก การเพิ่มค่าอัตโนมัติใช้กับชนิดข้อมูล INT ชนิดข้อมูล INT รองรับทั้งค่าที่มีเครื่องหมายและไม่มีเครื่องหมาย ชนิดข้อมูลที่ไม่มีเครื่องหมายสามารถเก็บได้เฉพาะตัวเลขบวกเท่านั้น ตามหลักปฏิบัติที่ดีที่สุด แนะนำให้กำหนดข้อจำกัดที่ไม่มีเครื่องหมาย (unsigned constraint) บนคีย์หลักที่ใช้การเพิ่มค่าอัตโนมัติ

ไวยากรณ์การเพิ่มขึ้นอัตโนมัติ

เมื่อได้อธิบายเหตุผลเรียบร้อยแล้ว ลองมาดูสคริปต์ที่ใช้สร้างตารางหมวดหมู่ภาพยนตร์กัน

CREATE TABLE `categories` (
  `category_id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `category_name` varchar(150) DEFAULT NULL,
  `remarks` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`category_id`)
);

โปรดสังเกต "AUTO_INCREMENT" ในฟิลด์ category_id ซึ่งจะทำให้รหัสหมวดหมู่ถูกสร้างขึ้นโดยอัตโนมัติทุกครั้งที่มีการแทรกแถวใหม่ลงในตาราง โดยจะไม่ได้ระบุค่านี้เมื่อทำการแทรกข้อมูลลงในตาราง MySQL สร้างมันขึ้นมา

หมายเหตุ คีย์เวิร์ด UNSIGNED จะเพิ่มช่วงบวกของคอลัมน์เป็นสองเท่า และความกว้างในการแสดงผลที่เคยเขียนเป็น int(11) นั้นเลิกใช้แล้ว MySQL ตั้งแต่ 8.0.17 เป็นต้นไป แบบธรรมดา int เป็นรูปแบบปัจจุบัน

โดยค่าเริ่มต้น ค่าเริ่มต้นของ AUTO_INCREMENT คือ 1 และจะเพิ่มขึ้นทีละ 1 สำหรับแต่ละเรคอร์ดใหม่

เรามาตรวจสอบเนื้อหาปัจจุบันของตารางหมวดหมู่กันเถอะ

SELECT * FROM `categories`;

ดำเนินการสคริปต์ข้างต้นใน MySQL การทดสอบด้วย Workbench กับ myflixdb ให้ผลลัพธ์ดังต่อไปนี้

category_id category_name remarks
1 Comedy Movies with humour
2 Romantic Love stories
3 Epic Story acient movies
4 Horror NULL
5 Science Fiction NULL
6 Thriller NULL
7 Action NULL
8 Romantic Comedy NULL

มีทั้งหมดแปดแถว ดังนั้นรหัสที่สร้างขึ้นถัดไปควรจะเป็น 9 ตอนนี้เรามาแทรกหมวดหมู่ใหม่ลงในตารางหมวดหมู่ โดยระบุเพียงชื่อเท่านั้น

INSERT INTO `categories` (`category_name`) VALUES ('Cartoons');

ดำเนินการสคริปต์ข้างต้นกับ myflixdb ใน MySQL ปรับแต่ง ทำให้เราได้ผลดังแสดงข้างล่างนี้

category_id category_name remarks
1 Comedy Movies with humour
2 Romantic Love stories
3 Epic Story acient movies
4 Horror NULL
5 Science Fiction NULL
6 Thriller NULL
7 Action NULL
8 Romantic Comedy NULL
9 Cartoons NULL

โปรดทราบว่าเราไม่ได้ระบุรหัสหมวดหมู่ MySQL ระบบสร้างขึ้นโดยอัตโนมัติ เนื่องจากรหัสหมวดหมู่ถูกกำหนดให้เพิ่มขึ้นอัตโนมัติ

หากคุณต้องการรับรหัสแทรกล่าสุดที่สร้างขึ้นโดย MySQLคุณสามารถใช้ฟังก์ชัน LAST_INSERT_ID เพื่อดำเนินการดังกล่าวได้ สคริปต์ที่แสดงด้านล่างได้รับรหัสล่าสุดที่สร้างขึ้น

SELECT LAST_INSERT_ID();

การเรียกใช้สคริปต์ข้างต้นจะให้หมายเลขเพิ่มอัตโนมัติล่าสุดที่สร้างโดยคำสั่ง INSERT ผลลัพธ์แสดงอยู่ด้านล่าง

MySQL AUTO_INCREMENT

เคล็ดลับ: ฟังก์ชัน LAST_INSERT_ID() นั้นจำกัดขอบเขตการใช้งานเฉพาะการเชื่อมต่อของคุณเท่านั้น ดังนั้นค่าที่สร้างขึ้นจากการแทรกข้อมูลของผู้ใช้รายอื่นจึงไม่สามารถส่งกลับมายังคุณโดยไม่ได้ตั้งใจได้

วิธีตั้งค่าหรือรีเซ็ตค่าเริ่มต้น AUTO_INCREMENT

ลำดับเริ่มต้นตามค่าเริ่มต้นจะเริ่มที่ 1 แต่ไม่ใช่ว่าทุกโครงการจะต้องการเช่นนั้นเสมอไป หมายเลขใบแจ้งหนี้อาจต้องต่อเนื่องจากระบบเดิม และตารางทดสอบมักจะต้องถูกรีเซ็ตใหม่ MySQL เปิดเผยตัวนับโดยตรง ดังนั้นจึงสามารถจัดการทั้งสองกรณีได้ด้วยข้อความเงื่อนไขเดียว ทำตามขั้นตอนเหล่านี้เพื่อควบคุมหมายเลขเริ่มต้น

  1. กำหนดค่า ณ เวลาสร้าง เพิ่มข้อความ AUTO_INCREMENT ต่อท้ายคำสั่ง CREATE TABLE แถวแรกที่แทรกเข้าไปจะได้รับหมายเลขนั้นแทนที่จะเป็นเลข 1
  2. เปลี่ยนแปลงค่าในตารางที่มีอยู่แล้ว ใช้ แก้ไขตาราง โดยมีข้อความเดียวกัน MySQL ระบบจะยอมรับหมายเลขใหม่ก็ต่อเมื่อหมายเลขนั้นสูงกว่าหมายเลขระบุตัวตนที่ใหญ่ที่สุดที่จัดเก็บไว้ในปัจจุบันเท่านั้น
  3. รีเซ็ตตารางที่คุณได้ล้างข้อมูลไปแล้ว คำสั่ง TRUNCATE TABLE จะลบทุกแถวและคืนค่าตัวนับเป็น 1 ในการดำเนินการเพียงครั้งเดียว ซึ่งคำสั่ง DELETE เพียงอย่างเดียวไม่สามารถทำได้
  4. ยืนยันการเปลี่ยนแปลง แทรกแถวและอ่านค่าตัวระบุกลับมาด้วย LAST_INSERT_ID() ก่อนที่จะใช้ลำดับใหม่
-- Start a brand-new table at 1000
CREATE TABLE `invoices` (
  `invoice_id` int UNSIGNED NOT NULL AUTO_INCREMENT,
  `amount` decimal(10,2),
  PRIMARY KEY (`invoice_id`)
) AUTO_INCREMENT = 1000;

-- Move the counter on an existing table
ALTER TABLE `categories` AUTO_INCREMENT = 100;

-- Empty the table and reset the counter to 1
TRUNCATE TABLE `categories`;

ขนาดของขั้นตอนสามารถเปลี่ยนแปลงได้โดยใช้ตัวแปรระบบ auto_increment_increment แต่จะมีผลกับทั้งเซิร์ฟเวอร์ ไม่ใช่แค่ตารางเดียว โดยส่วนใหญ่จะใช้ในการจำลองข้อมูล ซึ่งเซิร์ฟเวอร์สองเครื่องต้องไม่สร้างตัวระบุเดียวกัน

ทำไมจึงมีช่องว่างปรากฏในลำดับ AUTO_INCREMENT?

ไม่ช้าก็เร็ว ตารางจะแสดงตัวเลขระบุเช่น 1, 2, 5, 6 ไม่มีอะไรผิดปกติ ตัวนับถูกออกแบบมาเพื่อรับประกันความไม่ซ้ำกัน ไม่ใช่เพื่อรับประกันลำดับตัวเลขที่ไม่ขาดตอน และจะไม่แสดงค่าเดียวกันซ้ำสองครั้ง

ช่องว่างเกิดขึ้นจากสาเหตุดังต่อไปนี้

  • แถวที่ถูกลบ: เมื่อมีการลบแถวออกจากตาราง รหัสประจำตัวที่เพิ่มขึ้นอัตโนมัติของแถวนั้นจะไม่ถูกนำกลับมาใช้ใหม่ MySQL ยังคงสร้างตัวเลขใหม่ขึ้นมาอย่างต่อเนื่อง
  • ธุรกรรมที่ถูกยกเลิก: หมายเลขดังกล่าวจะถูกจองทันทีที่ทำการแทรกข้อมูล หากยกเลิกธุรกรรม ข้อมูลในแถวนั้นจะหายไป แต่หมายเลขนั้นจะถูกใช้ไปแล้ว
  • การแทรกข้อมูลล้มเหลว: คำสั่งที่ถูกปฏิเสธโดยข้อจำกัด UNIQUE ยังคงสามารถใช้ตัวระบุได้ก่อนที่จะเกิดข้อผิดพลาด
  • แผ่นแทรกจำนวนมาก: InnoDB อาจสงวนบล็อกหมายเลขไว้สำหรับการแทรกข้อมูลหลายแถว และทิ้งหมายเลขที่ไม่ใช้งาน

การพยายามอุดช่องว่างเหล่านี้เป็นความผิดพลาด การกำหนดหมายเลขแถวใหม่จะทำลายคีย์ต่างประเทศทั้งหมดที่ชี้ไปยังแถวนั้น และค่าที่ได้นั้นไม่มีความหมายทางธุรกิจใดๆ หากรายงานต้องการรายการต่อเนื่อง ให้สร้างหมายเลขแถวในแบบสอบถามแทนที่จะเขียนทับข้อมูลที่จัดเก็บไว้

คำถามที่พบบ่อย

ลำดับ MySQL อนุญาตให้มีคอลัมน์ AUTO_INCREMENT เพียงคอลัมน์เดียวต่อตาราง และคอลัมน์นั้นต้องมีการสร้างดัชนี โดยการประกาศเป็น คีย์หลัก ตรงตามข้อกำหนดของดัชนี

การแทรกข้อมูลล้มเหลวเนื่องจากข้อผิดพลาดคีย์ซ้ำ เพราะตัวนับไม่สามารถเลื่อนเกินค่าสูงสุดของชนิดข้อมูลได้ ชนิดข้อมูล TINYINT ที่ไม่มีเครื่องหมายจะหยุดที่ 255 โปรดเปลี่ยนคอลัมน์เป็นชนิดข้อมูลที่กว้างกว่า เช่น BIGINT ก่อนถึงจุดนั้น

ใช่ จาก MySQL ตั้งแต่เวอร์ชัน 8.0 เป็นต้นไป InnoDB จะเขียนตัวนับลงในไฟล์บันทึกการทำซ้ำ (redo log) ดังนั้นค่าจะถูกกู้คืนหลังจากรีสตาร์ท เวอร์ชันก่อนหน้าจะคำนวณค่าใหม่และอาจกำหนดหมายเลขใหม่ให้กับข้อมูลที่ถูกลบไปแล้ว

บางส่วน ผู้ช่วยสร้างแผนผัง AI ภายในเครื่องมือต่างๆ เช่น MySQL ม้านั่งทำงานของช่างเครื่อง แนะนำให้ใช้จำนวนเต็มที่ไม่ติดลบที่มีช่วงกว้างพอสำหรับปริมาตรที่คุณอธิบาย การประมาณการจะแม่นยำได้ก็ต่อเมื่อตัวเลขการเติบโตที่คุณให้มานั้นถูกต้อง ดังนั้นโปรดตรวจสอบความถูกต้องด้วย

ใช่ บ่อยครั้ง ระบบช่วยค้นหาข้อมูลด้วย AI จะชี้ไปยังธุรกรรมที่ถูกยกเลิกหรือล้มเหลว INSERT คำสั่งต่างๆ และแถวที่ถูกลบเป็นสาเหตุที่พบบ่อย ให้ถือว่าคำอธิบายนี้เป็นเพียงจุดเริ่มต้น และตรวจสอบยืนยันกับบันทึกของเซิร์ฟเวอร์อีกครั้ง

สรุปโพสต์นี้ด้วย: