Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL Trigger: Insert Row เข้าอีกตารางเมื่อมีการ Insert (Audit Log Pattern)

ใช้ AFTER INSERT TRIGGER เพื่อ Insert ข้อมูลเข้าตารางอื่นอัตโนมัติเมื่อมีการ Insert (เหมาะสำหรับ Audit Log, Replication, Denormalization)

ตัวอย่าง: Sync Table1 → Table2

1. สร้างตาราง

CREATE TABLE Table1 (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Table2 (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

2. สร้าง Trigger

DELIMITER //
CREATE TRIGGER Table1Trigger
AFTER INSERT ON Table1
FOR EACH ROW
BEGIN
    INSERT INTO Table2 (id, name) VALUES (NEW.id, NEW.name);
END //
DELIMITER ;

3. ทดสอบ

INSERT INTO Table1 VALUES (1, 'John'), (2, 'Smith'), (3, 'Carol');

SELECT * FROM Table1;
+----+-------+
| id | name  |
+----+-------+
| 1  | John  |
| 2  | Smith |
| 3  | Carol |
+----+-------+

SELECT * FROM Table2;
+----+-------+
| id | name  |
+----+-------+
| 1  | John  |
| 2  | Smith |
| 3  | Carol |
+----+-------+

Trigger Types และ NEW/OLD

Trigger TimeEventNEWOLDใช้เมื่อไหร่
BEFOREINSERT✅❌Validate/Modify ก่อน Insert
AFTERINSERT✅❌Action หลัง Insert (Log, Sync)
BEFOREUPDATE✅✅Validate/Modify ก่อน Update
AFTERUPDATE✅✅Action หลัง Update (Audit)
BEFOREDELETE❌✅Validate/Archive ก่อน Delete
AFTERDELETE❌✅Action หลัง Delete (Log)

ตัวอย่าง Audit Log Table (Best Practice)

CREATE TABLE audit_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    table_name VARCHAR(64),
    operation ENUM('INSERT','UPDATE','DELETE'),
    old_data JSON,
    new_data JSON,
    changed_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6),
    changed_by VARCHAR(100),
    INDEX idx_table_op (table_name, operation)
);

-- Trigger สำหรับ UPDATE
CREATE TRIGGER users_audit_update
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
    INSERT INTO audit_log (table_name, operation, old_data, new_data, changed_by)
    VALUES (
        'users', 'UPDATE',
        JSON_OBJECT('id', OLD.id, 'name', OLD.name, 'email', OLD.email),
        JSON_OBJECT('id', NEW.id, 'name', NEW.name, 'email', NEW.email),
        CURRENT_USER()
    );
END;

⚠️ ข้อควรระวัง

  • Trigger รันใน Transaction เดียวกับ Statement ต้นทาง (Rollback = Trigger Rollback)
  • Performance: Trigger เพิ่ม Latency ต่อ Row (Batch Insert = Trigger รันหลายครั้ง)
  • Recursive Trigger: Trigger ใน Table2 Insert กลับ Table1 → Infinite Loop (MySQL ป้องกันบางส่วน)
  • ไม่ทำงานกับ LOAD DATA INFILE (บาง Version), REPLACE, TRUNCATE
  • Debug ยาก: ใช้ SHOW TRIGGERS, Error Log

ดู Triggers ที่มีอยู่

SHOW TRIGGERS;
SHOW CREATE TRIGGER Table1Trigger;