PlusMagi's Blog By Pitt Phunsanit Database ล้างข้อมูลลบทุกตารางในฐานข้อมูล

ล้างข้อมูลลบทุกตารางในฐานข้อมูล

ในการพัฒนาระบบฐานข้อมูล (Database Development) บ่อยครั้งที่เราจำเป็นต้องรีเซ็ตสภาพแวดล้อมการทำงานทั้งหมด เพื่อให้แน่ใจว่าโค้ดที่กำลังทดสอบนั้นสะอาด ไม่มีข้อมูลเก่ามาปะปน ซึ่งกระบวนการนี้เรียกว่าการ ‘ล้างข้อมูล’ หรือ ‘Reset Database’

สำหรับผู้ที่ใช้ SQL Server อาจคุ้นเคยกับการวนลูปคำสั่ง แต่เมื่อเราเปลี่ยนมาใช้ PostgreSQL เราจำเป็นต้องใช้วิธีการที่ทรงพลังและยืดหยุ่นกว่า นั่นคือการสร้าง Dynamic SQL เพื่อจัดการกับตารางทั้งหมดใน Schema ที่ต้องการได้อย่างมีประสิทธิภาพ

💡 ทำไมต้อง Truncate แทน Delete?

ก่อนที่เราจะลงมือล้างข้อมูล เราควรทำความเข้าใจความแตกต่างระหว่างคำสั่ง DELETE FROM และ TRUNCATE TABLE ก่อน:

  • DELETE FROM table_name;: จะทำการลบแถว (Row) ทีละรายการ ทำให้ใช้ทรัพยากรสูงกว่าและช้ากว่า นอกจากนี้ยังคงบันทึก Log การทำธุรกรรมไว้
  • TRUNCATE TABLE table_name;: เป็นคำสั่งที่ถูกออกแบบมาเพื่อล้างข้อมูลทั้งหมดในตารางอย่างรวดเร็วที่สุด (Fastest way to empty a table) และที่สำคัญคือ มันจะรีเซ็ต Sequence/Identity Column ให้กลับไปเริ่มต้นที่ 1 เสมอ ซึ่งเหมาะกับการทำ Development Environment มากกว่า

⚙️ การล้างข้อมูลทุกตารางใน PostgreSQL ด้วย Dynamic SQL

เนื่องจาก PostgreSQL ไม่มีคำสั่งสำเร็จรูปในการวนลูปและรัน TRUNCATE ทุกตารางโดยอัตโนมัติ เราจึงต้องใช้เทคนิคการ Query ข้อมูล Metadata (Schema) และสร้างชุดคำสั่ง SQL แบบไดนามิก (Dynamic SQL) ขึ้นมาเอง

เราจะดึงรายชื่อตารางทั้งหมดจาก information_schema.tables แล้วนำชื่อเหล่านั้นมาประกอบเป็นคำสั่ง TRUNCATE TABLE table_name CASCADE; โดยการใช้ฟังก์ชันของ PostgreSQL เช่น string_agg() และ format()

ตัวอย่างโค้ด: การสร้างชุดคำสั่ง Truncate ทั้งหมด

โค้ดนี้จะรวบรวมชื่อตารางทั้งหมดใน Schema ปัจจุบัน (public) แล้วสร้างเป็นสตริงของคำสั่ง TRUNCATE TABLE ... ที่พร้อมใช้งาน:

SQL

SELECT string_agg(format('TRUNCATE TABLE %I CASCADE;', table_name), ';
') AS truncate_commands FROM information_schema.tables WHERE table_schema = current_schema() AND table_type = 'BASE TABLE';

คำอธิบายโค้ด:

  • information_schema.tables: คือแหล่งข้อมูลที่เก็บ Metadata ของฐานข้อมูล
  • WHERE table_schema = current_schema(): จำกัดขอบเขตให้เหลือเฉพาะ Schema ปัจจุบัน (เช่น ‘public’) เพื่อป้องกันการลบตารางจาก Schema อื่นโดยไม่ตั้งใจ
  • string_agg(..., ';\n'): ทำหน้าที่รวมชื่อตารางทั้งหมดที่ได้มา ให้กลายเป็นข้อความยาวๆ ที่มีคำสั่ง TRUNCATE TABLE ...; คั่นอยู่

⚠️ ข้อควรระวังและขั้นตอนการใช้งาน (Best Practice)

เนื่องจากการรัน Dynamic SQL นี้เป็นการดำเนินการที่มีผลกระทบสูงต่อข้อมูลทั้งหมดในฐานข้อมูล จึงต้องทำด้วยความระมัดระวังสูงสุดเสมอ:

  1. ใช้ Transaction Block: ควรห่อคำสั่งทั้งหมดไว้ใน BEGIN; ... COMMIT; เพื่อให้สามารถ Rollback ได้หากเกิดข้อผิดพลาด
  2. ทดสอบบน Staging Environment เท่านั้น: ห้ามรันโค้ดนี้กับ Production Database โดยเด็ดขาด
  3. การใช้ CASCADE: การเพิ่มคำว่า CASCADE หลังชื่อตาราง (เช่น TRUNCATE TABLE table_name CASCADE;) มีความสำคัญมาก เพราะมันจะล้างข้อมูลในตารางที่ถูกอ้างอิง (Foreign Key) ไปยังตารางหลักโดยอัตโนมัติ ทำให้การรีเซ็ตฐานข้อมูลสมบูรณ์ยิ่งขึ้น

✅ สรุป

การใช้ Dynamic SQL ร่วมกับ information_schema เป็นวิธีมาตรฐานและมีประสิทธิภาพที่สุดในการล้างข้อมูลทั้งหมดใน PostgreSQL เพื่อให้แน่ใจว่าสภาพแวดล้อมการพัฒนาของคุณสะอาดพร้อมสำหรับการทดสอบครั้งใหม่เสมอ เพียงจำไว้ว่าความเร็วและความปลอดภัยต้องมาก่อนเสมอเมื่อจัดการกับโครงสร้างฐานข้อมูลขนาดใหญ่