Заметки IT библиотека

На главную

PlantUML для моделирования баз данных

Опубликовано: 28.06.2024  Последнее обновление: 28.06.2024

Часто требуется описать связи таблиц в базе данных так, чтоб это было понятно и легко поддерживаемо.

На помощь приходит PlantUML.

За основу я взял подходы описанные здесь:

Основное отличие от оригинала, функции, описывающие отдельные понятия таблиц дообогащены подсветкой и явным указание. Так, тип столбца имеет зелёный цвет, комментарий - курсив, добавлена функция внешнего ключа.

Для начала работы просто скопируйте код в свой редактор, поддерживающий PlantUML или воспользуйтесь online просмотром скопировав код в поле ввода.

Подсказка по связям:

Отношения Идентифицирующее Неидентифицирующее
Ноль или один |o-- |o..
Только один ||-- ||..
Ноль или много }o-- }o..
Один или много }|-- }|..

Пример кода:

@startuml

' комментарий
!function $comment($value) !return "<i><color:#efefef><&media-record></color>" + $value + "</i>"

' тип данных
!function $type($value) !return "<color:#006400>" + $value + "</color>"

' название столбца
!function $plain_name($value, $isRequired="false")
!if ($isRequired == "true")
!return "<color:#ff0000>*</color> " + $value
!else
!return "<color:#000000>-</color> " + $value
!endif
!endfunction

' название первичного ключа
!function $primary_key_name($value) !return "<b><color:#b8861b><&key></color> " + $value + "</b>"

' название вторичного ключа
!function $foreign_key_name($value, $isRequired="false")
!if ($isRequired == "true")
!return "<color:#ff0000>*</color> <color:#aaaaaa><&key></color> " + $value
!else
!return "<color:#000000>-</color> <color:#aaaaaa><&key></color> " + $value
!endif
!endfunction

' столбец
!function $column($nameValue, $typeValue, $commentValue)
!return $nameValue + ": " + $type($typeValue) + $comment($commentValue)
!endfunction

' таблица
!function $table($tableName) !return "entity " + $tableName + " << (T, white) >>"

map Легенда {
    <color:#b8861b><&key></color> => Первичный ключ
    <color:#ff0000>*</color> <color:#aaaaaa><&key></color> => Обязательный внешний ключ
    <color:#000000>-</color> <color:#aaaaaa><&key></color> => Необязательный внешний ключ
    <color:#ff0000>*</color> => Не nullable столбец
    <color:#000000>-</color> => Nullable столбец
    NAME => Название столбца
    <color:#006400>NUMBER</color> => Тип столбца

    |o-- => Ноль или один. Идентифицирующее
    |o.. => Ноль или один. Неидентифицирующее
    ||-- => Только один. Идентифицирующее
    ||.. => Только один. Неидентифицирующее
    }o-- => Ноль или много. Идентифицирующее
    }o.. => Ноль или много. Неидентифицирующее
    }|-- => Один или много. Идентифицирующее
    }|.. => Один или много. Неидентифицирующее
}

$table("CLIENT <<Клиент>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("FIRST_NAME", "true"), "NUMBER", "Имя" )
    $column( $plain_name("LAST_NAME", "true"), "VARCHAR(512)", "Фамилия" )
    $column( $plain_name("ADDRESS", "true"), "VARCHAR(500)", "Адрес" )
    $column( $plain_name("POSTAL_CODE", "true"), "VARCHAR(10)", "Почтовый код" )
    $column( $plain_name("CREATION_DATE", "true"), "TIMESTAMP", "Дата создания записи" )
    $column( $foreign_key_name("COUNTRY_ID"), "NUMBER", "Идентификатор страны" )
}

$table("ORDER <<Заказ>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("CREATION_DATE", "true"), "TIMESTAMP", "Дата создания записи" )
    $column( $foreign_key_name("CLIENT_ID", "true"), "NUMBER", "Идентификатор клиента")
    $column( $foreign_key_name("PRODUCT_ID", "true"), "NUMBER", "Идентификатор товара" )
}

$table("COUNTRY <<Страна>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("NAME", "true"), "VARCHAR(512)", "Фамилия" )
}

package "Product data" as PRODUCT_DATA {
    $table("PRODUCT <<Товар>>") {
        $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
        $column( $plain_name("NAME", "true"), "VARCHAR(128)", "Название")
        $column( $plain_name("COLOR", "false"), "VARCHAR(128)", "Цвет" )
        $column( $plain_name("QUANTITY","true"), "NUMBER", "Количество" )
    }

    $table("SIZE <<Размеры>>") {
        $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
        $column( $plain_name("NAME", "true"), "VARCHAR(128)", "Название")
        $column( $plain_name("COLOR", "false"), "VARCHAR(128)", "Цвет" )
        $column( $plain_name("QUANTITY","true"), "NUMBER", "Количество" )
    }

    $table("PRODUCT_SIZE <<Товар и его размеры>>") {
        $column( $foreign_key_name("PRODUCT_ID", "true"), "NUMBER", "Идентификатор товара")
        $column( $foreign_key_name("SIZE_ID", "true"), "NUMBER", "Идентификатор размера" )
    }
}

CLIENT::ID ||--o{ ORDER::CLIENT_ID
CLIENT::COUNTRY_ID ||--|| COUNTRY::ID

ORDER::PRODUCT_ID }o--|| PRODUCT::ID

PRODUCT::ID ||--o{ PRODUCT_SIZE::PRODUCT_ID
SIZE::ID ||--o{ PRODUCT_SIZE::SIZE_ID
@enduml

Результат:

Схема

В примере выше используется связывание по столбцам, если вам достаточно связать просто таблицы, можно воспользоваться настройкой skinparam linetype ortho, которая делает линии связи прямыми.

Пример:

@startuml

skinparam linetype ortho

' комментарий
!function $comment($value) !return "<i><color:#efefef><&media-record></color>" + $value + "</i>"

' тип данных
!function $type($value) !return "<color:#006400>" + $value + "</color>"

' название столбца
!function $plain_name($value, $isRequired="false")
!if ($isRequired == "true")
!return "<color:#ff0000>*</color> " + $value
!else
!return "<color:#000000>-</color> " + $value
!endif
!endfunction

' название первичного ключа
!function $primary_key_name($value) !return "<b><color:#b8861b><&key></color> " + $value + "</b>"

' название вторичного ключа
!function $foreign_key_name($value, $isRequired="false")
!if ($isRequired == "true")
!return "<color:#ff0000>*</color> <color:#aaaaaa><&key></color> " + $value
!else
!return "<color:#000000>-</color> <color:#aaaaaa><&key></color> " + $value
!endif
!endfunction

' столбец
!function $column($nameValue, $typeValue, $commentValue)
!return $nameValue + ": " + $type($typeValue) + $comment($commentValue)
!endfunction

' таблица
!function $table($tableName) !return "entity " + $tableName + " << (T, white) >>"

map Легенда {
    <color:#b8861b><&key></color> => Первичный ключ
    <color:#ff0000>*</color> <color:#aaaaaa><&key></color> => Обязательный внешний ключ
    <color:#000000>-</color> <color:#aaaaaa><&key></color> => Необязательный внешний ключ
    <color:#ff0000>*</color> => Не nullable столбец
    <color:#000000>-</color> => Nullable столбец
    NAME => Название столбца
    <color:#006400>NUMBER</color> => Тип столбца

    |o-- => Ноль или один. Идентифицирующее
    |o.. => Ноль или один. Неидентифицирующее
    ||-- => Только один. Идентифицирующее
    ||.. => Только один. Неидентифицирующее
    }o-- => Ноль или много. Идентифицирующее
    }o.. => Ноль или много. Неидентифицирующее
    }|-- => Один или много. Идентифицирующее
    }|.. => Один или много. Неидентифицирующее
}

$table("CLIENT <<Клиент>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("FIRST_NAME", "true"), "NUMBER", "Имя" )
    $column( $plain_name("LAST_NAME", "true"), "VARCHAR(512)", "Фамилия" )
    $column( $plain_name("ADDRESS", "true"), "VARCHAR(500)", "Адрес" )
    $column( $plain_name("POSTAL_CODE", "true"), "VARCHAR(10)", "Почтовый код" )
    $column( $plain_name("CREATION_DATE", "true"), "TIMESTAMP", "Дата создания записи" )
    $column( $foreign_key_name("COUNTRY_ID"), "NUMBER", "Идентификатор страны" )
}

$table("ORDER <<Заказ>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("CREATION_DATE", "true"), "TIMESTAMP", "Дата создания записи" )
    $column( $foreign_key_name("CLIENT_ID", "true"), "NUMBER", "Идентификатор клиента")
    $column( $foreign_key_name("PRODUCT_ID", "true"), "NUMBER", "Идентификатор товара" )
}

$table("COUNTRY <<Страна>>") {
    $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
    $column( $plain_name("NAME", "true"), "VARCHAR(512)", "Фамилия" )
}

package "Product data" as PRODUCT_DATA {
    $table("PRODUCT <<Товар>>") {
        $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
        $column( $plain_name("NAME", "true"), "VARCHAR(128)", "Название")
        $column( $plain_name("COLOR", "false"), "VARCHAR(128)", "Цвет" )
        $column( $plain_name("QUANTITY","true"), "NUMBER", "Количество" )
    }

    $table("SIZE <<Размеры>>") {
        $column( $primary_key_name("ID"), "NUMBER", "Идентификатор")
        $column( $plain_name("NAME", "true"), "VARCHAR(128)", "Название")
        $column( $plain_name("COLOR", "false"), "VARCHAR(128)", "Цвет" )
        $column( $plain_name("QUANTITY","true"), "NUMBER", "Количество" )
    }

    $table("PRODUCT_SIZE <<Товар и его размеры>>") {
        $column( $foreign_key_name("PRODUCT_ID", "true"), "NUMBER", "Идентификатор товара")
        $column( $foreign_key_name("SIZE_ID", "true"), "NUMBER", "Идентификатор размера" )
    }
}

CLIENT ||--o{ ORDER
CLIENT ||--|| COUNTRY

ORDER }o--|| PRODUCT

PRODUCT ||--o{ PRODUCT_SIZE
SIZE ||--o{ PRODUCT_SIZE
@enduml

Результат:

Схема

Успехов!

© 2020 - 2025

Ёжик