การออกแบบสถาปัตยกรรมฐานข้อมูลสำหรับ SaaS

การตัดสินใจเรื่องฐานข้อมูลที่ผิดพลาดในช่วงสัปดาห์แรกจะตามหลอกหลอนคุณไปอีกหลายปี

ผู้ก่อตั้ง SaaS ต้องการ Schema ที่รองรับ multi-tenancy, การเรียกเก็บเงิน (billing) และการเติบโต หากคุณทำพลาด คุณจะต้องเขียนระบบใหม่ทั้งหมดภายในหกเดือน

และนี่คือวิธีสร้าง Schema ที่พร้อมใช้งานจริง (production-ready)

  1. เลือกกลยุทธ์ Tenant ของคุณ

คุณต้องแยกข้อมูลระหว่างลูกค้าออกจากกัน

• Row-level (Shared DB): ความซับซ้อนต่ำ เหมาะที่สุดสำหรับสตาร์ทอัพส่วนใหญ่ ใช้ตัวกรอง WHERE organization_id = ? ในทุกๆ query • Schema-level (Separate Schemas): ความซับซ้อนปานกลาง เหมาะสำหรับความต้องการด้านกฎระเบียบ (regulatory) • Database-level (Separate DBs): ความซับซ้อนสูง เหมาะที่สุดสำหรับลูกค้ากลุ่มองค์กร (enterprise)

สำหรับผลิตภัณฑ์ใหม่ 90% การทำ multi-tenancy แบบ row-level คือทางเลือกที่ถูกต้อง

  1. ลำดับชั้นของ Entity ที่ถูกต้อง

อย่าเรียกเก็บเงินจากผู้ใช้ (user) โดยตรง เพราะผู้ใช้มีการเข้าและออก แต่ "องค์กร" (organization) จะยังคงอยู่

ลำดับชั้นควรเป็นดังนี้: User ── MemberOf ── Organization ── Subscription ── Invoice

• Users: เก็บตารางนี้ไว้สำหรับระบุตัวตนเท่านั้น ใช้ UUID เพื่อป้องกันการโจมตี • Organizations: นี่คือขอบเขตของ tenant ของคุณ ให้เชื่อมโยง subscription เข้ากับ organization เสมอ • Memberships: ใช้ join table เพื่อเชื่อมโยง users เข้ากับ organizations และเก็บ roles ไว้ที่นี่ ไม่ใช่ในตาราง user

  1. การเรียกเก็บเงินและการสมัครสมาชิก (Billing and Subscriptions)

อย่าใช้ค่า boolean ง่ายๆ อย่าง is_active เพราะจะทำให้ข้อมูลยุ่งเหยิง

ใช้ state machine สำหรับ subscriptions โดยสถานะ (states) ที่พบบ่อย ได้แก่: • trialing • active • past_due • canceled • expired • incomplete

วิธีนี้จะช่วยให้คุณจัดการกับความล้มเหลวในการชำระเงินและระยะเวลาผ่อนผัน (grace periods) ได้โดยไม่ต้องมาตามแก้ไขข้อมูลด้วยตัวเอง

  1. เรื่องเงินและการออกใบแจ้งหนี้ (Money and Invoicing)

ปฏิบัติตามกฎที่เข้มงวดเหล่านี้เพื่อหลีกเลี่ยงข้อผิดพลาดทางการเงิน:

• อย่าใช้ FLOAT หรือ REAL สำหรับข้อมูลการเงิน ให้ใช้ integer เพื่อเก็บหน่วยเป็นเซนต์ (cents) ตัวอย่างเช่น $29.99 จะกลายเป็น 2999 • ใช้ตาราง invoice_line_items คุณจำเป็นต้องใช้ตารางนี้สำหรับการทำรายงานภาษีและการคืนเงิน (refunds) • ใช้ตาราง usage_events หากคุณเรียกเก็บเงินตามปริมาณการใช้งานผลิตภัณฑ์ของลูกค้า

  1. เคล็ดลับด้านประสิทธิภาพ (Performance Tips)

• ทำ Index ให้กับ foreign keys • ทำ Index ให้กับคอลัมน์ status • ทำ Index ให้กับคอลัมน์ timestamp • หลีกเลี่ยง N+1 queries ให้ใช้ JOIN เพื่อดึงข้อมูล organization และ subscription ในครั้งเดียว

Schema ที่ดีจะทำงานได้อย่างราบรื่นจนคุณไม่รู้สึกถึงมัน แต่หากมันล้มเหลว มันจะกลายเป็นหายนะ

จงสร้างระบบเพื่อองค์กร ใช้ state machines และเก็บข้อมูลเงินเป็น integer

Source: https://dev.to/feidou/designing-saas-database-architecture-users-organizations-subscriptions-and-billing-df

Optional learning community: https://t.me/GyaanSetuAi