![]()
Khi thiết kế các kiến trúc cơ sở dữ liệu vững chắc cho các lĩnh vực phức tạp như ngành khách sạn, 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 ánh xạ hồ sơ khách hàng, theo dõi tồn kho phòng, hay quản lý hóa đơn, một sơ đồ Entity Relationship Diagram (ERD) được cấu trúc tốt sẽ tiết kiệm vô số giờ trong quá trình phát triển. Trong khóa học chuyên sâu này, tôi sẽ hướng dẫn bạn cách tôi xây dựng một sơ đồ ERD quản lý khách sạn toàn diện từ đầu bằng PlantUML bên trong trì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 của tập lệnh. Khi làm việc với các lược đồ phức tạp chứa nhiều thuộc tính, khả năng đọc được bố cục là yếu tố quan trọng nhất. Tôi cấu hình PlantUML để ẩn các chi tiết thừa và tối ưu hóa hướng bố cục của sơ đồ:
@startuml
title Sơ đồ ERD quản lý khách sạn
hide circle
left to right direction
Tại sao lại chọn cách tiếp cận này? Việc ẩn các vòng tròn thuộc tính mặc định giúp các hộp thực thể trở nên sạch sẽ và hiện đại. Việc đặt hướng thành hướng từ trái sang phải giúp ngăn ngừa các sơ đồ ERD rộng trở nên khó quản lý theo chiều dọc, đồng thời phân bố các mối quan hệ đa bảng một cách hợp lý.
2. Định nghĩa các thực thể cốt lõi và thuộc tính
Tiếp theo, tôi cần định nghĩa 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 mỗi thực thể với các 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õi Khách hàng và Loại phòng thực thể:
entity "Khách hàng" as customer {
* 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)
}
entity "Loại phòng" as roomtype {
* 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 định nghĩa các dấu hiệu rõ ràng như <<PK>> và <<UK>>, bất kỳ ai xem xét mã đều có thể hiểu ngay lập tức về các quy tắc chỉ mục và tính duy nhất trước khi các tập lệnh di chuyển cơ sở dữ liệu thậm chí được viết ra.
3. Ánh xạ 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 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ể liên kết ngược lại các bảng nền tảng của chúng ta thông qua các khóa ngoại:
entity "Phòng" as room {
* 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
}
entity "Đặt phòng" as reservation {
* 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 ánh xạ các bản ghi thanh toá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 đảm nhiệm. Để kết nối mọi thứ lại với nhau, tôi định nghĩa rõ ràng tính đa trị (cardinality) bằng ký hiệu PlantUML tiêu chuẩn:
' Các mối quan hệ
customer ||--o{ reservation : "tạo ra"
room ||--o{ reservation : "được chỉ định 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 quạ chính xác (chẳng hạn như “||--o{ đối với các mối quan hệ một-nhiều bắt buộc đến tùy chọn) đảm bảo các quy tắc logic nghiệp vụ—chẳng hạn như một đặt phòng yêu cầu một 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—được mô hình hóa chính xác.
Kịch bản PlantUML hoàn chỉnh
Dưới đây là mã nguồn đầy đủ, đã được tổng hợp cho sơ đồ thực thể-quan hệ (ERD) quản lý khách sạn của chúng tôi. Bạn có thể sao chép và dán mã này trực tiếp vào công cụ PlantUML miễn phí yêu thích của mìnhcông cụ PlantUML miễn phí để chỉnh sửa hoặc hiển thị đồ họa vector:
@startuml
title Sơ đồ ERD Quản lý Khách sạn
hide circle
left to right direction
' Định nghĩa các thực thể với các 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)
}
' Các mối quan hệ
customer ||--o{ reservation : "tạo ra"
room ||--o{ reservation : "được chỉ định 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 
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 đồng nghĩa với việc vật lộn 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 sơ đồ 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 bảo 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ậpVPasCode để trải nghiệm khả năng hiển thị thời gian thực, phát hiện định dạng tự động và xuất dữ liệu liền mạch cho tài liệu kỹ thuật của bạn ngay hôm nay!