# Kiến Trúc Multi-Tenant - Database Per Tenant

---

## Slide 1: Tổng Quan Kiến Trúc

### Mô Hình Database

**DB lms_new (Config):**
- `tenants` - Quản lý thông tin tenant
- `users` - Quản lý user admin
- `user_tenant_permissions` - Phân quyền user-tenant

**DB tenant_xxx (Business Data):**
- `tenant_icc`: students, exam_histories, courses, lessons, questions...
- `tenant_abc`: students, exam_histories, courses, lessons, questions...
- Mỗi tenant = 1 DB riêng biệt

---

## Slide 2: Sơ Đồ Luồng Hoạt Động

```mermaid
graph LR
    A[Admin Login] --> B[Chọn Tenant] --> C[Switch DB]
    S[Student Request] --> D[Detect Tenant] --> C
    C --> E[(Tenant DB)]
```

---

## Slide 3: Luồng Hoạt Động - Admin Backend

1. **Login** → Authenticate với `lms_new.users`
2. **Lấy danh sách tenant** → Query `user_tenant_permissions`
3. **Chọn tenant** → User select từ dropdown
4. **Switch DB** → Connection động đến `tenant_xxx`
5. **Thao tác** → Tất cả query đi vào DB tenant đã chọn

---

## Slide 4: Luồng Hoạt Động - Student Frontend

1. **Request** → `lcms.icanwork.vn/...`
2. **Detect tenant** → Từ header `x-tenant-code`
3. **Switch DB** → Connection động đến `tenant_xxx`
4. **Thao tác** → Query dữ liệu của tenant đó

---

## Slide 5: So Sánh 3 Mô Hình Multi-Tenant

**⚠️ Lưu ý:** Trong MySQL, Database = Schema nên DB Per Tenant = Schema Per Tenant. Trong PostgreSQL thì khác nhau.

| Tiêu Chí | **DB Per Tenant** | **Schema Per Tenant** | **Shared DB** |
|----------|-------------------|----------------------|---------------|
| **Cấu trúc** | 1 tenant = 1 DB | 1 DB, 1 tenant = 1 Schema | 1 DB chung, dùng `tenant_id` |
| **Tách biệt** | ✅ Tuyệt đối | ✅ Tốt | ⚠️ Logic |
| **Bảo mật** | ✅ Rất cao | ✅ Cao | ⚠️ Trung bình |
| **Chi phí** | ⚠️ Cao nhất | ✅ Trung bình | ✅ Thấp nhất |
| **Migration** | ⚠️ Phức tạp | ⚠️ Phức tạp | ✅ Đơn giản |
| **Customization** | ✅ Dễ nhất | ✅ Dễ | ❌ Khó |
| **Hiệu suất** | ✅ Tốt nhất (không filter, index nhỏ) | ✅ Tốt (ít bị ảnh hưởng) | ⚠️ Có thể bị ảnh hưởng (phải filter, index lớn) |
| **Cô lập lỗi** | ✅ Tuyệt đối (1 DB lỗi không ảnh hưởng tenant khác) | ⚠️ Tốt (1 schema lỗi ít ảnh hưởng, nhưng cùng DB) | ❌ Thấp (1 DB lỗi ảnh hưởng tất cả tenant) |
| **Cross-tenant** | ❌ Khó | ⚠️ Khó | ✅ Dễ |

---

## Slide 6: Mô Hình 1 - Database Per Tenant

**✅ Ưu điểm:** Tách biệt tuyệt đối, Bảo mật cao, Hiệu suất tốt nhất, Cô lập lỗi tuyệt đối (1 DB lỗi không ảnh hưởng tenant khác)

**❌ Nhược điểm:** Chi phí cao, Migration phức tạp, Quản lý phức tạp

---

## Slide 7: Mô Hình 2 - Schema Per Tenant

**Cấu trúc:** 1 DB chung, mỗi tenant = 1 Schema riêng (tenant_icc.students)

**✅ Ưu điểm:** Tách biệt tốt, Chi phí trung bình, Hiệu suất tốt, Customization dễ, 1 connection pool

**❌ Nhược điểm:** Migration phức tạp, Cross-tenant query khó, Cô lập lỗi tốt nhưng vẫn cùng DB (1 DB lỗi ảnh hưởng tất cả)

**Cách hoạt động:** `USE tenant_icc;` → Query tự động trong schema đó

**⚠️ Lưu ý MySQL vs PostgreSQL:**
- **MySQL:** Database = Schema (tương đương nhau) → DB Per Tenant = Schema Per Tenant
- **PostgreSQL:** Database ≠ Schema (khác nhau) → DB Per Tenant ≠ Schema Per Tenant

---

## Slide 8: Mô Hình 3 - Shared Database

**Cấu trúc:** 1 DB chung, tất cả bảng có `tenant_id` để phân biệt

**✅ Ưu điểm:** Chi phí thấp nhất, Migration đơn giản, Cross-tenant query dễ

**❌ Nhược điểm:** Tách biệt thấp, Rủi ro bảo mật, Hiệu suất có thể bị ảnh hưởng (phải filter tenant_id), Cô lập lỗi thấp (1 DB lỗi ảnh hưởng tất cả tenant), Khó scale, Schema chung

---

## Slide 9: Khi Nào Nên Dùng Mô Hình Nào?

**Database Per Tenant:** Bảo mật cao, compliance, white-label, budget đủ

**Schema Per Tenant:** Cần tách biệt tốt, budget hạn chế, balance cost/isolation

**Shared Database:** Nhiều tenant nhỏ, budget hạn chế, cần cross-tenant reporting

---

## Slide 10: Tóm Tắt So Sánh Nhanh

| Tiêu Chí | DB Per Tenant | Schema Per Tenant | Shared DB |
|----------|---------------|-------------------|-----------|
| **Chi phí** | ⚠️ Cao | ✅ TB | ✅ Thấp |
| **Bảo mật** | ✅ Cao | ✅ Cao | ⚠️ TB |
| **Tách biệt** | ✅ Tuyệt đối | ✅ Tốt | ⚠️ Logic |
| **Hiệu suất** | ✅ Tốt nhất | ✅ Tốt | ⚠️ TB |
| **Cô lập lỗi** | ✅ Tuyệt đối | ⚠️ Tốt | ❌ Thấp |
| **Customization** | ✅ Dễ | ✅ Dễ | ❌ Khó |
| **Cross-tenant** | ❌ Khó | ⚠️ Khó | ✅ Dễ |

---

## Slide 11: Kết Luận

**Database Per Tenant phù hợp với LMS vì:**
- ✅ Bảo mật cao (dữ liệu học sinh)
- ✅ Tách biệt tốt (mỗi tenant riêng biệt)
- ✅ Scalability (scale độc lập)
- ✅ Customization (schema riêng)

