VietERP Platform sử dụng PostgreSQL 16 làm hệ thống quản lý cơ sở dữ liệu chính, với Prisma ORM làm lớp trích xuất dữ liệu. Kiến trúc cơ sở dữ liệu được thiết kế hỗ trợ đa tenant, đa module và mở rộng theo kiểu enterprise.
VietERP Platform uses PostgreSQL 16 as the primary database management system, with Prisma ORM as the data abstraction layer. The database architecture is designed to support multi-tenancy, multiple modules, and enterprise-scale expansion.
- PostgreSQL 16+ — Relational database
- Prisma 5.0+ — ORM and migration management
- Node.js 18+ — Runtime for migration scripts
- npm/yarn — Package management
VietERP sử dụng mô hình một schema cho một module, cho phép:
- Tách biệt logic nghiệp vụ rõ ràng
- Quản lý phiên bản schema độc lập
- Giảm xung đột merge khi phát triển song song
- Dễ dàng kiểm tra schema-specific
VietERP uses a one schema per module model, enabling:
- Clear business logic separation
- Independent schema versioning
- Reduced merge conflicts in parallel development
- Easy schema-specific testing
| Module | Schema | Chủ yếu / Primary Entities |
|---|---|---|
| Shared / Master Data | public |
Tenants, Users, Customers, Products, Employees, Suppliers, Warehouses |
| Accounting | accounting |
Accounts, JournalEntries, Invoices, Tax Declarations, Bank Transactions |
| CRM | crm |
Leads, Contacts, Accounts, Opportunities, Activities, Campaigns |
| Ecommerce | ecommerce |
Products, Categories, Orders, Carts, Payments, Shipping |
| HRM | hrm |
Employees, Departments, Positions, Attendance, Payroll, Leaves |
| MRP | mrp |
BOM, ProductionOrders, QualityChecks, Inventory, Machines |
Mỗi module có file prisma/schema.prisma riêng:
- packages/database/prisma/schema.prisma — Shared master data
- apps/Accounting/prisma/schema.prisma — Accounting module schema
- apps/CRM/prisma/schema.prisma — CRM module schema
- Tương tự cho các module khác / Similar for other modules
# Thiết lập DATABASE_URL trong .env
# Set DATABASE_URL in .env
export DATABASE_URL="postgresql://user:password@localhost:5432/vierp_db"
# Tạo Prisma client
npx prisma generate- Type-safe queries — Full TypeScript support
- Migrations — Version-controlled schema changes
- Seeding — Populate test data
- Query optimization — Built-in relationship loading
- SQL injection prevention — Parameterized queries automatically
# Tạo migration từ thay đổi schema
npx prisma migrate dev --name add_feature_name
# Ví dụ / Example:
npx prisma migrate dev --name add_customer_segmentsCâu lệnh này:
- Kiểm tra sự thay đổi schema (
schema.prisma) - Tạo file SQL migration trong
prisma/migrations/ - Áp dụng migration vào development database
- Tạo lại Prisma client
Development Environment:
npx prisma migrate devStaging/Production Environment:
# Không tương tác / Non-interactive
npx prisma migrate deployKiểm tra status migration / Check Migration Status:
npx prisma migrate statusDevelopment:
# Hoàn tác migration cuối cùng (không được áp dụng thực tế)
npx prisma migrate resolve --rolled-back migration_nameProduction: Không có built-in rollback — phải tạo migration inverse thủ công.
- Tên migration rõ ràng —
add_customer_segments,rename_order_status, không phảiupdate - Migration nhỏ — Một thay đổi logic trên một migration
- Kiểm thử migration — Chạy trên staging trước production
- Giữ .sql files — Không xoá thư mục
migrations/ - Mô tả thay đổi — Thêm comment trong SQL migration
- Không chỉnh schema trực tiếp — Luôn tạo migration, không chỉnh production database
Tạo prisma/seed.ts:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// Tạo dữ liệu test / Create test data
const tenant = await prisma.tenant.create({
data: {
name: 'Demo Tenant',
slug: 'demo-tenant',
},
});
console.log(`Seeded tenant: ${tenant.id}`);
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});npx prisma db seedpackage.json:
{
"prisma": {
"seed": "ts-node prisma/seed.ts"
}
}# Full backup
pg_dump -U postgres -d vierp_db -f backup_$(date +%Y%m%d_%H%M%S).sql
# Custom format (nén) / Compressed format
pg_dump -U postgres -d vierp_db -F c -f backup_$(date +%Y%m%d_%H%M%S).dump# Từ SQL dump / From SQL dump
psql -U postgres -d vierp_db -f backup_20260329_120000.sql
# Từ custom format / From custom format
pg_restore -U postgres -d vierp_db backup_20260329_120000.dumpSử dụng cron job:
# Mỗi ngày lúc 2 AM
0 2 * * * pg_dump -U postgres vierp_db | gzip > /backups/vierp_$(date +\%Y\%m\%d).sql.gzCác index hiện có / Existing indexes:
tenantId— Multi-tenant queriesstatusfields — Filter operationscreatedAt— Time-based sorting- Foreign keys — Relationship lookups
Thêm index tuỳ chỉnh / Custom indexes:
model Account {
id String @id @default(cuid())
accountNumber String
tenantId String
@@unique([accountNumber, tenantId]) // Unique constraint
@@index([tenantId, status]) // Composite index for filtering
}- Sử dụng include/select để tránh N+1 queries
- Batch queries khi có thể
- Sử dụng
$queryRawcho các query phức tạp - Limit results với pagination
// ❌ Bad: N+1 queries
const accounts = await prisma.account.findMany();
for (const account of accounts) {
const lines = await prisma.journalLine.findMany({
where: { accountId: account.id },
});
}
// ✅ Good: Include relationship
const accounts = await prisma.account.findMany({
include: { journalLines: true },
});Prisma sử dụng connection pooling built-in. Cấu hình trong .env:
DATABASE_URL="postgresql://user:pass@localhost:5432/vierp_db?schema=public"
# Pool size (default: 2 for development, 10 for production)
# Prisma tự động điều chỉnh / Prisma auto-adjusts
- Parameterized queries — Prisma sử dụng tự động
- Role-based access — PostgreSQL roles cho mỗi application user
- Encryption at rest — Cấu hình ở database server level
- Audit logs — Tất cả thay đổi được ghi lại
- Least privilege — Application user chỉ có quyền cần thiết
-- Tạo application user
CREATE USER vierp_app WITH PASSWORD 'secure_password';
-- Grant rights
GRANT CONNECT ON DATABASE vierp_db TO vierp_app;
GRANT USAGE ON SCHEMA public TO vierp_app;
GRANT ALL ON ALL TABLES IN SCHEMA public TO vierp_app;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO vierp_app;- Query performance — Slow query log
- Connection count — Active connections
- Disk space — Database size
- Replication lag — If using replication
-- Kích thước database / Database size
SELECT pg_database.datname,
pg_size_pretty(pg_database_size(pg_database.datname)) AS size
FROM pg_database
WHERE datname LIKE 'vierp%';
-- Active queries / Active queries
SELECT pid, usename, application_name, state, query
FROM pg_stat_activity
WHERE state != 'idle';
-- Table sizes / Table sizes
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;- Database Schemas — Chi tiết từng module schema
- ER Diagram — Biểu đồ thực thể quan hệ
- Migration Guide — Hướng dẫn migration chi tiết
Nếu có câu hỏi về cơ sở dữ liệu, vui lòng mở GitHub Discussion hoặc tạo issue.
For database questions, please open a GitHub Discussion or create an issue.