Za darmo · Bez rejestracji · Obsługuje pliki .mmd

Edytor diagramów ER Mermaid

Diagram związków encji pokazuje tabele, ich kolumny i sposób, w jaki się łączą. Nadaje się wtedy, gdy tematem jest schemat bazy danych, a ciekawe pytania dotyczą kluczy i liczności — jeden do wielu, opcjonalnie, albo przez tabelę łączącą. Do typów z zachowaniem i dziedziczeniem lepszy jest diagram klas.

Znormalizowany schemat zamówień z tabelą łączącą

Wartą uwagi częścią jest `}o--||` przy pozycji zamówienia: tak wyraża się uczciwie relację wiele do wielu, przez tabelę łączącą z własnymi kolumnami, zamiast udawać, że dwie tabele łączą się bezpośrednio. Przechowywanie ceny w pozycji, a nie tylko w produkcie, to właśnie decyzja, którą diagram powinien uwidocznić.

erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"
    ZAMOWIENIE ||--|{ POZYCJA : "zawiera"
    PRODUKT ||--o{ POZYCJA : "występuje w"
    KLIENT ||--o{ ADRES : "wysyłka na"

    KLIENT {
        int id PK
        string email UK "zapisywany małymi literami"
        string nazwa
        datetime utworzony
    }
    ZAMOWIENIE {
        int id PK
        int klient_id FK
        string status
        decimal wartosc
    }
    POZYCJA {
        int zamowienie_id PK, FK
        int produkt_id PK, FK
        int ilosc
        decimal cena "cena z chwili złożenia zamówienia"
    }
    PRODUKT {
        int id PK
        string sku UK
        string nazwa
    }
    ADRES {
        int id PK
        int klient_id FK
        string kod_pocztowy
    }
Otwórz to w edytorze
Reklama

Omówione przykłady

1. Dwie encje i jedna relacja

Każda relacja ER wymaga etykiety po dwukropku — nie jest opcjonalna, inaczej niż krawędź schematu blokowego. Czyta się to jak zdanie: KLIENT składa ZAMOWIENIE.

erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"
Otwórz w edytorze

2. Dodawanie kolumn

Każdy wiersz atrybutu to `typ nazwa` i obie części są obowiązkowe. `PK`, `FK` i `UK` oznaczają klucze; napis w cudzysłowie na końcu jest komentarzem do kolumny.

erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"
    KLIENT {
        int id PK
        string email UK
        string nazwa
    }
    ZAMOWIENIE {
        int id PK
        int klient_id FK
        datetime zlozone "w UTC"
    }
Otwórz w edytorze

3. Liczność, która coś mówi

Dwa znaki najbliżej każdej encji to jej liczność. Ten przykład mówi, że zamówienie musi mieć co najmniej jedną pozycję, ale klient może nie mieć żadnego zamówienia: realne ograniczenie, które schemat powinien wymuszać, a diagram pokazywać.

erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"
    ZAMOWIENIE ||--|{ POZYCJA : "zawiera"
    POZYCJA }o--|| PRODUKT : "odwołuje się do"
Otwórz w edytorze

4. Wiele do wielu przez tabelę łączącą

Mermaid potrafi narysować bezpośrednią relację wiele do wielu, ale schemat prawie nigdy jej nie ma: pod spodem leży tabela łącząca. Narysowanie jej jest uczciwsze i daje miejsce na kolumny należące do samej relacji.

erDiagram
    STUDENT ||--o{ ZAPIS : "zapisuje się na"
    KURS ||--o{ ZAPIS : "realizowany przez"
    ZAPIS {
        int student_id PK, FK
        int kurs_id PK, FK
        datetime data_zapisu
        string ocena "pusta do czasu zaliczenia"
    }
    STUDENT {
        int id PK
        string nazwisko
    }
    KURS {
        int id PK
        string kod UK
    }
Otwórz w edytorze

5. Relacje zwrotne

Tabela może wiązać się sama ze sobą: linia podległości, drzewo kategorii, wątek komentarzy. Etykieta relacji ma tu większe znaczenie niż zwykle, bo oba końce to ta sama encja.

erDiagram
    PRACOWNIK ||--o{ PRACOWNIK : "kieruje"
    PRACOWNIK {
        int id PK
        int przelozony_id FK "puste dla zarządu"
        string nazwisko
        string stanowisko
    }
Otwórz w edytorze

Ściąga ze składni diagramu ER

Liczność zapisuje się dwoma znakami na każdym końcu relacji i czyta od środka na zewnątrz. Lewa para opisuje encję po lewej, prawa tę po prawej.

SkładniaZnaczenie
erDiagramOtwiera diagram. Rozróżnia wielkość liter: `erdiagram` nie zadziała.
A ||--o{ B : "etykieta"Relacja. Etykieta jest obowiązkowa.
||Dokładnie jeden.
o|Zero albo jeden.
}|Jeden albo więcej.
}oZero albo więcej.
--Relacja identyfikująca — linia ciągła.
..Relacja nieidentyfikująca — linia przerywana.
A { ... }Blok atrybutów encji A.
int id PKAtrybut: typ, potem nazwa, potem opcjonalne oznaczenie klucza.
PK / FK / UKKlucz główny, obcy, unikalny.
int id PK, FKKilka oznaczeń klucza, rozdzielonych przecinkiem.
string email "komentarz"Napis w cudzysłowie na końcu to komentarz do kolumny.
A ||--o{ B : "należy do"Cudzysłowy są OBOWIĄZKOWE, gdy tylko etykieta zawiera spację. Bez nich urywa się na pierwszej spacji, a każdy pozostały wyraz staje się encją widmem.
Reklama

Sześć błędów, które psują diagram ER

ER ma najostrzejszą gramatykę spośród sześciu typów: to, co przechodzi w innych diagramach, tutaj jest odrzucane wprost. Ma jednak także cichy błąd, na który po polsku wpada się szczególnie łatwo. Wszystko odtworzone na Mermaidzie 11.12.2.

Co widzisz

Rysuje się, etykieta jest ucięta, a na diagramie pojawiają się encje, których nie napisałeś

Dlaczego

Etykieta relacji zawiera spację i nie ma cudzysłowów. To błąd, który po polsku będzie przeszkadzał najbardziej, bo nasze zwroty relacyjne prawie zawsze są wielowyrazowe: «należy do», «występuje w», «wysyłka na». Zmierzone: `KLIENT ||--o{ ZAMOWIENIE : należy do` nie zgłasza błędu, skraca etykietę do «należy» i tworzy pustą encję o nazwie «do». Przy trzech wyrazach powstają dwie encje widma. Dwie tabele rysują się jako cztery prostokąty i nic o tym nie ostrzega.

Rozwiązanie

Bierz w cudzysłów każdą etykietę zawierającą spację. Po polsku znaczy to praktycznie zawsze; łatwiej przyjąć to jako zasadę niż rozstrzygać za każdym razem.

Błędnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : należy do
Poprawnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "należy do"

Co widzisz

Parse error, kończy się na: Expecting 'COLON', 'STYLE_SEPARATOR', got 'NEWLINE'

Dlaczego

Relacja bez etykiety. Inaczej niż w krawędzi schematu blokowego, dwukropek i etykieta są obowiązkowe: bez nich wiersz po prostu kończy się za wcześnie.

Rozwiązanie

Dodaj dwukropek i zwrot czasownikowy, w cudzysłowie, jeśli zawiera spację.

Błędnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE
Poprawnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"

Co widzisz

Parse error, kończy się na: got 'UNICODE_TEXT'

Dlaczego

Nieprawidłowy token liczności. Poprawne są wyłącznie `||`, `o|`, `}|` i `}o` (oraz ich lustrzane odbicia); cokolwiek innego się przewraca. `oo` to typowa literówka, brana z założenia, że notacja jest symetryczna.

Rozwiązanie

Użyj jednej z czterech par. `||--o{` — dokładnie jeden do zera lub więcej — pokrywa większość kluczy obcych.

Błędnie
erDiagram
    KLIENT ||--oo{ ZAMOWIENIE : "składa"
Poprawnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"

Co widzisz

Parse error, kończy się na: Expecting 'ATTRIBUTE_WORD', got 'BLOCK_STOP'

Dlaczego

Atrybut ma nazwę, ale nie ma typu. Atrybuty ER zapisuje się jako `typ nazwa`, a typ nie jest opcjonalny — co zaskakuje osoby przychodzące z baz bez schematu.

Rozwiązanie

Nadaj typ każdemu atrybutowi. Wymyśl go, jeśli prawdziwy schemat go nie ma: `string`, `int`, `json`.

Błędnie
erDiagram
    KLIENT {
        email
    }
Poprawnie
erDiagram
    KLIENT {
        string email
    }

Co widzisz

Parse error, kończy się na: Expecting 'NON_IDENTIFYING', 'IDENTIFYING', got 'UNICODE_TEXT'

Dlaczego

Linia między dwoma oznaczeniami liczności jest niewłaściwa. Musi mieć dokładnie dwa znaki: `--` dla relacji identyfikującej albo `..` dla nieidentyfikującej. Pojedynczy myślnik nie jest skróconą wersją `--`, tylko błędem składni.

Rozwiązanie

Między parami liczności pisz `--` albo `..`.

Błędnie
erDiagram
    KLIENT ||-o{ ZAMOWIENIE : "składa"
Poprawnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"

Co widzisz

Liczność się rysuje, ale opisuje odwrotne ograniczenie

Dlaczego

Dwa znaki najbliżej każdej encji należą do tej właśnie encji, a przeczytanie ich na odwrót jest bardzo łatwe. `KLIENT ||--o{ ZAMOWIENIE` mówi, że jeden klient ma zero lub więcej zamówień. Odwróć to na `KLIENT }o--|| ZAMOWIENIE`, a stwierdzisz, że każdy klient należy do dokładnie jednego zamówienia, co nie ma sensu — i rysuje się bez najmniejszego sprzeciwu.

Rozwiązanie

Czytaj od środka na zewnątrz: znaki dotykające KLIENTA opisują, ilu jest klientów, a nie ile jest zamówień.

Błędnie
erDiagram
    KLIENT }o--|| ZAMOWIENIE : "składa"
Poprawnie
erDiagram
    KLIENT ||--o{ ZAMOWIENIE : "składa"

Uwagi o renderowaniu

Zmierzone na Mermaidzie 11.12.2, którego używa ta strona.

Układ dyktują relacje, a nie liczba encji

Łańcuch encji powiązanych jedna z drugą rysuje się jako wysoka kolumna: czterdzieści encji daje viewBox około 116×7315, wobec 116×470 przy trzech. Ale te same czterdzieści encji powiązanych z jedną tabelą centralną daje coś znacznie szerszego i niższego. To jedyny typ diagramu tutaj, w którym kształt twoich danych zmienia kształt obrazka bardziej niż jego rozmiar, więc schemat, który się nie mieści, częściej naprawia się zmianą tego, które relacje rysujesz, niż ich liczby.

Po polsku prawie każda etykieta wymaga cudzysłowów

Warto to powtórzyć, bo to najdroższy cichy błąd na tej stronie. Angielskie etykiety relacji bywają jednowyrazowe — places, contains, references — więc w angielskiej dokumentacji cudzysłowy wyglądają na ozdobnik. Po polsku większość to zwroty wielowyrazowe i bez cudzysłowów się rozpadają. Zasada praktyczna: zawsze bierz etykietę w cudzysłów i przestań o tym myśleć.

Nazwy encji rozróżniają wielkość liter i umownie pisze się je wersalikami

`KLIENT` i `klient` to dwie różne encje, a wspomnienie obu w jednym diagramie daje dwa prostokąty bez ostrzeżenia. Konwencji wersalików Mermaid nie wymusza, ale warto ją trzymać właśnie dlatego, że uwidacznia przypadkowe odwołanie małymi literami. Polskie znaki działają w nazwach encji i kolumn bez problemu; warto natomiast z góry zdecydować, czy schemat ma ogonki, i się tego trzymać.

Gramatyka jest najostrzejsza spośród sześciu typów

Etykiety relacji są obowiązkowe, typy atrybutów również, a tokeny liczności tworzą zbiór zamknięty. W porównaniu z Ganttem, gdzie rysuje się niemal wszystko, a błędy milczą, ER przewraca się wcześnie i głośno. To zaleta: jeśli diagram ER się narysował, jest całkiem prawdopodobne, że to ten diagram, o który ci chodziło — z wyraźnym wyjątkiem etykiet bez cudzysłowów.

Etykiety to HTML, więc eksport do PNG przerysowuje

Tabele atrybutów encji rysowane są wewnątrz `<foreignObject>` w SVG, więc przeglądarki nie potrafią ich zrasteryzować wprost na canvasie. Eksport do PNG na tej stronie wcześniej po cichu oddawał plik SVG; teraz najpierw przerysowuje diagram etykietami z czystego tekstu SVG i wytwarza poprawny PNG w pełnym rozmiarze, z ledwie zauważalnie innym składem.

Kiedy lepszy będzie inny diagram

Jeśli potrzebujesz dziedziczenia, interfejsów albo metod, to niewłaściwy diagram: ER nie ma żadnego z tych pojęć. Użyj diagramu klas i przyjmij, że modeluje on twój kod, a nie twoje tabele.

Jeśli schemat jest duży, diagram ER całości staje się ścienną planszą, której nikt nie czyta. Narysuj pięć tabel związanych z tym, co właśnie tłumaczysz, a resztę zostaw poza kadrem; diagram jest argumentem, a nie inwentarzem.

A jeśli prawdziwe pytanie brzmi, jak dane przepływają między systemami, a nie jak są przechowywane, odpowie na nie schemat blokowy z podgrafem na system, a diagram ER nie.

Inne typy diagramów

Autor Dominik Malsch · Ostatnia aktualizacja:

Otwórz edytor →