เห็นใน feed มีพูดคุยเรื่องการ soft delete ข้อมูลใน database
ซึ่งคำถามแรกที่เกิดขึ้นมาคือ soft delete มันคืออะไร ?
คำตอบคือ การไม่ลบข้อมูลจริง ๆ
แต่ทำการ update ให้มี status=delete ไป
แล้วตอนดึงข้อมูลก็ใช้ where clause นั่นเอง
แต่ว่าวิธีการนี้มีปัญหาอะไรที่ควรต้องรู้ไว้นิดหน่อย ?

ปล. เป็นวิธีการพื้นฐานที่ผมพอรู้บ้างนะครับ อาจจะผิดบ้างถูกบ้าง !!

ถ้าข้อมูลไม่เยอะ ผู้ใช้งานไม่มาก
index ไม่ใหญ่ ความสัมพันธ์ของ table ไม่สูง
จะทำแบบไหนก็ทำไป เพราะว่ามัน work อยู่แล้ว

แต่เมื่อมีข้อมูลมากยิ่งขึ้น ผู้ใช้งานสูงขึ้น จำเป็นต้องพึงระวังไว้ด้วย

ยกตัวอย่างเช่น การจัดการข้อมูลใน PostgreSQL database นั้น
การ update ข้อมูลนั้น จะมี 2 operation เกิดขึ้นคือ

  • ทำการ insert row ใน version ใหม่เข้ามา
  • ทำการลบ row ใน version เก่า (dead row)

ซึ่งนำมาสู่การ re-index ของ table ที่เกี่ยวข้อง
นั่นคือ operation cost ที่เกิดขึ้นมา สูงใช้ได้เลย !!
ดังนั้น นี่คือความรู้พื้นฐานที่ควรรู้ในแต่ละ database

ดังนั้นเรื่องแรกที่ควรต้องทำคือ การจัดการ index ให้เล็ก ทำงานเร็ว และ cache ใน memory
เช่นจากการใช้งาน full index มาออกแบบเพิ่มเติมและใช้งาน partial index กันสักหน่อย
จากนั้นใน PostgreSQL ต้องทำการ config เรื่อง Autovacuum อีกด้วย
ดังนั้นถ้ามีการ update เยอะ ๆ จะเกิด dead row/tuple เยอะ
เมื่อ Autovacuum ทำงานแบบปกติเพื่อเอา disk กลับคืนมา
อาจจะทำงานเยอะเกินไป แถมทำให้ database มีปัญหาอีก

หรือถ้ามีข้อมูลมาก ๆ สามารถแยก data ที่ถูก delete
ไปไว้ยัง partition อื่น จากนั้นก็ prune หรือ ลบทิ้งทั้ง partition ไป
ก็ช่วยลดปัญหาลงไปได้เยอะ

แต่เห็นว่ามีการใช้งาน trigger ใน database ด้วย ตรงนี้ก็ใช้อย่างระมัดระวัง !!

มันคือการเพิ่มภาระงานให้กับ database เข้าไปอีก
คาดเดาการทำงานได้ยากมาก ๆ
ถ้าจริง ๆ ไม่อยากแนะนำให้ใช้งานนะครับ

หรืออาจจะใช้ view/material view มาใช้ก็ได้
หรือเขียน store procedure ก็ว่ากันไป

มาถึงตรงนี้จะพบว่า การ update ข้อมูล เป็นการเพิ่มภาระงานให้ database อย่างมาก
อีกทั้งระวังอาจจะเกิด deadlock จากการทำงานได้อีก !!

แต่ถ้าถามว่ามีวิธีการอื่น ๆ อีกหรือไม่ สำหรับการจัดการปัญหาเหล่านี้

คำตอบคือ มี แต่จะเพิ่มความซับซ้อนของระบบมากยิ่งขึ้น
ดังนั้นก็ต้องดูด้วยว่าระบบของเรามีความต้องการอย่างไรบ้าง ?

วิธีการที่อาจจะใช้งาน เช่น

  • ทำการออกแบบแบบ append-only log หรือ immutable คือ ทำการ insert อย่างเดียว เพื่อลด overhead ต่าง ๆ ลงไป แต่ต้องคิดในมุมมองของการดึงข้อมูล (Read) ด้วย
  • ทำการออกแบบแยก Read และ Write ออกจากกัน หรือ CQRS (Command Query Responsibility Segregation)
  • นำเอาพวก Event-based architecture เข้ามาช่วยก็ได้
  • บางคนก็ใช้พวก CDC (Change Data Capture) มาช่วย
  • จัดการในระดับ application ได้ เช่น caching และ messaging เป็นต้น

แต่ไม่ว่าวิธีการอะไร ก็ย้อนกลับไปที่ความต้องการของระบบงานว่าเป็นอย่างไร

ปัญหาที่พบเจอเป็นอย่างไร
มีระบบ monitoring app และ database ที่ดีไหม
ทำ house keeping กันหรือยัง
ยิ่ง data เยอะขึ้น ระบบกลับช้าลงเรื่อย ๆ ไหม
จากนั้นจึงเลือกวิธีการ ที่เหมาะสมกับปัญหาของคุณนั่นเอง

สุดท้ายอย่าลืมทำ performance testing ด้วยละครับ
เราคงไม่ใช่คนจริงใช่ไหม ที่ไปทดสอบน production กันเลย (เพราะว่าไม่มีที่ไหนจริงเท่า production กันแล้ว)