PlusMagi's Blog By Pitt Phunsanit Backend,Database สร้าง muti site ใน laravel

สร้าง muti site ใน laravel

การพัฒนาระบบ Multi-Site หรือ Multi-Tenancy คือการสร้างแพลตฟอร์มเดียวที่สามารถรองรับลูกค้าหรือบริษัทจำนวนมาก (Tenants) โดยที่แต่ละบริษัทจะถูกแยกข้อมูลออกจากกันอย่างสมบูรณ์ แต่ยังคงใช้โค้ดเบส (Codebase) และโครงสร้างพื้นฐานเดียวกัน

ในฐานะ Senior Architect เราแนะนำให้ใช้ PostgreSQL เป็นฐานข้อมูลหลัก เนื่องจาก PostgreSQL มีความสามารถในการจัดการ Schema และ Data Integrity ที่ยอดเยี่ยม ทำให้เหมาะอย่างยิ่งสำหรับการออกแบบระบบ Multi-Tenancy ที่ต้องการความปลอดภัยในการแยกข้อมูลสูง

หลักการ Multi-Tenancy ด้วย PostgreSQL

แทนที่จะใช้การสร้าง Schema แยกสำหรับทุกบริษัท (Schema per Tenant) ซึ่งอาจซับซ้อนในการจัดการเมื่อจำนวนบริษัทเพิ่มขึ้น เราจะใช้แนวทางที่เรียกว่า Shared Schema with Tenant ID โดยการเพิ่มคอลัมน์ tenant_id เข้าไปในทุกตารางข้อมูลหลัก เพื่อระบุว่าข้อมูลแถวนั้นๆ เป็นของบริษัทใด

ขั้นตอนที่ 1: การออกแบบ Schema ด้วย PostgreSQL

เราต้องมั่นใจว่าตารางข้อมูลหลักทุกตารางมีคอลัมน์ tenant_id เพื่อให้ Laravel สามารถกรองข้อมูลได้อย่างถูกต้องตามบริษัทที่ล็อกอินอยู่

SQL

-- สร้างตารางข้อมูลหลักที่รองรับ Multi-Tenancy<br>CREATE TABLE products ( <br>    id SERIAL PRIMARY KEY, <br>    tenant_id UUID NOT NULL, <br>    product_name VARCHAR(255) NOT NULL, <br>    sku VARCHAR(50) UNIQUE, <br>    price NUMERIC(10, 2) <br>    -- เพิ่ม Index เพื่อเร่งความเร็วในการค้นหาตาม Tenant ID<br>    );<br>CREATE INDEX idx_tenant_id ON products (tenant_id);

ขั้นตอนที่ 2: การจัดการข้อมูลและการแยก Tenant

เมื่อ Laravel ทำงานกับ PostgreSQL เราจะต้องมั่นใจว่าทุกคำสั่ง Query จะมีการใส่เงื่อนไข WHERE tenant_id = :current_tenant_id เสมอ เพื่อป้องกันการรั่วไหลของข้อมูล (Data Leakage) ระหว่างบริษัท

ตัวอย่างการเพิ่มข้อมูล (Insert) สำหรับ Tenant A และ Tenant B:

SQL

-- สมมติว่า Tenant A มี UUID: 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'<br>INSERT INTO products (tenant_id, product_name, sku, price) <br>VALUES ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'apple', 'A101', 1.00);<br><br>-- ข้อมูลของ Tenant B<br>INSERT INTO products (tenant_id, product_name, sku, price) <br>VALUES ('b0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22', 'banana', 'B202', 0.50);

ตัวอย่างการดึงข้อมูล (Select) สำหรับ Tenant A เท่านั้น:

SQL

SELECT * FROM products <br>WHERE tenant_id = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11' <br>AND product_name = 'apple';

การผสานรวมใน Laravel (Laravel Integration)

ในระดับ Laravel เราจะใช้ Middleware หรือ Scope เพื่อดักจับ tenant_id จากผู้ใช้ที่ล็อกอิน และทำการผูกค่านี้เข้ากับทุก Query ที่ส่งไปยัง PostgreSQL โดยอัตโนมัติ ทำให้โค้ดส่วน Business Logic ไม่ต้องกังวลเรื่องการใส่เงื่อนไข WHERE tenant_id ซ้ำๆ

บทสรุป

การใช้ PostgreSQL ร่วมกับแนวคิด Shared Schema & Tenant ID ใน Laravel เป็นวิธีที่ทรงพลังและปลอดภัยในการสร้างระบบ Multi-Site ที่ขยายตัวได้ง่าย (Scalable) และสามารถรองรับการเติบโตของลูกค้าได้ในระยะยาว สิ่งสำคัญที่สุดคือการบังคับใช้การกรองข้อมูลด้วย tenant_id ในทุกระดับของการเข้าถึงข้อมูลเพื่อรักษาความปลอดภัยของข้อมูลลูกค้าแต่ละราย