![]()
При проектировании надежных архитектур баз данных для сложных областей, таких как гостеприимство, четкое визуализирование связей имеет решающее значение. Будь то создание профилей клиентов, отслеживание инвентаря номеров или управление счетами, хорошо структурированная диаграмма сущность-связь (ERD) экономит бесчисленное количество часов во время разработки. В этом мастер-классе я покажу, как я создал полную диаграмму сущность-связь для управления отелем с нуля с использованием PlantUML внутри бесплатного редактора PlantUML, VPasCode.

1. Инициализация среды PlantUML
Я начинаю с создания основной структуры скрипта. При работе со сложными схемами, содержащими множество атрибутов, читаемость макета имеет первостепенное значение. Я настраиваю PlantUML для скрытия ненужного мусора и оптимизации направления расположения диаграммы:
@startuml
title Диаграмма сущность-связь для управления отелем
скрыть круг
направление слева направо
Почему именно такой подход?Скрытие стандартных кругов атрибутов сохраняет блоки сущностей чистыми и современными. Установка направления на направление слева направопомогает предотвратить вертикальное переполнение широких ERD, логически распределяя отношения между несколькими таблицами.
2. Определение основных сущностей и атрибутов
Далее мне нужно определить основные сущности, представляющие нашу предметную область. Я структурирую каждую сущность с первичными ключами, уникальными ограничениями и типизированными атрибутами. Давайте посмотрим, как я настроил основные Customer и RoomType сущности:
entity "Customer" 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 "RoomType" 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
}
Определяя явные маркеры, такие как <<PK>> и <<UK>>, любой, кто просматривает код, мгновенно понимает правила индексации и уникальности, даже до написания скриптов миграции базы данных.
3. Картирование операционных сущностей (номера, бронирования и персонал)
После того как наши справочные данные на месте, я перехожу к транзакционному центру системы управления отелем: номера, бронирования и рабочие процессы персонала. Каждая сущность связывается с нашими основными таблицами с помощью внешних ключей:
entity "Room" 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 "Reservation" 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. Установление финансовых и сервисных связей
Для завершения архитектуры я отображаю записи счетов (платежи и счета), а также вспомогательные услуги, такие как обслуживание номеров, выполняемое персоналом отеля. Чтобы объединить всё вместе, я явно определяю кардинальность с использованием стандартной нотации PlantUML:
' Связи
customer ||--o{ reservation : "создает"
room ||--o{ reservation : "назначена"
reservation ||--|| payment : "имеет"
reservation ||--|| invoice : "генерирует"
reservation ||--o{ roomservice : "запрашивает"
staff ||--o{ roomservice : "выполняет"
roomtype ||--o{ room : "категоризирует"
@enduml
Выбор дизайна: Использование точной нотации клювов (например, ||--o{ для обязательных связей один-ко-многим с необязательным элементом) обеспечивает точное моделирование бизнес-логики — например, бронирование требует клиента, но клиент может иметь несколько или ноль активных бронирований.
Полный скрипт PlantUML
Вот полный собранный исходный код для нашей ERD управления отелем. Вы можете скопировать и вставить этот код непосредственно в свой любимый бесплатный редактор PlantUML чтобы редактировать или отображать векторные изображения:
@startuml
title Управление отелем ERD
hide circle
left to right direction
' Определение сущностей с атрибутами
entity "Клиент" 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 "Номер" 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 "Тип номера" 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 "Бронирование" 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 "Платеж" 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 "Счет" 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 "Персонал" 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 "Служба номеров" 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)
}
' Связи
customer ||--o{ reservation : "создает"
room ||--o{ reservation : "назначена"
reservation ||--|| payment : "имеет"
reservation ||--|| invoice : "генерирует"
reservation ||--o{ roomservice : "запрашивает"
staff ||--o{ roomservice : "выполняет"
roomtype ||--o{ room : "категоризирует"
@enduml 
Создание сложных моделей баз данных не обязательно означает борьбу с неудобными интерфейсами перетаскивания. Используя подход «диаграмма как код», ваша архитектура будет контролироваться версиями, чистой и легко поддерживаемой.
Готовы попробовать создать собственные архитектуры систем? Перейдите на VPasCode чтобы сегодня испытать мгновенное отображение, автоматическое определение формата и бесшовную экспортацию для вашей технической документации!



