Grátis · Sem cadastro · Funciona com arquivos .mmd

Editor de diagrama ER Mermaid

Um diagrama entidade-relacionamento mostra tabelas, suas colunas e como elas se juntam. Use quando o assunto for um esquema de banco de dados e as perguntas interessantes forem sobre chaves e cardinalidade — um para muitos, opcional, ou através de uma tabela associativa. Para tipos com comportamento e herança, use um diagrama de classes.

Um esquema de pedidos normalizado com tabela associativa

A parte que merece estudo é o `}o--||` de ITEM_PEDIDO: é assim que se expressa com honestidade um relacionamento muitos-para-muitos, através de uma tabela associativa com colunas próprias, em vez de fingir que duas tabelas se ligam diretamente. Guardar o preço no item, e não só no produto, é a decisão que o diagrama precisa deixar visível.

erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"
    PEDIDO ||--|{ ITEM_PEDIDO : "contém"
    PRODUTO ||--o{ ITEM_PEDIDO : "aparece em"
    CLIENTE ||--o{ ENDERECO : "entrega em"

    CLIENTE {
        int id PK
        string email UK "gravado em minúsculas"
        string nome
        datetime criado_em
    }
    PEDIDO {
        int id PK
        int cliente_id FK
        string status
        decimal valor_total
    }
    ITEM_PEDIDO {
        int pedido_id PK, FK
        int produto_id PK, FK
        int quantidade
        decimal preco_unitario "preço no momento do pedido"
    }
    PRODUTO {
        int id PK
        string sku UK
        string nome
    }
    ENDERECO {
        int id PK
        int cliente_id FK
        string cep
    }
Abrir isto no editor
Publicidade

Exemplos resolvidos

1. Duas entidades e um relacionamento

Todo relacionamento ER precisa de um rótulo depois dos dois-pontos — não é opcional, ao contrário de uma aresta de fluxograma. Leia como uma frase: CLIENTE realiza PEDIDO.

erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"
Abrir no editor

2. Acrescentar colunas

Cada linha de atributo é `tipo nome`, e as duas partes são obrigatórias. `PK`, `FK` e `UK` marcam chaves; uma string entre aspas no fim é um comentário.

erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"
    CLIENTE {
        int id PK
        string email UK
        string nome
    }
    PEDIDO {
        int id PK
        int cliente_id FK
        datetime feito_em "em UTC"
    }
Abrir no editor

3. Cardinalidade que diz alguma coisa

Os dois caracteres mais próximos de cada entidade são a cardinalidade dela. Este exemplo diz que um pedido precisa ter ao menos um item, mas que um cliente pode não ter pedido nenhum: uma restrição real, que o esquema deveria impor e o diagrama deveria mostrar.

erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"
    PEDIDO ||--|{ ITEM_PEDIDO : "contém"
    ITEM_PEDIDO }o--|| PRODUTO : "referencia"
Abrir no editor

4. Muitos-para-muitos com tabela associativa

O Mermaid consegue desenhar um muitos-para-muitos direto, mas um esquema quase nunca tem um: há uma tabela associativa por baixo. Desenhá-la é mais honesto e dá onde colocar as colunas que pertencem ao próprio relacionamento.

erDiagram
    ALUNO ||--o{ MATRICULA : "se inscreve em"
    DISCIPLINA ||--o{ MATRICULA : "é cursada via"
    MATRICULA {
        int aluno_id PK, FK
        int disciplina_id PK, FK
        datetime matriculado_em
        string nota "nula até a avaliação"
    }
    ALUNO {
        int id PK
        string nome
    }
    DISCIPLINA {
        int id PK
        string codigo UK
    }
Abrir no editor

5. Relacionamentos reflexivos

Uma tabela pode se relacionar consigo mesma: uma linha de subordinação, uma árvore de categorias, uma thread de comentários. Aqui o rótulo do relacionamento importa mais que o normal, porque as duas pontas são a mesma entidade.

erDiagram
    FUNCIONARIO ||--o{ FUNCIONARIO : "gerencia"
    FUNCIONARIO {
        int id PK
        int gestor_id FK "nulo para a diretoria"
        string nome
        string cargo
    }
Abrir no editor

Referência de sintaxe do diagrama ER

A cardinalidade é escrita com dois caracteres em cada ponta do relacionamento e se lê do centro para fora. O par da esquerda descreve a entidade da esquerda; o da direita, a da direita.

SintaxeSignificado
erDiagramAbre o diagrama. Diferencia maiúsculas: `erdiagram` não vale.
A ||--o{ B : "rótulo"Relacionamento. O rótulo é obrigatório.
||Exatamente um.
o|Zero ou um.
}|Um ou mais.
}oZero ou mais.
--Relacionamento identificador — linha cheia.
..Relacionamento não identificador — linha tracejada.
A { ... }Bloco de atributos da entidade A.
int id PKAtributo: tipo, depois nome, depois marca de chave opcional.
PK / FK / UKChave primária, estrangeira, única.
int id PK, FKVárias marcas de chave, separadas por vírgula.
string email "comentário"A string entre aspas no fim é um comentário da coluna.
A ||--o{ B : "pertence a"As aspas são OBRIGATÓRIAS assim que o rótulo tiver um espaço. Sem elas ele é cortado no primeiro espaço e cada palavra restante vira uma entidade fantasma.
Publicidade

Seis erros que quebram um diagrama ER

O ER tem a gramática mais rígida dos seis tipos: o que passa em outros diagramas aqui é rejeitado de cara. Mas é também onde mora a falha silenciosa que mais castiga quem escreve em português. Tudo reproduzido no Mermaid 11.12.2.

O que você vê

Desenha, o rótulo sai cortado e surgem entidades que você não escreveu

Por quê

Um rótulo de relacionamento com espaço e sem aspas. É a falha que mais vai incomodar em português, porque quase todos os nossos verbos de relação pedem preposição: «pertence a», «aparece em», «entrega em». Medido: `CLIENTE ||--o{ PEDIDO : pertence a` não dá erro nenhum, corta o rótulo para «pertence» e cria uma entidade fantasma chamada «a». Com três palavras saem duas entidades fantasma. Duas tabelas viram quatro caixas e nada avisa.

Solução

Ponha entre aspas todo rótulo que tiver espaço. Em português isso significa quase sempre; é mais fácil adotar como regra do que decidir caso a caso.

Quebrado
erDiagram
    CLIENTE ||--o{ PEDIDO : pertence a
Corrigido
erDiagram
    CLIENTE ||--o{ PEDIDO : "pertence a"

O que você vê

Parse error, terminando em: Expecting 'COLON', 'STYLE_SEPARATOR', got 'NEWLINE'

Por quê

Um relacionamento sem rótulo. Ao contrário de uma aresta de fluxograma, os dois-pontos e o rótulo são obrigatórios: sem eles a linha simplesmente termina cedo demais.

Solução

Acrescente os dois-pontos e uma locução verbal, entre aspas se tiver espaço.

Quebrado
erDiagram
    CLIENTE ||--o{ PEDIDO
Corrigido
erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"

O que você vê

Parse error, terminando em: got 'UNICODE_TEXT'

Por quê

Um token de cardinalidade inválido. Só valem `||`, `o|`, `}|` e `}o` (e seus espelhos); qualquer outra coisa falha. `oo` é o erro de digitação de sempre, por esperar que a notação seja simétrica.

Solução

Use um dos quatro pares. `||--o{` — exatamente um para zero ou mais — cobre a maioria das chaves estrangeiras.

Quebrado
erDiagram
    CLIENTE ||--oo{ PEDIDO : "realiza"
Corrigido
erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"

O que você vê

Parse error, terminando em: Expecting 'ATTRIBUTE_WORD', got 'BLOCK_STOP'

Por quê

Um atributo com nome e sem tipo. Atributos ER são `tipo nome`, e o tipo não é opcional — o que surpreende quem vem de bancos sem esquema.

Solução

Dê um tipo a cada atributo. Invente um se o esquema real não tiver: `string`, `int`, `json`.

Quebrado
erDiagram
    CLIENTE {
        email
    }
Corrigido
erDiagram
    CLIENTE {
        string email
    }

O que você vê

Parse error, terminando em: Expecting 'NON_IDENTIFYING', 'IDENTIFYING', got 'UNICODE_TEXT'

Por quê

A linha entre as duas marcas de cardinalidade está errada. Ela precisa ter exatamente dois caracteres: `--` para um relacionamento identificador ou `..` para um não identificador. Um hífen só não é uma versão curta de `--`, é erro de sintaxe.

Solução

Use `--` ou `..` entre os pares de cardinalidade.

Quebrado
erDiagram
    CLIENTE ||-o{ PEDIDO : "realiza"
Corrigido
erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"

O que você vê

A cardinalidade desenha, mas descreve a restrição contrária

Por quê

Os dois caracteres mais próximos de cada entidade pertencem àquela entidade, e é facílimo lê-los ao contrário. `CLIENTE ||--o{ PEDIDO` diz que um cliente tem zero ou mais pedidos. Inverta para `CLIENTE }o--|| PEDIDO` e você afirmou que todo cliente pertence a exatamente um pedido, o que não faz sentido — e desenha sem reclamar.

Solução

Leia do centro para fora: as marcas que tocam CLIENTE descrevem quantos clientes, não quantos pedidos.

Quebrado
erDiagram
    CLIENTE }o--|| PEDIDO : "realiza"
Corrigido
erDiagram
    CLIENTE ||--o{ PEDIDO : "realiza"

Notas sobre a renderização

Medido no Mermaid 11.12.2 que este site usa.

O layout é ditado pelos relacionamentos, não pelo número de entidades

Uma cadeia de entidades ligadas uma à seguinte desenha como uma coluna alta: quarenta entidades dão um viewBox de aproximadamente 116×7315, contra 116×470 com três. Mas essas mesmas quarenta entidades ligadas a uma única tabela central produzem algo bem mais largo e baixo. É o único tipo de diagrama daqui em que o formato dos seus dados muda o formato do desenho mais que o tamanho dele, então um esquema que não cabe se resolve mais vezes mudando quais relacionamentos você desenha do que quantos.

Em português quase todo rótulo precisa de aspas

Vale insistir porque é a falha silenciosa mais cara desta página. Em inglês os rótulos de relacionamento costumam ter uma palavra só — places, contains, references —, então na documentação inglesa as aspas parecem enfeite. Em português a maioria são locuções com preposição e quebram sem aspas. A regra prática: ponha sempre o rótulo entre aspas e você não precisa mais pensar nisso.

Nomes de entidade diferenciam maiúsculas e por convenção vão em caixa alta

`CLIENTE` e `cliente` são duas entidades distintas, e mencionar as duas no mesmo diagrama dá duas caixas sem aviso. A convenção da caixa alta não é imposta pelo Mermaid, mas vale manter justamente porque deixa evidente qualquer referência em minúsculas escrita por descuido. Acentos funcionam sem problema em nomes de entidade e de coluna; o que convém é decidir de saída se o esquema leva acentos ou não e não misturar.

A gramática é a mais rígida dos seis tipos

Rótulos de relacionamento são obrigatórios, tipos de atributo também, e os tokens de cardinalidade formam um conjunto fechado. Comparado com o Gantt, onde quase tudo desenha e os erros são mudos, o ER falha cedo e em voz alta. Isso é uma virtude: se um diagrama ER desenhou, é bem provável que seja o diagrama que você queria — com a exceção notável dos rótulos sem aspas.

Os rótulos são HTML, então a exportação para PNG redesenha

As tabelas de atributos das entidades são desenhadas dentro de um `<foreignObject>` do SVG, então os navegadores não conseguem rasterizá-las direto num canvas. A exportação para PNG deste site devolvia antes um arquivo SVG em silêncio; agora ela redesenha primeiro com rótulos em texto SVG simples e produz um PNG correto e em tamanho cheio, com tipografia mal perceptivelmente diferente.

Quando usar outro diagrama

Se você precisa de herança, interfaces ou métodos, este é o diagrama errado: o ER não tem nenhum desses conceitos. Use um diagrama de classes e aceite que ele modela o seu código, não as suas tabelas.

Se o esquema é grande, um ER do esquema inteiro vira um painel de parede que ninguém lê. Desenhe as cinco tabelas envolvidas naquilo que você está explicando e deixe o resto de fora; um diagrama é um argumento, não um inventário.

E se a pergunta real é como os dados se movem entre sistemas em vez de como são armazenados, um fluxograma com um subgrafo por sistema responde e um ER não.

Outros tipos de diagrama

Escrito por Dominik Malsch · Última atualização:

Abrir o editor →