PlantUML is a tool I’m fond of using to create diagrams from text. While they may not give the same level of customization as a graphical editor, they’re easier to maintain/update.
The other day I was working to loosely define a schema in PlantUML and realized that it wasn’t obvious how to customize plantuml to represent this.
Skinning Components
To start, I’m using PlantUML’s class diagram to describe our schema since it provides a lot of useful relationship and attribute descriptors. We can start with a base description of offices and their employees:
class "Office" as office {
officeCode: integer
city: string
phone: string
addressLine1: string
addressLine2: string
state: string
country: string
postalCode: string
territory: string
}
class "Employee" as employee {
employeeId: uuid
officeCode: integer
lastName: string
firstName: string
email: string
jobTitle: string
}
which renders as the following:
Now this looks alright but some parts aren’t quite right. We’re not really representing a class via the ‘C’ icon. Furthermore, there’s a line at the bottom which would be used to split between class fields and methods but for our schema this isn’t needed. To make this more schema-oriented, we can spruce this up a bit by replacing the ‘C’ icon representing “class” with a ‘T’ icon representing “table”. We also can remove the bottom line delineating between the fields and methods of a ‘class’. This can be accomplished with the following changes (’ at the beginning of a line denotes a comment):
@startuml
' Define a preprocessor define to shorthand table creation
!define table(name, x) class "name" as x << (T,#FFAAAA) >>
' Ensure we hide methods and stereotypes to clean up the diagram
hide methods
hide stereotypes
table(Employee, employee) {
officeCode: integer
city: string
phone: string
addressLine1: string
addressLine2: string
state: string
country: string
postalCode: string
territory: string
}
table(Office, office) {
employeeId: uuid
officeCode: integer
lastName: string
firstName: string
email: string
jobTitle: string
}
@enduml
This reads a bit cleaner in the text as well as on the diagram:
Relationships Between Tables
Within our usecase, let’s say that within every office there are 0 or more employees. We can represent this in PlantUML with the following addition:
office "1" -r- "*" employee
Which renders as:
Primary, Foreign Keys and other attribute modifiers
Now that we’ve established the relationship between the tables, it’d be nice if we could mark the attributes that show uniqueness for table elements as well as table relationships. For this example, the two things that would be helpful to mark would be the primary and foreign keys. This is done via a key icon and underlining to indicate a primary vs a foreign key. This can be accomplished with a couple more preprocessor defines:
!define primary_key(x) <&key><u>x</u>
!define foreign_key(x) <&key>x
we can then use these to wrap attributes of a table like so:
table(Employee, employee) {
primary_key(employeeId: uuid)
foreign_key(officeCode: integer)
lastName: string
firstName: string
email: string
jobTitle: string
}
table(Office, office) {
primary_key(officeCode: uuid)
city: string
phone: string
addressLine1: string
addressLine2: string
state: string
country: string
postalCode: string
territory: string
}
which renders as:
Conclusion
While this doesn’t fully cover all the possible attributes they may need to be represented in a schema, it can give a starting point to quickly iterate until you’ve come to a better understanding of the given problem domain and how those relationships should be represented.
The full example and all the intermediate steps can be found here.