เทคนิค การจัดตัวเลขที่มีรูปแบบ (Running Number)
ก่อนอื่นเรามาดูวิธีการสร้างรหัสก่อน
จริงๆแล้วถ้าเป็นไปได้ ผมแนะนำให้จัดการรหัสสินค้าด้วยวิธีนี้ เทคนิคการกำหนดรหัสสินค้า แต่วิธีนี้เราจะไม่สามารถจัดการรหัสสินค้าโดยอัตโนมัติได้ แต่ในกรณีที่ต้องการสร้างรหัสสินค้า (หรือรหัสต่อเนื่อง ใดๆ) ด้วยตัวเองก็สามารถสร้างรหัสได้ด้วยคำสั่งนี้
<?php
$id = 1;
$code = sprintf('P-%04d', $id);
echo $code; // P-0001
?>
คำสั่งที่ใช้คือ sprinf() ครับ โดยที่ P-%04d แยกออกดังนี้
- %04d เป็นคำสั่งกำหนดรูปแบบให้ ให้เติม 0 ด้านหน้าตัวเลขให้ครบ 4 หลัก (รายละเอียดเพิ่มเติม http://php.net/...unction.sprintf.php)
- P- อันนี้เป็น prefix ที่ใช้เติมด้านหน้าเฉยๆ ครับ จะมีหรือไม่ก็ได้ ที่สำคัญคือต้องไม่ตรงกับรูปแบบคำสั่งของ sprinf
$id คือค่าตัวเลขที่ต้องการ มีค่าระหว่าง 0-9999 ซึ่งจะได้รหัสเป็น P-0000 ถึง P-9999 ซึ่งค่าตัวเลขนี้เราต้องกำหนดเอง หรือเอามาจากฐานข้อมูลครับ ซึงวิธีอ่านค่านี้จากฐานข้อมูล มี วิธีหลักๆที่เป็นที่นิยม 3 วิธี
วิธีแรกคืออ่าน ID จากคอลัมน์ ID ที่เป็น AUTO_INCREMENT ของตาราง วิธีนี้จะได้ ID ของข้อมูลตรงกันกับ ID ของรหัสสินค้าอัตโนมัติ
<?php
$sql = "SHOW TABLE STATUS LIKE 'table_name";
$result = @mysql_query($sql);
$row = @mysql_fetch_assoc($result);
$id = (int)$row['Auto_increment']; // คืนค่า id จากค่า AUTO_INCREMENT ของฐานข้อมูล
?>
วิธีที่สอง คล้ายๆกันกับวิธีแรก แต่ใช้วิธีอ่านค่าสูงสุดของ ID ออกมา เสร็จแล้ว + 1 ได้เป็น ID ใหม่นำไปใช้งานได้SELECT MAX(`id`) AS `lastid` FROM `table`
ทิป ID ที่ได้สามารถนำไปใช้กับสินค้าใหม่ได้ทันทีเหมือนกับวิธีแรกนะครับ ซึ่งวิธีนี้มีข้อดีกว่าวิธีแรกคือ เลขรหัสจะต่อเนื่องกว่าหากมีการลบข้อมูลรายการล่าสุดออกไป (ถ้ามีการลบรายการล่าสุดออก ID ที่อ่านได้ใหม่จะได้เป็น ID ที่ถูกลบออก) แต่ในกรณีอื่นๆ เลขรหัสจะไม่ได้รหัสเดิมที่ลบนะครับ อย่าสับสน
วิธีที่ 3 บันทึกข้อมูลรหัสสินค้าไว้อีกตาราง คล้ายๆวิธีแรกครับ โดยการสร้างตาราง number และเก็บข้อมูลไว้ 1 record ดังโค้ด
CREATE TABLE `table_number` (
`id` int(11) NOT NULL,
`product_no` int(11),
`order_no` int(11)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `table_number` (`id`, `product_no`, `order_no`) VALUES (1, 1, 1);
product_no ใช้เก็บ ID ของสินค้าล่าสุด
order_no ใช้เก็บ ID ของ Order ล่าสุด
ในกรณีที่มีรหัสอื่นๆอีกก็สามารถเพิ่มได้ตามที่ต้องการนะครับ
วิธีใช้ ให้อ่าน id ของรหัสที่ต้องการ ออกมาใช้งานได้เลย
SELECT `product_no` FROM `table_number` WHERE `id`=1
ผลลัพท์ที่ได้ก็จะเป็น ID ของสินค้าที่สามารถนำไปใช้ได้เลย ซึ่งหลังจากนำรหัสไปใช้งานแล้ว จะต้องกลับมาอัปเดทข้อมูลว่าใช้งานไปแล้วด้วย
UPDATE `table_number` SET `product_no`=`product_no`+1 WHERE `id`=1
คำเตือน การอ่านข้อมูล ID จากฐานข้อมูลออกมาก่อน อาจเกิดกรณีเลข ID ซ้ำได้ หากมีการอ่านข้อมูลพร้อมๆกันจากหลายๆคน (เช่นการเข้าเว็บพร้อมกัน) ซึ่งหลายๆคนชอบแนะนำให้ทำการป้องกันด้วย SELECT .... FOR UPDATE หรือ เทคนิคอื่นใดที่สามารถ ROLLBACK หรือยกเลิกการบันทึกข้อมูลได้ แต่ผมกลับไม่ชอบวิธีเหล่านี้เลยเพราะ
- เมื่อมีการใช้คำสั่ง ตารางจะถูกล๊อก (ในกรณีที่ดีหน่อยจะถูกล๊อกแค่แถว) ซึ่งมีผลให้คำสั่งต่อไป (จากบุคคลอื่น) ต้องรอ
- หากมีข้อมูลซ้ำขึ้นมาจริงๆ การบันทึกข้อมูลจะถูกยกเลิก และทำให้การบันทึกไม่สำเร็จ ซึ่งอาจมีปัญหากับผู้ใช้ เช่นในกรณ๊ที่มีผู้ใช้จำนวนมากรอคิวพร้อมๆกัน
- การตรวจสอบข้อมูลซ้ำก่อนการบันทึก อาจทำให้เกิด Query ที่ไม่จำเป็นเป็นจำนวนมากและอาจต้องรอนานขึ้น