![]()
Khi thiết kế các kiến trúc cơ sở dữ liệu mạnh mẽ cho các lĩnh vực phức tạp như ngành lưu trú, việc trực quan hóa các mối quan hệ một cách rõ ràng là điều then chốt. Dù bạn đang lập bản đồ hồ sơ khách hàng, theo dõi tồn kho phòng hay quản lý hóa đơn, một sơ đồ quan hệ thực thể (ERD) được cấu trúc tốt sẽ tiết kiệm hàng trăm giờ trong quá trình phát triển. Trong buổi học chuyên sâu này, tôi sẽ dẫn bạn từng bước cách tôi xây dựng sơ đồ ERD quản lý khách sạn toàn diện từ đầu bằng PlantUML bên trongtrình soạn thảo PlantUML miễn phí, VPasCode.

1. Khởi tạo môi trường PlantUML
Tôi bắt đầu bằng việc thiết lập cấu trúc nền tảng cho đoạn mã. Khi làm việc với các lược đồ phức tạp chứa nhiều thuộc tính, tính dễ đọc của bố cục là điều then chốt. Tôi cấu hình PlantUML để ẩn những phần lộn xộn không cần thiết và tối ưu hóa hướng bố cục sơ đồ:
@startuml
title Sơ đồ quan hệ thực thể quản lý khách sạn
ẩn hình tròn
hướng trái sang phải
Tại sao lại dùng cách tiếp cận này?Ẩn các hình tròn thuộc tính mặc định giúp các hộp thực thể trở nên gọn gàng và hiện đại hơn. Thiết lập hướng thànhhướng trái sang phảigiúp ngăn chặn các sơ đồ ERD rộng trở nên không thể quản lý theo chiều dọc, đồng thời phân bố hợp lý các mối quan hệ giữa nhiều bảng.
2. Xác định các thực thể cốt lõi và thuộc tính
Tiếp theo, tôi cần xác định các thực thể cốt lõi đại diện cho lĩnh vực kinh doanh của chúng ta. Tôi cấu trúc từng thực thể với khóa chính, ràng buộc duy nhất và các thuộc tính có kiểu dữ liệu. Hãy cùng xem cách tôi thiết lập các thực thể cốt lõiKhách hàng và Loại phòng các thực thể:
thực thể "Khách hàng" as kháchhang {
* customer_id : UUID <<PK>>
--
first_name : VARCHAR(50)
last_name : VARCHAR(50)
email : VARCHAR(100) <<UK>>
phone : VARCHAR(20)
address : TEXT
loyalty_points : INTEGER
total_stays : INTEGER
date_registered : TIMESTAMP
date_of_birth : DATE
nationality : VARCHAR(50)
}
thực thể "Loại phòng" as loaiphong {
* room_type_id : UUID <<PK>>
--
type_name : VARCHAR(50) <<UK>>
description : TEXT
standard_capacity : INTEGER
base_price : DECIMAL(10,2)
extra_bed_charge : DECIMAL(10,2)
has_kitchenette : BOOLEAN
has_balcony : BOOLEAN
}
Bằng cách xác định các dấu hiệu rõ ràng như<<PK>> và <<UK>>, bất kỳ ai xem xét mã nguồn đều có thể hiểu ngay lập tức về quy tắc chỉ mục và duy nhất trước khi các kịch bản di chuyển cơ sở dữ liệu được viết ra.
3. Bản đồ hóa các thực thể vận hành (Phòng, Đặt phòng và Nhân viên)
Với dữ liệu tham chiếu đã được thiết lập, tôi chuyển sang phần cốt lõi giao dịch của hệ thống quản lý khách sạn: phòng, đặt phòng và quy trình làm việc của nhân viên. Mỗi thực thể đều liên kết trở lại các bảng nền tảng thông qua khóa ngoại:
thực thể "Phòng" as phong {
* room_id : UUID <<PK>>
--
room_number : VARCHAR(10) <<UK>>
floor_number : INTEGER
room_type_id : UUID <<FK>>
capacity : INTEGER
base_price : DECIMAL(10,2)
is_available : BOOLEAN
has_view : BOOLEAN
square_feet : INTEGER
last_renovated : DATE
}
thực thể "Đặt phòng" as datphong {
* reservation_id : UUID <<PK>>
--
customer_id : UUID <<FK>>
room_id : UUID <<FK>>
check_in_date : DATE
check_out_date : DATE
number_of_guests : INTEGER
total_amount : DECIMAL(10,2)
status : VARCHAR(20)
special_requests : TEXT
created_at : TIMESTAMP
updated_at : TIMESTAMP
confirmation_code : VARCHAR(20) <<UK>>
}
4. Thiết lập các mối quan hệ tài chính và dịch vụ
Để hoàn thiện kiến trúc, tôi vẽ ra các hồ sơ hóa đơn (Thanh toán và Hóa đơn) cùng với các dịch vụ phụ trợ như Dịch vụ phòng do nhân viên khách sạn xử lý. Để kết nối tất cả lại với nhau, tôi xác định rõ ràng tính bội số bằng ký hiệu chuẩn của PlantUML:
' Mối quan hệ
customer ||--o{ reservation : "tạo ra"
room ||--o{ reservation : "được gán cho"
reservation ||--|| payment : "có"
reservation ||--|| invoice : "tạo ra"
reservation ||--o{ roomservice : "yêu cầu"
staff ||--o{ roomservice : "thực hiện"
roomtype ||--o{ room : "phân loại"
@enduml
Lựa chọn thiết kế: Sử dụng ký hiệu chân chim chính xác (như ||--o{ cho các mối quan hệ một-đa bắt buộc-tới-tùy chọn—đảm bảo các quy tắc logic kinh doanh được mô hình hóa chính xác, ví dụ như một đặt phòng yêu cầu phải có khách hàng, nhưng một khách hàng có thể có nhiều hoặc không có đặt phòng nào đang hoạt động.
Toàn bộ đoạn mã PlantUML
Dưới đây là mã nguồn đầy đủ và được ghép nối cho sơ đồ ERD quản lý khách sạn của chúng ta. Bạn có thể sao chép và dán đoạn mã này trực tiếp vào trình chỉnh sửa PlantUML yêu thích của mìnhtrình chỉnh sửa PlantUML miễn phí để chỉnh sửa hoặc tạo đồ họa vector:
@startuml
title Sơ đồ ERD Quản lý Khách sạn
ẩn hình tròn
hướng từ trái sang phải
' Định nghĩa các thực thể với thuộc tính
entity "Khách hàng" as customer {
* customer_id : UUID <>
--
first_name : VARCHAR(50)
last_name : VARCHAR(50)
email : VARCHAR(100) <>
phone : VARCHAR(20)
address : TEXT
loyalty_points : INTEGER
total_stays : INTEGER
date_registered : TIMESTAMP
date_of_birth : DATE
nationality : VARCHAR(50)
}
entity "Phòng" as room {
* room_id : UUID <>
--
room_number : VARCHAR(10) <>
floor_number : INTEGER
room_type_id : UUID <>
capacity : INTEGER
base_price : DECIMAL(10,2)
is_available : BOOLEAN
has_view : BOOLEAN
square_feet : INTEGER
last_renovated : DATE
}
entity "Loại Phòng" as roomtype {
* room_type_id : UUID <>
--
type_name : VARCHAR(50) <>
description : TEXT
standard_capacity : INTEGER
base_price : DECIMAL(10,2)
extra_bed_charge : DECIMAL(10,2)
has_kitchenette : BOOLEAN
has_balcony : BOOLEAN
}
entity "Đặt phòng" as reservation {
* reservation_id : UUID <>
--
customer_id : UUID <>
room_id : UUID <>
check_in_date : DATE
check_out_date : DATE
number_of_guests : INTEGER
total_amount : DECIMAL(10,2)
status : VARCHAR(20)
special_requests : TEXT
created_at : TIMESTAMP
updated_at : TIMESTAMP
confirmation_code : VARCHAR(20) <>
}
entity "Thanh toán" as payment {
* payment_id : UUID <>
--
reservation_id : UUID <>
amount : DECIMAL(10,2)
payment_date : TIMESTAMP
payment_method : VARCHAR(30)
transaction_id : VARCHAR(50) <>
status : VARCHAR(20)
receipt_url : TEXT
refund_amount : DECIMAL(10,2)
}
entity "Hóa đơn" as invoice {
* invoice_id : UUID <>
--
reservation_id : UUID <>
invoice_number : VARCHAR(20) <>
issued_date : DATE
due_date : DATE
subtotal : DECIMAL(10,2)
tax : DECIMAL(10,2)
service_charge : DECIMAL(10,2)
total_amount : DECIMAL(10,2)
status : VARCHAR(20)
}
entity "Nhân viên" as staff {
* staff_id : UUID <>
--
first_name : VARCHAR(50)
last_name : VARCHAR(50)
email : VARCHAR(100) <>
phone : VARCHAR(20)
role : VARCHAR(30)
hire_date : DATE
salary : DECIMAL(10,2)
shift_schedule : VARCHAR(50)
is_active : BOOLEAN
}
entity "Dịch vụ phòng" as roomservice {
* service_id : UUID <>
--
reservation_id : UUID <>
staff_id : UUID <>
service_type : VARCHAR(50)
description : TEXT
request_time : TIMESTAMP
completion_time : TIMESTAMP
status : VARCHAR(20)
price : DECIMAL(10,2)
}
' Mối quan hệ
customer ||--o{ reservation : "tạo ra"
room ||--o{ reservation : "được gán cho"
reservation ||--|| payment : "có"
reservation ||--|| invoice : "tạo ra"
reservation ||--o{ roomservice : "yêu cầu"
staff ||--o{ roomservice : "thực hiện"
roomtype ||--o{ room : "phân loại"
@enduml 
Việc xây dựng các mô hình cơ sở dữ liệu phức tạp không nhất thiết phải đối mặt với các giao diện người dùng kéo-thả cồng kềnh. Bằng cách tận dụng phương pháp biểu đồ-dưới-dạng-mã, kiến trúc của bạn sẽ được kiểm soát phiên bản, sạch sẽ và dễ dàng duy trì.
Sẵn sàng thử xây dựng kiến trúc hệ thống của riêng bạn? Hãy truy cập vào VPasCode để trải nghiệm hiển thị thời gian thực, phát hiện định dạng tự động và xuất dữ liệu trơn tru cho tài liệu kỹ thuật của bạn ngay hôm nay!



