Miễn phí · Không cần đăng ký · Hỗ trợ tệp .mmd

Trình tạo sơ đồ ER Mermaid

Sơ đồ thực thể - liên kết cho thấy các bảng, các cột của chúng và cách chúng nối với nhau. Nó hợp khi chủ đề là lược đồ cơ sở dữ liệu và những câu hỏi đáng quan tâm xoay quanh khóa và bội số — một-nhiều, tùy chọn, hay thông qua một bảng trung gian. Với các kiểu có hành vi và kế thừa thì sơ đồ lớp tốt hơn.

Lược đồ đơn hàng đã chuẩn hóa với bảng trung gian

Phần đáng chú ý là `}o--||` ở dòng đơn hàng: đó là cách diễn đạt trung thực một liên kết nhiều-nhiều, thông qua bảng trung gian có cột riêng, thay vì giả vờ rằng hai bảng nối thẳng với nhau. Việc lưu giá ngay trên dòng chứ không chỉ trên sản phẩm đúng là loại quyết định mà sơ đồ nên phơi bày. Cũng để ý mọi nhãn liên kết đều nằm trong dấu nháy: với tiếng Việt đó không phải tùy chọn.

erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"
    DON_HANG ||--|{ DONG_DON_HANG : "gồm có"
    SAN_PHAM ||--o{ DONG_DON_HANG : "xuất hiện trong"
    KHACH_HANG ||--o{ DIA_CHI : "giao đến"
    DON_HANG ||--o| HOA_DON : "được xuất cho"

    KHACH_HANG {
        int id PK
        string email UK "lưu ở dạng chữ thường"
        string ho_ten
        string so_dien_thoai
        datetime ngay_tao
    }
    DON_HANG {
        int id PK
        int khach_hang_id FK
        string trang_thai
        decimal tong_tien
    }
    DONG_DON_HANG {
        int don_hang_id PK, FK
        int san_pham_id PK, FK
        int so_luong
        decimal don_gia "giá tại thời điểm đặt hàng"
    }
    SAN_PHAM {
        int id PK
        string ma_hang UK
        string ten_san_pham
    }
    DIA_CHI {
        int id PK
        int khach_hang_id FK
        string phuong_xa
    }
    HOA_DON {
        int id PK
        string so_hoa_don UK
        decimal tien_thue
    }
Mở cái này trong trình soạn thảo
Quảng cáo

Ví dụ có giải thích

1. Hai thực thể và một liên kết

Mọi liên kết ER đều đòi một nhãn sau dấu hai chấm — khác với cạnh của lưu đồ, nó không phải tùy chọn. Đọc lên như một câu: KHACH_HANG đặt DON_HANG.

erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"
Mở trong trình soạn thảo

2. Thêm các cột

Mỗi dòng thuộc tính là `kiểu tên` và cả hai phần đều bắt buộc. `PK`, `FK` và `UK` đánh dấu khóa; chuỗi trong dấu nháy ở cuối là ghi chú cho cột.

erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"
    KHACH_HANG {
        int id PK
        string email UK
        string ho_ten
    }
    DON_HANG {
        int id PK
        int khach_hang_id FK
        datetime ngay_dat "theo giờ UTC"
    }
Mở trong trình soạn thảo

3. Bội số nói lên điều gì đó

Hai ký hiệu gần một thực thể nhất chính là bội số của nó. Ví dụ này nói rằng một đơn hàng phải có ít nhất một dòng, nhưng một khách hàng có thể chưa có đơn hàng nào: một ràng buộc thật mà lược đồ nên bắt buộc và sơ đồ nên cho thấy.

erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"
    DON_HANG ||--|{ DONG_DON_HANG : "gồm có"
    DONG_DON_HANG }o--|| SAN_PHAM : "tham chiếu tới"
Mở trong trình soạn thảo

4. Nhiều-nhiều thông qua bảng trung gian

Mermaid vẽ được liên kết nhiều-nhiều trực tiếp, nhưng trong lược đồ thật gần như không bao giờ có: bên dưới luôn là một bảng trung gian. Vẽ nó ra thì trung thực hơn và chừa chỗ cho những cột thuộc về chính mối liên kết đó.

erDiagram
    HOC_VIEN ||--o{ DANG_KY : "ghi danh vào"
    KHOA_HOC ||--o{ DANG_KY : "được mở qua"
    DANG_KY {
        int hoc_vien_id PK, FK
        int khoa_hoc_id PK, FK
        datetime ngay_dang_ky
        string diem "để trống cho tới khi thi"
    }
    HOC_VIEN {
        int id PK
        string ho_ten
    }
    KHOA_HOC {
        int id PK
        string ma_khoa UK
    }
Mở trong trình soạn thảo

5. Liên kết tự tham chiếu

Một bảng có thể liên kết với chính nó: cây quản lý, cây danh mục, chuỗi bình luận. Nhãn liên kết ở đây quan trọng hơn bình thường, vì cả hai đầu đều là cùng một thực thể.

erDiagram
    NHAN_VIEN ||--o{ NHAN_VIEN : "quản lý"
    NHAN_VIEN {
        int id PK
        int quan_ly_id FK "để trống với ban giám đốc"
        string ho_ten
        string chuc_danh
    }
Mở trong trình soạn thảo

Tóm tắt cú pháp sơ đồ ER

Bội số viết bằng hai ký hiệu ở mỗi đầu liên kết và đọc từ trong ra ngoài. Cặp bên trái mô tả thực thể bên trái, cặp bên phải mô tả thực thể bên phải.

Cú phápÝ nghĩa
erDiagramMở sơ đồ. Phân biệt hoa thường: `erdiagram` không chạy.
A ||--o{ B : "nhãn"Liên kết. Nhãn là bắt buộc.
||Đúng một.
o|Không hoặc một.
}|Một hoặc nhiều.
}oKhông hoặc nhiều.
--Liên kết định danh — đường liền.
..Liên kết không định danh — đường đứt.
A { ... }Khối thuộc tính của thực thể A.
int id PKThuộc tính: kiểu trước, tên sau, rồi tới ký hiệu khóa nếu có.
PK / FK / UKKhóa chính, khóa ngoại, khóa duy nhất.
int id PK, FKNhiều ký hiệu khóa, ngăn nhau bằng dấu phẩy.
string email "ghi chú"Chuỗi trong dấu nháy ở cuối là ghi chú cho cột.
A ||--o{ B : "thuộc về"Dấu nháy là BẮT BUỘC ngay khi nhãn có khoảng trắng. Không có nó, nhãn bị cắt ở khoảng trắng đầu tiên và mỗi chữ còn lại biến thành một thực thể ma.
Quảng cáo

Sáu lỗi làm hỏng sơ đồ ER

ER có ngữ pháp chặt nhất trong sáu loại: thứ lọt được ở sơ đồ khác thì ở đây bị từ chối thẳng. Nhưng nó cũng có một lỗi im lặng mà người viết tiếng Việt đặc biệt dễ mắc. Tất cả đều dựng lại trên Mermaid 11.12.2.

Bạn thấy gì

Vẽ được, nhãn bị cắt cụt, và trong sơ đồ xuất hiện những thực thể bạn không hề viết

Vì sao

Nhãn liên kết có khoảng trắng mà không có dấu nháy. Đây là lỗi gây phiền nhất với tiếng Việt, vì tiếng Việt viết rời từng âm tiết nên hầu như mọi động từ quan hệ đều nhiều chữ: «đặt hàng», «thuộc về», «xuất hiện trong». Đã đo: `KHACH_HANG ||--o{ DON_HANG : đặt hàng` không báo lỗi nào, rút nhãn còn «đặt» và tạo ra một thực thể rỗng tên «hàng». Với ba chữ thì sinh ra hai thực thể ma. Hai bảng vẽ thành bốn hình chữ nhật và không có gì cảnh báo bạn — ngoài việc viewBox nhảy từ 128 lên 398 pixel.

Cách sửa

Đặt dấu nháy quanh mọi nhãn có khoảng trắng. Với tiếng Việt điều đó gần như luôn đúng; coi nó là quy tắc thì dễ hơn là cân nhắc từng lần.

Sai
erDiagram
    KHACH_HANG ||--o{ DON_HANG : đặt hàng
Đúng
erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt hàng"

Bạn thấy gì

Parse error, kết thúc bằng: Expecting 'COLON', 'STYLE_SEPARATOR', got 'NEWLINE'

Vì sao

Liên kết không có nhãn. Khác với cạnh của lưu đồ, dấu hai chấm và nhãn là bắt buộc: thiếu chúng thì dòng đơn giản là kết thúc quá sớm.

Cách sửa

Thêm dấu hai chấm và một cụm động từ, đặt trong dấu nháy nếu có khoảng trắng.

Sai
erDiagram
    KHACH_HANG ||--o{ DON_HANG
Đúng
erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"

Bạn thấy gì

Parse error, kết thúc bằng: got 'UNICODE_TEXT'

Vì sao

Ký hiệu bội số không hợp lệ. Chỉ có `||`, `o|`, `}|` và `}o` là đúng (cùng dạng đối xứng của chúng); mọi thứ khác đều đổ. `oo` là lỗi gõ kinh điển, xuất phát từ giả định rằng ký pháp này đối xứng.

Cách sửa

Dùng một trong bốn cặp. `||--o{` — đúng một tới không hoặc nhiều — bao được phần lớn khóa ngoại.

Sai
erDiagram
    KHACH_HANG ||--oo{ DON_HANG : "đặt"
Đúng
erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"

Bạn thấy gì

Parse error, kết thúc bằng: Expecting 'ATTRIBUTE_WORD', got 'BLOCK_STOP'

Vì sao

Một thuộc tính có tên nhưng không có kiểu. Thuộc tính ER viết theo dạng `kiểu tên`, và kiểu không phải tùy chọn — điều này làm những người quen với cơ sở dữ liệu không lược đồ bất ngờ.

Cách sửa

Cho mỗi thuộc tính một kiểu. Cứ đặt ra nếu lược đồ thật không có: `string`, `int`, `json`.

Sai
erDiagram
    KHACH_HANG {
        email
    }
Đúng
erDiagram
    KHACH_HANG {
        string email
    }

Bạn thấy gì

Parse error, kết thúc bằng: Expecting 'NON_IDENTIFYING', 'IDENTIFYING', got 'UNICODE_TEXT'

Vì sao

Đường nối giữa hai ký hiệu bội số bị sai. Nó phải dài đúng hai ký tự: `--` cho liên kết định danh hoặc `..` cho liên kết không định danh. Một dấu gạch ngang đơn không phải dạng rút gọn của `--`, đó là lỗi cú pháp.

Cách sửa

Viết `--` hoặc `..` giữa hai cặp bội số.

Sai
erDiagram
    KHACH_HANG ||-o{ DON_HANG : "đặt"
Đúng
erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"

Bạn thấy gì

Bội số vẽ ra được, nhưng lại mô tả ràng buộc ngược lại

Vì sao

Hai ký hiệu gần một thực thể nhất thuộc về đúng thực thể đó, và đọc ngược chúng thì rất dễ. `KHACH_HANG ||--o{ DON_HANG` nói rằng một khách hàng có không hoặc nhiều đơn hàng. Lật thành `KHACH_HANG }o--|| DON_HANG` là bạn đang khẳng định mỗi khách hàng thuộc về đúng một đơn hàng, điều chẳng có nghĩa gì — và nó vẽ ra không một lời phản đối.

Cách sửa

Đọc từ trong ra ngoài: những ký hiệu chạm vào KHACH_HANG mô tả có bao nhiêu khách hàng, chứ không phải bao nhiêu đơn hàng.

Sai
erDiagram
    KHACH_HANG }o--|| DON_HANG : "đặt"
Đúng
erDiagram
    KHACH_HANG ||--o{ DON_HANG : "đặt"

Ghi chú về việc vẽ

Đo trên Mermaid 11.12.2, đúng phiên bản trang này dùng.

Bố cục do các liên kết quyết định, không phải do số lượng thực thể

Một chuỗi thực thể nối lần lượt vào nhau sẽ vẽ thành một cột cao: bốn mươi thực thể cho viewBox khoảng 116×7315, so với 116×470 khi có ba. Nhưng cũng bốn mươi thực thể ấy mà cùng nối vào một bảng trung tâm thì cho ra thứ rộng hơn và thấp hơn rất nhiều. Đây là loại sơ đồ duy nhất ở đây mà hình dạng dữ liệu của bạn làm thay đổi hình dạng bức tranh nhiều hơn là kích thước của nó, nên một lược đồ không vừa khung thường được chữa bằng cách đổi xem vẽ những liên kết nào chứ không phải bao nhiêu liên kết.

Với tiếng Việt, gần như nhãn nào cũng cần dấu nháy

Điều này đáng nhắc lại vì đây là lỗi im lặng tốn kém nhất trên trang này. Nhãn liên kết tiếng Anh có thể chỉ một chữ — places, contains, references — nên trong tài liệu tiếng Anh dấu nháy trông như đồ trang trí. Tiếng Việt viết rời từng âm tiết, nên gần như nhãn nào cũng nhiều chữ và không có dấu nháy thì rã ra. Quy tắc thực dụng: luôn đặt nhãn trong dấu nháy rồi thôi không nghĩ về nó nữa.

Tên thực thể phân biệt hoa thường; hãy chọn một cách viết rồi giữ nguyên

`KHACH_HANG` và `khach_hang` là hai thực thể khác nhau, và nhắc tới cả hai trong một sơ đồ sẽ cho ra hai hình chữ nhật mà không cảnh báo gì. Mermaid không ép quy ước viết hoa, nhưng nên theo nó chính vì nó làm lộ ra tham chiếu viết thường do sơ ý. Dấu tiếng Việt dùng được trong tên thực thể, nhưng vì tên thực thể là định danh nên khoảng trắng thì không: hãy chọn dấu gạch dưới như `DONG_DON_HANG` hoặc viết liền, rồi giữ nguyên cách đó trong cả lược đồ.

Ngữ pháp chặt nhất trong sáu loại

Nhãn liên kết là bắt buộc, kiểu thuộc tính cũng vậy, và các ký hiệu bội số tạo thành một tập đóng. So với Gantt, nơi gần như thứ gì cũng vẽ ra và lỗi thì im lặng, ER đổ sớm và đổ ồn ào. Đó là một ưu điểm: nếu một sơ đồ ER đã vẽ ra được thì khá nhiều khả năng nó đúng là sơ đồ bạn định vẽ — trừ ngoại lệ rõ ràng là nhãn thiếu dấu nháy.

Nhãn là HTML, nên việc xuất PNG phải vẽ lại

Bảng thuộc tính của các thực thể được vẽ bên trong một `<foreignObject>` trong SVG, nên trình duyệt không thể chuyển thẳng chúng thành ảnh raster trên canvas. Chức năng xuất PNG của trang này trước đây lặng lẽ trả về tệp SVG; giờ nó vẽ lại sơ đồ bằng nhãn văn bản SVG thuần trước và cho ra tệp PNG đúng, đủ kích thước, với kiểu chữ chỉ khác đi rất khẽ.

Khi nào nên dùng loại sơ đồ khác

Nếu bạn cần kế thừa, giao diện hay phương thức thì đây là loại sơ đồ sai: ER không có khái niệm nào trong số đó. Hãy dùng sơ đồ lớp và chấp nhận rằng nó mô hình hóa mã nguồn của bạn chứ không phải các bảng của bạn.

Nếu lược đồ lớn, một sơ đồ ER vẽ trọn vẹn sẽ thành tấm áp phích dán tường không ai đọc. Hãy vẽ năm cái bảng liên quan tới điều bạn đang giải thích lúc đó và để phần còn lại ngoài khung; sơ đồ là một lập luận chứ không phải một bản kiểm kê.

Còn nếu câu hỏi thật sự là dữ liệu chảy giữa các hệ thống thế nào chứ không phải nó được lưu ra sao, thì một lưu đồ với mỗi hệ thống một nhóm con sẽ trả lời được, còn sơ đồ ER thì không.

Các loại sơ đồ khác

Viết bởi Dominik Malsch · Cập nhật lần cuối:

Mở trình soạn thảo →