SQL Academy · บทเรียน

การตรวจสอบตารางด้วยทริกเกอร์

สร้างประวัติการตรวจสอบด้วยทริกเกอร์ AFTER INSERT/UPDATE/DELETE ที่เขียนข้อมูลลงในตาราง audit_log

บทเรียน 4 จาก 414 ขั้นตอน

การตรวจสอบตารางด้วยทริกเกอร์ เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องมีการตรวจสอบ

บันทึกการตรวจสอบช่วยตอบว่า "ใครเปลี่ยนแปลงอะไร เมื่อใด" จำเป็นต่อการปฏิบัติตามข้อกำหนด (HIPAA, SOX, การสืบสวนตามสิทธิ์ในการลบข้อมูลของ GDPR) และการสืบหาสาเหตุเชิงปฏิบัติการ

ตารางตรวจสอบ

ตารางศูนย์กลางหนึ่งตารางจะบันทึกการเปลี่ยนแปลงทุกครั้ง:

CREATE TABLE audit_log (
  id BIGSERIAL PRIMARY KEY,
  ts TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  user_name TEXT NOT NULL DEFAULT CURRENT_USER,
  table_name TEXT NOT NULL,
  action TEXT NOT NULL,             -- INSERT, UPDATE, DELETE
  row_id TEXT,
  old_data JSONB,
  new_data JSONB
);

ฟังก์ชันทริกเกอร์ตรวจสอบ

ฟังก์ชันเดียวที่นำกลับมาใช้ซ้ำได้กับหลายตาราง:

CREATE OR REPLACE FUNCTION audit_row()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO audit_log (table_name, action, row_id, old_data, new_data)
  VALUES (
    TG_TABLE_NAME,
    TG_OP,
    COALESCE(NEW.id::TEXT, OLD.id::TEXT),
    CASE WHEN TG_OP IN ('UPDATE','DELETE') THEN to_jsonb(OLD) END,
    CASE WHEN TG_OP IN ('INSERT','UPDATE') THEN to_jsonb(NEW) END
  );
  RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;

แนบทริกเกอร์กับตาราง

สร้างทริกเกอร์เมื่อ AFTER INSERT/UPDATE/DELETE:

CREATE TRIGGER trg_audit_users
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION audit_row();

to_jsonb(NEW)

เทคนิค to_jsonb จะจับภาพทั้งแถวแบบทั่วไป โดยไม่ต้องเขียนโค้ดแยกตามคอลัมน์ ใช้ได้กับทุกตารางที่มีคอลัมน์ id

ติดตามผู้กระทำ

หากแอปทำงานโดยใช้ผู้ใช้ฐานข้อมูลรายเดียว CURRENT_USER ก็ไม่เพียงพอ ให้ส่งผู้ใช้ของแอปผ่าน GUC ของเซสชัน:

-- App sets:
SET LOCAL app.user_id = '42';

-- Trigger reads:
INSERT INTO audit_log (... actor_id ...) VALUES (..., current_setting('app.user_id', true)::BIGINT);

ตรวจสอบคอลัมน์เฉพาะ

ใช้ส่วนคำสั่ง WHEN ของทริกเกอร์เพื่อเลือกตรวจสอบเฉพาะกรณี:

CREATE TRIGGER trg_audit_role_change
AFTER UPDATE OF role ON users
FOR EACH ROW WHEN (OLD.role IS DISTINCT FROM NEW.role)
EXECUTE FUNCTION audit_role_change();

ตารางตรวจสอบแยกตามตาราง

อีกทางเลือกหนึ่งคือสร้างตารางตรวจสอบหนึ่งตารางต่อตารางจริง เช่น users_audit โดยใช้โครงสร้างเดียวกันพร้อมข้อมูลเมตาสำหรับตรวจสอบ สอบถามได้ง่ายกว่า แต่ต้องดูแล DDL มากขึ้น

ตรวจสอบเฉพาะส่วนต่าง

จัดเก็บเฉพาะคอลัมน์ที่เปลี่ยนแปลง:

INSERT INTO audit_log (table_name, action, changes)
VALUES (
  TG_TABLE_NAME, TG_OP,
  (SELECT jsonb_object_agg(key, value)
   FROM jsonb_each(to_jsonb(NEW))
   WHERE NEW.* IS DISTINCT FROM OLD.* AND to_jsonb(NEW)->key IS DISTINCT FROM to_jsonb(OLD)->key)
);

ประสิทธิภาพของตารางตรวจสอบ

ตารางตรวจสอบจะเติบโตอย่างรวดเร็วในระบบที่มีการใช้งานสูง ให้แบ่งพาร์ทิชันตามเวลา:

CREATE TABLE audit_log (...) PARTITION BY RANGE (ts);
CREATE TABLE audit_log_2024_q1 PARTITION OF audit_log
  FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');

ข้อแลกเปลี่ยนด้านประสิทธิภาพ

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

กรณีที่ไม่ควรใช้ทริกเกอร์ฐานข้อมูล

หากคุณต้องเชื่อมต่อกับบัสเหตุการณ์ จัดคิวเหตุการณ์ด้วย NOTIFY หรือ LISTEN หรือใช้เครื่องมือการจำลองแบบเชิงตรรกะ / CDC (Debezium) แทนทริกเกอร์

สรุป

ทริกเกอร์ตรวจสอบเป็นวิธีที่ง่ายที่สุดในการบันทึกประวัติ

  • ใช้ฟังก์ชันทั่วไปหนึ่งฟังก์ชันร่วมกับ to_jsonb(NEW/OLD)
  • แนบฟังก์ชันกับทุกตารางที่ต้องตรวจสอบ
  • แบ่งพาร์ทิชันตารางตรวจสอบตามเวลา
  • ติดตามผู้กระทำของแอปอย่างชัดเจนผ่าน GUC

ตรวจสอบอย่างรวดเร็ว

ภายในฟังก์ชันทริกเกอร์ตรวจสอบ คุณจะจับแถวใหม่เป็น JSONB แบบทั่วไปได้อย่างไร?

เริ่มต้นได้ฟรี

เรียนรู้ SQL ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
46
บทเรียน
183

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

บทเรียน “การตรวจสอบตารางด้วยทริกเกอร์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การตรวจสอบตารางด้วยทริกเกอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การตรวจสอบตารางด้วยทริกเกอร์”

สร้างประวัติการตรวจสอบด้วยทริกเกอร์ AFTER INSERT/UPDATE/DELETE ที่เขียนข้อมูลลงในตาราง audit_log คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การตรวจสอบตารางด้วยทริกเกอร์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม

ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้างทริกเกอร์: BEFORE/AFTER, FOR EACH ROW
  2. พื้นฐานฟังก์ชัน PL/pgSQL
  3. บล็อก DO และโค้ดนิรนาม
  4. การตรวจสอบตารางด้วยทริกเกอร์
← กลับไปที่ SQL Academy