MySQL แนวปฏิบัติที่ดี (Best Practices) ในการเขียน Stored Procedure

การเขียน Stored Procedure ไม่แค่เพื่อให้ทำงานได้เท่านั้น แต่ต้องคิดเผื่อถึงการบำรุงรักษา การแก้ไขภายหลัง และความเข้าใจของทีมพัฒนาคนอื่นด้วย

ดังนั้นเราควรมีแนวทางที่ดี หรือ Best Practices มาใช้ตั้งแต่แรก เพื่อช่วยให้ Procedure ของเรามีคุณภาพ

Best Practices ในการเขียน Stored Procedure มีดังนี้

1. ตั้งชื่อ Procedure ให้สื่อความหมาย และเป็นมาตรฐาน

ชื่อ Procedure ควรบอกให้รู้ว่า Procedure นี้ทำอะไร เช่น

  • get_customer_orders() ดึงรายการคำสั่งซื้อของลูกค้า
  • calculate_monthly_salary() คำนวณเงินเดือนประจำเดือน
  • log_user_login() บันทึกการล็อกอินของผู้ใช้

2. เขียน Comment ไว้ใน Procedure เสมอ

ไม่ว่าจะเป็น logic ที่ซับซ้อน หรือแม้แต่ชื่อพารามิเตอร์ ก็ควรเขียนคำอธิบายไว้ด้วย เช่น

SQL
-- รับ user_id เพื่อคำนวณยอดรวมคำสั่งซื้อ
CREATE PROCEDURE get_total_order(IN user_id INT)
BEGIN
  -- ประกาศตัวแปรสำหรับเก็บยอดรวม
  DECLARE total DECIMAL(10,2);

  -- ดึงยอดรวมจากตาราง orders
  SELECT SUM(amount) INTO total
  FROM orders
  WHERE customer_id = user_id;

  SELECT total AS ยอดรวม;
END;

3. อย่าเขียน Procedure ยาวเกินไป

ถ้า Procedure ของเรามีความยาวเกิน 50–100 บรรทัด ควรพิจารณา

  • แยกเป็นหลาย Procedure ย่อย ๆ
  • ย้าย Logic ซ้ำ ๆ ไปไว้ใน Function หรือ Procedure แยก

4. ใช้ตัวแปรภายในให้เป็นระบบ

  • ตั้งชื่อให้ชัด เช่น total_amount, customer_name แทนการใช้ชื่อง่าย ๆ เช่น a, x, y
  • ถ้ามีการวนลูปหลายระดับ ควรใช้ counter_1, counter_2 แยกให้ชัด

5. หลีกเลี่ยงการใช้ SELECT * ใน Procedure

การใช้ SELECT * อาจทำให้เกิดปัญหาในอนาคตเมื่อมีการเพิ่มคอลัมน์

ควรระบุคอลัมน์ที่ต้องการใช้ชัดเจน เช่น

SQL
SELECT first_name, last_name, email FROM customers;

6. ใช้ IFNULL, COALESCE และ DEFAULT เพื่อจัดการ NULL อย่างชัดเจน

เพื่อลด bug ที่อาจเกิดจาก NULL เช่น

SQL
-- ดีกว่า
SELECT IFNULL(SUM(amount), 0) INTO total;

-- หรือ
DECLARE total DECIMAL(10,2) DEFAULT 0;

7. ใช้ TRANSACTION กับ Procedure ที่มีขั้นตอนสำคัญหลายขั้นตอน

เช่น เมื่อมีการ insert หลายตารางพร้อมกัน ควรใช้ TRANSACTION

SQL
START TRANSACTION;

-- หลายคำสั่งที่เกี่ยวข้องกัน

COMMIT;
-- หรือ ROLLBACK เมื่อเกิด error

8. ควบคุมสิทธิ์การใช้งาน Procedure ด้วย GRANT EXECUTE

เพื่อไม่ให้ผู้ใช้ทั่วไปสามารถเรียก Procedure ที่มีผลกระทบต่อข้อมูลสำคัญ

อ่านเพิ่มเติมได้ในบทความ ความปลอดภัยและการจัดการสิทธิ์ของ Stored Procedure

9. สร้างระบบจัดเก็บเวอร์ชัน (Versioning)

วิธีง่าย ๆ เช่น

  • ตั้งชื่อว่า process_order_v1, process_order_v2
  • บันทึกวันที่สร้างไว้ใน comment
  • เก็บ log การเปลี่ยนแปลงไว้ในไฟล์เอกสารหรือ version control

10. ทดสอบ Procedure ก่อนใช้งานจริงทุกครั้ง

  • สร้างตารางจำลอง (sandbox) สำหรับทดสอบ
  • สร้าง test case ที่ครอบคลุมทั้งกรณีปกติและกรณีผิดพลาด
  • ทดสอบกับ NULL, ค่าว่าง, และค่าที่ไม่ควรปล่อยผ่าน
แชร์เรื่องนี้