GORAGOD.com

freelance, web developer, web designer, hosting, domain name

วิธีหา record ต่อไป สำหรับ field ที่เป็น autoincrement ใน mysql

ผมจะหาลำดับที่ต่อไปของ record ได้อย่างไรครับ คิดไม่ออกครับ
17 ธ.ค. 2551 7 7,382

จะหาอะไรครับ ถ้าเป็น key หลักที่เราสร้างให้เป็น auto_increment ก้ใช้คำสั่ง mysql_insert_id(); หลังจากการ query ครับ ถ้าไม่อย่างงั่นก้หา max ของข้อมูล
#1

SELECT MAX(id) FROM tablename

คำสั่ง sql ครับ ปกติแล้วผมใช้คำสั่งนี้มากกว่า mysql_insert_id(); ครับ เนื่องจาก mysql_insert_id(); เนื่องจาก mysql_insert_id(); มีข้อจำกัดค่อนข้างมาก
#2

ผมต้องการเลขที่ได้นำไปเป็น primary key ของอีกตารางอื่นครับ โดยที่จะต้องไม่เกิดค่าที่ซ้ำกัน

ถ้าใช้ MAX (id)
สมมติว่าในตารางของผมมี 10 record
การใช้ max(id) ถ้าลบ record ออกไป 1 record ก็จะเหลือ 9 record
record ต่อไปผมก็จะได้ค่าที่ซ้ำกับ record ก่อนลบ ซึ่งก็จะใช้ไม่ได้ผล

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


ถ้าใช้ mysql_insert_id()
ก็จะต้องมีการ insert ข้อมูลก่อนจึงจะได้ค่าขึ้นมาใช่ไหมครับ
คำถามต่อ แม้ว่าเราลบบาง record ออกไป ค่าจาก mysql_insert_id() ก็จะไม่ลดใช่ไหมครับ ถ้าตอบก็จะเป็นพระคุณแม้ว่าผมอาจจะไปลองเองได้ (อยากให้ช่วยยืนยัน)

แนวทางที่อาจเป็นไปไดตามความเห็นผม อาจจะต้องใช้ mysql_insert_id() ครับ จะรอความเห็นสนับสนุนหรือเห็นแย้ง (เสนอความเห็นอื่นด้วยนะครับ)
#3

ปัญหาที่เกิดขึ้นผมมองว่าเป็นปัญหาที่ไม่ค่อยสมเหตุสมผล

1. ตาราง 2 ตารางอ้างอิง จาก id เดียวกัน ตามความสัมพันธ์แล้ว เวลาลบ มันควรจะลบรายการออกทั้ง 2 รายการพร้อมกัน โดยลบตารางหลักออก ก็ควรลบตารางรอง ออกด้วย

ผมยกตัวอย่างกรณีบอร์ด เมื่อลบคำถาม ก็ควรลบคำตอบด้วย ดังนั้นกรณี id ซ้ำกับที่มีอยู่แล้วก็จะไม่เกิดขึ้น

2. เป็นความจริงตามนั้น ผมถึงไม่ค่อยใช้ mysql_insert_id() เนื่องจากคำสั่งนี้เกิดหลัง การ insert edit delete

การแก้ปัญหา ใช้ time stamp ก็ได้ แต่ถ้าเกิดกรณีซ้ำกัน ซึ่งคงเกิดในกรณีที่มีการ insert พร้อมกัน 2 คน ก็เป็นได้ ทางแก้ไขหากใช้วิธีนี้ ก็คงต้องทำการตรวจสอบ time stamp ก่อนใช้งาน
ยังมีอีกวิธีหนึ่ง คือ ใช้ running number ภายนอกครับ เช่น สร้างตารางเพื่อเก็บ id สุดท้ายต่างหากจากตารางปกติ วิธีนี้มีข้อเสีบที่ การ insert delete จำเป็นต้องมีการนำมาตรวจสอบตารางนี้ทุกครัง
มีอีกวิธีนึงครับ คือการตรวจหา MAX จากทั้ง 2 ตารางพร้อมกัน คือให้เลือกค่าสูงสุดจากทั้ง 2 ตารางพร้อมกันเลย วิธีนี้มีประสิธิภาพสูงสุดครับ แต่ต้องจัดการ query ถึง 2 ครั้ง

ผมเองมองว่ามันควรจะเข้าตามกฏข้อ 1 มากกว่า ซึ่งทำให้ การใช้งาน MAX ได้ผลอยู่แล้ว ลองเลือกวิธีืัที่เหมาะสมดูครับ
#4

ข้อ 2 และที่อธิบายเพิ่มเติมเคลียร์ดีมากและเห็นด้วยตามนั้นครับ

ขออนุญาตกลับมาที่ข้อ 1 อีกครั้ง

ถ้าการลบ record นั้นเป็นการลบ record สุดท้ายจะไม่มีปัญหา
แต่ถ้าลบ record ตอนต้นๆ เช่น มี 10 record แล้วลบ record ที่ 2 และ 3 ในคราวเดียวกันในตารางหลักและลบ id ที่ 2 และ 3 ในตารางรอง
ค่า MAX(id) ของตารางหลักตอนนี้ก็จะเท่ากับ 8 ส่วน id 9 และ 10 ในตารางรองก็ยังคงอยู่ กรณีนี้การใช้ MAX(id) จะเกิดปัญหาไหมครับ
#5

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

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

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

ถ้าไม่สามารถใช้วิธีใดๆข้างบนได้เลย ก็มีวิธีที่ยังทำได้คือ การหาค่า MAX ของ id ของทั้ง 2 ตารางแล้วเลือกเอาค่า id ที่มากสุดมาใช้งานแทน เท่านั้นเอง


ปล.เราสามารถกำหนด id ด้วยตัวเองได้ครับ ถึงแม้ว่าเราจะกำหนดให้ id เป็น auto_increment ไว้เพียงแต่ id ไม่ควรจะซ้ำกันกับที่มีอยู่แล้วเท่านั้นครับ

ส่วนคำถาม จากการลบ id 2 ก็ไม่ทำให้ค่า MAX เปลี่ยนแปลงไปครับ มันก็ยังคงคืนค่า record สูงสุดเหมือนเดิม เข้น id สุดท้ายที่บันทึกไว้ เป็น 10 มันก็ยังคงคืนค่า 10 แม้ว่าจะลบทุก record ตั้งแต่ 1-9 ไปแล้วครับ

MAX = หาค่าสูงสุด
COUNT = นับจำนวน record
#6

อาจารย์ครับ ผมคงเข้าใจผิดอย่างมหันต์เลย
ถูกต้องที่ค่า MAX(id) ไม่เปลี่ยน แม้ลบ record ต้นๆของตาราง (ก็มันถูกอยู่แล้วนี่)
ผมไปสับสนกับ count ครับ
ซึ่งถ้าผมใช้ count(id) ก็จะเกิดเหตุการณ์อย่างที่ผมอธิบายข้างต้น
ถ้าใช้ MAX(id) ทุกอย่างก็จะเป็นไปตามที่อาจารย์อธิบายทั้งหมด
ผมคงต้องนั่งทำสมาธิสักหน่อยแล้วล่ะ
ขอบคุณครับ

#7
ความคิดเห็น
ไฟล์อัปโหลด ชนิด jpg, jpeg ขนาดไฟล์ไม่เกิน 2M
^