ลงทะเบียน
ชั้นเรียนกระบวนการ
การแสดงออกทางกราฟิก
การคิด
การแสดงออกที่มีโครงสร้าง
หมายเหตุ
การแสดงออกอย่างมีประสิทธิภาพ

แผนภาพ ERไวยากรณ์

แผนภาพ ER

แผนภาพความสัมพันธ์เชิงเอนทิตี (เรียกสั้น ๆ ว่าแผนภาพ ER) อธิบายสิ่งต่าง ๆ ที่น่าสนใจซึ่งมีความสัมพันธ์กันในแวดวงความรู้เฉพาะ แผนภาพ ER พื้นฐานประกอบด้วยประเภทเอนทิตี (ใช้จัดหมวดหมู่สิ่งต่าง ๆ ที่น่าสนใจ) และระบุความสัมพันธ์ที่สามารถมีได้ระหว่างเอนทิตี (อินสแตนซ์ของประเภทเอนทิตีเหล่านี้),โปรดทราบว่าในการใช้งานจริงของแผนภาพ ER เกือบทุกครั้งจะเรียก 'ประเภทเอนทิตี' สั้น ๆ ว่า 'เอนทิตี' ตัวอย่างเช่น 'ประเภทเอนทิตี CUSTOMER' มักเรียกตรง ๆ ว่า 'เอนทิตี CUSTOMER' การปฏิบัติเช่นนี้พบได้ทั่วไปมาก จึงไม่แนะนำให้ใช้วิธีอื่น แต่ในทางเทคนิคแล้ว เอนทิตีคืออินสแตนซ์เชิงนามธรรมของประเภทเอนทิตี และแผนภาพ ER แสดงอินสแตนซ์เชิงนามธรรมเหล่านี้และความสัมพันธ์ระหว่างกัน นี่คือเหตุผลว่าทำไมเอนทิตีจึงตั้งชื่อด้วยคำนามเอกพจน์เสมอ

โค้ด
                            
คัดลอก
ฝัง
--- title: Order example --- erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ LINE-ITEM : contains CUSTOMER }|..|{ DELIVERY-ADDRESS : uses

ชื่อเอนทิตีมักเป็นตัวพิมพ์ใหญ่ แม้ว่าจะไม่มีมาตรฐานที่เป็นที่ยอมรับในเรื่องนี้ และไวยากรณ์ของ Mermaid ก็ไม่ได้บังคับ

ความสัมพันธ์ระหว่างเอนทิตี แสดงด้วยเส้นที่มีเครื่องหมายที่ปลายซึ่งระบุคาร์ดินาลิตี Mermaid ใช้สัญลักษณ์เท้ารวมซึ่งเป็นที่นิยมที่สุด ซึ่งแสดงอย่างชัดเจนว่าเอนทิตีที่มันเชื่อมต่ออยู่อาจมีอินสแตนซ์ได้หลายตัว

แผนภาพ ER ใช้ได้หลากหลายวัตถุประสงค์ ตั้งแต่แบบจำลองเชิงตรรกะเชิงนามธรรมที่ไม่มีการรายละเอียดการนำไปใช้ใด ๆ ไปจนถึงแบบจำลองทางกายภาพของตารางฐานข้อมูลเชิงสัมพันธ์ การใส่คำจำกัดความของคุณสมบัติในแผนภาพ ER ช่วยให้เข้าใจจุดประสงค์และความหมายของเอนทิตี คำจำกัดความของคุณสมบัติเหล่านี้ไม่จำเป็นต้องครบถ้วนสมบูรณ์ โดยทั่วไปคุณสมบัติเพียงส่วนเล็ก ๆ ก็เพียงพอแล้ว Mermaid อนุญาตให้กำหนดคุณสมบัติเหล่านี้ด้วยประเภทและชื่อได้

โค้ด
                            
คัดลอก
ฝัง
erDiagram CUSTOMER ||--o{ ORDER : places CUSTOMER { string name string custNumber string sector } ORDER ||--|{ LINE-ITEM : contains ORDER { int orderNumber string deliveryAddress } LINE-ITEM { string productCode int quantity float pricePerUnit }

เมื่อใส่คุณสมบัติในแผนภาพ ER คุณต้องตัดสินใจว่าจะรวมคีย์นอกเป็นคุณสมบัติหรือไม่ ซึ่งอาจขึ้นอยู่กับว่าคุณต้องการแสดงโครงสร้างตารางเชิงสัมพันธ์มากเพียงใด หากแผนภาพของคุณเป็นแบบจำลองเชิงตรรกะและไม่ได้ตั้งใจจะสื่อถึงการนำไปใช้เชิงสัมพันธ์ ก็ไม่ควรใส่คุณสมบัติเหล่านี้ เนื่องจากความสัมพันธ์ได้สื่อถึงวิธีการเชื่อมโยงระหว่างเอนทิตีแล้ว ตัวอย่างเช่น โครงสร้างข้อมูล JSON สามารถใช้ array เพื่อสร้างความสัมพันธ์แบบหนึ่งต่อหลายโดยไม่มีคุณสมบัติคีย์นอกได้ ในทำนองเดียวกัน ภาษาโปรแกรมเชิงวัตถุสามารถใช้พอยน์เตอร์หรือการอ้างอิงไปยังคอลเลกชันได้ แม้กระทั่งสำหรับแบบจำลองที่มุ่งนำไปใช้เชิงสัมพันธ์ ก็อาจเห็นได้ว่าการใส่คุณสมบัติคีย์นอกเป็นการแสดงข้อมูลที่ความสัมพันธ์ได้แสดงไปแล้วซ้ำ และไม่ได้เพิ่มความหมายให้กับเอนทิตี

ไวยากรณ์

เอนทิตีและความสัมพันธ์

ไวยากรณ์ Mermaid ของแผนภาพ ER เข้ากันได้กับ PlantUML และได้ขยายความสามารถสำหรับการติดป้ายกำกับความสัมพันธ์ แต่ละคำสั่งประกอบด้วยสิ่งต่อไปนี้:

                            
คัดลอก
ฝัง
<first-entity> [<relationship> <second-entity> : <relationship-label>]
  • first-entity เป็นชื่อของเอนทิตีแรก ชื่อรองรับอักขระ Unicode ใดก็ได้ และหากล้อมด้วยเครื่องหมายอัญประกาศคู่ ก็สามารถมีช่องว่างได้
  • relationship อธิบายความสัมพันธ์ระหว่างสองเอนทิตี
  • second-entity เป็นชื่อของอีกเอนทิตีหนึ่ง
  • relationship-label อธิบายความสัมพันธ์โดยมองจากมุมของเอนทิตีแรก

ตัวอย่าง:

                            
คัดลอก
ฝัง
PROPERTY ||--|{ ROOM : contains

คำสั่งนี้สามารถเข้าใจได้ว่า: คุณสมบัติหนึ่งประกอบด้วยห้องหนึ่งห้องหรือมากกว่า ส่วนห้องหนึ่งห้องเป็นของทรัพย์สินเพียงหนึ่งเดียว ป้ายกำกับที่นี่มองจากมุมของเอนทิตีแรก: ทรัพย์สินหนึ่งประกอบด้วยห้องหนึ่งห้อง แต่ห้องหนึ่งห้องไม่ได้ประกอบด้วยทรัพย์สิน เมื่อมองจากมุมของเอนทิตีที่สอง โดยทั่วไปป้ายกำกับที่เทียบเท่ากันสามารถอนุมานได้ง่าย

มีเพียงส่วน first-entity เท่านั้นที่บังคับ ซึ่งทำให้สามารถแสดงเอนทิตีที่ไม่มีความสัมพันธ์ได้ ซึ่งมีประโยชน์มากเมื่อสร้างแผนภาพแบบทำซ้ำ หากระบุส่วนอื่นของคำสั่ง ส่วนทั้งหมดจะต้องกรอก

ข้อความ Unicode

ชื่อเอนทิตี ความสัมพันธ์ และคุณสมบัติ รองรับข้อความ unicode ทั้งหมด

โค้ด
                            
คัดลอก
ฝัง
erDiagram "This ❤ Unicode"

ไวยากรณ์ของความสัมพันธ์

ส่วนความสัมพันธ์ของแต่ละคำสั่งสามารถแยกออกเป็นสามส่วนย่อยได้:

  • คาร์ดินาลิตีของเอนทิตีแรกเมื่อเทียบกับเอนทิตีที่สอง
  • ความสัมพันธ์นี้ให้การระบุเอกลักษณ์แก่เอนทิตีย่อยหรือไม่
  • คาร์ดินาลิตีของเอนทิตีที่สองเมื่อเทียบกับเอนทิตีแรก

คาร์ดินาลิตีเป็นคุณสมบัติที่ใช้อธิบายจำนวนองค์ประกอบที่อีกเอนทิตีหนึ่งสามารถเชื่อมโยงกับเอนทิตีที่เกี่ยวข้องได้ ในตัวอย่างด้านบน PROPERTY หนึ่งสามารถเชื่อมโยงกับอินสแตนซ์ ROOM หนึ่งตัวหรือมากกว่า ส่วน ROOM หนึ่งตัวสามารถเชื่อมโยงกับ PROPERTY ได้เพียงหนึ่งตัว เครื่องหมายคาร์ดินาลิตีแต่ละอันมีสองอักขระ อักขระชั้นนอกสุดแทนค่ามากสุด อักขระชั้นในสุดแทนค่าน้อยสุด ตารางด้านล่างสรุปความเป็นไปได้ของคาร์ดินาลิตี:

ค่า (ซ้าย) ค่า (ขวา) ความหมาย
|o o| ศูนย์หรือหนึ่ง
|| || หนึ่งพอดี
}o o{ ศูนย์หรือหลาย (ไม่มีขีดจำกัดบน)
}| |{ หนึ่งหรือหลาย (ไม่มีขีดจำกัดบน)
นามแฝง
ค่า (ซ้าย) ค่า (ขวา) ความหมาย
one or zero one or zero ศูนย์หรือหนึ่ง
zero or one zero or one ศูนย์หรือหนึ่ง
one or more one or more หนึ่งหรือหลาย
one or many one or many หนึ่งหรือหลาย
many(1) many(1) หนึ่งหรือหลาย
1+ 1+ หนึ่งหรือหลาย
zero or more zero or more ศูนย์หรือหลาย
zero or many zero or many ศูนย์หรือหลาย
many(0) many(0) ศูนย์หรือหลาย
0+ 0+ ศูนย์หรือหลาย
only one only one หนึ่งพอดี
1 1 หนึ่งพอดี

การระบุเอกลักษณ์

ความสัมพันธ์สามารถแบ่งได้เป็นแบบระบุเอกลักษณ์และแบบไม่ระบุเอกลักษณ์ โดยเรนเดอร์เป็นเส้นทึบหรือเส้นประตามลำดับ สิ่งนี้สำคัญเมื่อเอนทิตีหนึ่งไม่สามารถดำรงอยู่ได้อย่างอิสระหากไม่มีอีกเอนทิตีหนึ่ง ตัวอย่างเช่น บริษัทที่ให้ประกันสำหรับการขับรถของบุคคลอาจต้องจัดเก็บข้อมูล NAMED-DRIVER เมื่อสร้างแบบจำลอง เราอาจสังเกตก่อนว่า CAR หนึ่งคันสามารถขับได้โดย PERSON หลายคน และ PERSON หนึ่งคนสามารถขับ CAR ได้หลายคัน ทั้งสองสามารถดำรงอยู่ได้โดยไม่ต้องมีอีกฝ่าย ดังนั้นนี่จึงเป็นความสัมพันธ์แบบไม่ระบุเอกลักษณ์ ซึ่งเราสามารถระบุใน Mermaid ได้เป็น: PERSON }|..|{ CAR : "driver" โปรดสังเกตจุดสองจุดตรงกลางความสัมพันธ์ ซึ่งจะทำให้วาดเส้นประระหว่างสองเอนทิตี อย่างไรก็ตาม เมื่อความสัมพันธ์แบบหลายต่อหลายนี้แยกออกเป็นความสัมพันธ์แบบหนึ่งต่อหลายสองความสัมพันธ์ เราสังเกตว่า NAMED-DRIVER ไม่สามารถดำรงอยู่ได้หากไม่มี PERSON และ CAR ความสัมพันธ์เหล่านี้กลายเป็นความสัมพันธ์แบบระบุเอกลักษณ์ และจะแสดงด้วยเครื่องหมายขีดกลาง ซึ่งก็คือเส้นทึบ:

ค่า นามแฝง
-- การระบุ
.. ไม่ระบุ
นามแฝง
ค่า 别名为
to การระบุ
optionally to ไม่ระบุ
โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR ||--o{ NAMED-DRIVER : allows PERSON }o..o{ NAMED-DRIVER : is
โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR ||--o{ NAMED-DRIVER : allows PERSON }o--o{ NAMED-DRIVER : is

คุณสมบัติ

สามารถกำหนดคุณสมบัติให้กับเอนทิตีได้โดยระบุชื่อเอนทิตี ตามด้วยบล็อกที่มี type name หลายรายการ โดยบล็อกถูกล้อมด้วยวงเล็บปีกกา {} คุณสมบัติจะแสดงภายในกล่องเอนทิตี ตัวอย่าง:

โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR ||--o{ NAMED-DRIVER : allows CAR { string registrationNumber string make string model } PERSON ||--o{ NAMED-DRIVER : is PERSON { string firstName string lastName int age }

ค่า type ต้องขึ้นต้นด้วยอักขระตัวอักษร และสามารถมีตัวเลข ขีดกลาง ขีดล่าง วงเล็บเล็ก และวงเล็บเหลี่ยมได้ ค่า name มีรูปแบบคล้ายกับ type แต่สามารถขึ้นต้นด้วยเครื่องหมายดอกจันได้เช่นกัน ซึ่งเป็นอีกทางเลือกหนึ่งในการบ่งชี้ว่าคุณสมบัติเป็นคีย์หลัก นอกเหนือจากนี้ไม่มีข้อจำกัดอื่น และไม่มีชุดประเภทข้อมูลที่ถูกต้องโดยนัย

นามแฝงของเอนทิตี

สามารถใช้วงเล็บเหลี่ยมเพื่อเพิ่มนามแฝงให้กับเอนทิตีได้ หากมีนามแฝง แผนภาพจะแสดงนามแฝงแทนชื่อเอนทิตี โดยนามแฝงปฏิบัติตามกฎทั้งหมดเช่นเดียวกับชื่อเอนทิตี

โค้ด
                            
คัดลอก
ฝัง
erDiagram p[Person] { string firstName string lastName } a["Customer Account"] { string email } p ||--o| a : has

คีย์และความคิดเห็นของคุณสมบัติ

คุณสมบัติยังสามารถกำหนดคีย์หรือความคิดเห็นได้ คีย์อาจเป็นคีย์หลัก (PK) คีย์นอก (FK) หรือคีย์เฉพาะ (UK) หากต้องการระบุข้อจำกัดคีย์หลายรายการบนคุณสมบัติเดียว ให้ใช้จุลภาคแยก (เช่น PK, FK) ความคิดเห็นถูกกำหนดโดยเครื่องหมายอัญประกาศคู่ที่ส่วนท้ายของคุณสมบัติ และความคิดเห็นไม่สามารถมีอักขระเครื่องหมายอัญประกาศคู่ได้

โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR ||--o{ NAMED-DRIVER : allows CAR { string registrationNumber PK string make string model string[] parts } PERSON ||--o{ NAMED-DRIVER : is PERSON { string driversLicense PK "The license #" string(99) firstName "Only 99 characters are allowed" string lastName string phone UK int age } NAMED-DRIVER { string carRegistrationNumber PK, FK string driverLicence PK, FK } MANUFACTURER ||--o{ CAR : makes

ทิศทาง

คำสั่งทิศทางประกาศทิศทางของแผนภาพ

TB ประกาศว่าทิศทางของแผนภาพคือจากบนลงล่าง ส่วน BT สามารถกลับทิศทางเป็นจากล่างขึ้นบนได้

โค้ด
                            
คัดลอก
ฝัง
erDiagram direction TB CUSTOMER ||--o{ ORDER : places CUSTOMER { string name string custNumber string sector } ORDER ||--|{ LINE-ITEM : contains ORDER { int orderNumber string deliveryAddress } LINE-ITEM { string productCode int quantity float pricePerUnit }

LR ประกาศว่าทิศทางของแผนภาพคือจากซ้ายไปขวา ส่วน RL สามารถกลับทิศทางเป็นจากขวาไปซ้ายได้

โค้ด
                            
คัดลอก
ฝัง
erDiagram direction LR CUSTOMER ||--o{ ORDER : places CUSTOMER { string name string custNumber string sector } ORDER ||--|{ LINE-ITEM : contains ORDER { int orderNumber string deliveryAddress } LINE-ITEM { string productCode int quantity float pricePerUnit }

ตั้งค่าสไตล์ของโหนด

สามารถนำสไตล์เฉพาะไปใช้กับโหนดได้ เช่น ขอบที่หนาขึ้นหรือสีพื้นหลังที่ต่างออกไป

โค้ด
                            
คัดลอก
ฝัง
erDiagram id1||--||id2 : label style id1 fill:pink,stroke:yellow,stroke-width:4px style id2 fill:#69d,stroke:#f96,stroke-width:2px,color:#fff,stroke-dasharray: 5 5

ยังสามารถแนบสไตล์กับรายการโหนดในคำสั่งเดียวได้:

                            
คัดลอก
ฝัง
style nodeId1,nodeId2 styleList

คลาส

สะดวกกว่าการกำหนดสไตล์ทุกครั้งคือการกำหนดคลาสสไตล์ แล้วแนบคลาสนั้นกับโหนดที่ต้องการรูปลักษณ์ที่ต่างออกไป

การกำหนดคลาสมีดังตัวอย่างต่อไปนี้:

                            
คัดลอก
ฝัง
classDef className fill:pink,stroke:#333,stroke-width:4px

ยังสามารถกำหนดหลายคลาสในคำสั่งเดียวได้:

                            
คัดลอก
ฝัง
classDef firstClassName,secondClassName font-size:12pt

ไวยากรณ์สำหรับแนบคลาสกับโหนดมีดังนี้:

                            
คัดลอก
ฝัง
class nodeId1 className

ยังสามารถแนบคลาสหนึ่งกับรายการโหนดในคำสั่งเดียวได้:

                            
คัดลอก
ฝัง
class nodeId1,nodeId2 className

ยังสามารถแนบหลายคลาสพร้อมกันได้:

                            
คัดลอก
ฝัง
class nodeId1,nodeId2 className1,className2

วิธีที่สะดวกในการเพิ่มคลาสคือการใช้ตัวดำเนินการ ::: เพื่อแนบชื่อคลาสกับโหนด ดังที่แสดงด้านล่าง:

โค้ด
                            
คัดลอก
ฝัง
erDiagram direction TB CAR:::someclass { string registrationNumber string make string model } PERSON:::someclass { string firstName string lastName int age } HOUSE:::someclass classDef someclass fill:#f96

การประกาศความสัมพันธ์ระหว่างเอนทิตีสามารถใช้ไวยากรณ์ต่อไปนี้:

โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR { string registrationNumber string make string model } PERSON { string firstName string lastName int age } PERSON:::foo ||--|| CAR : owns PERSON o{--|| HOUSE:::bar : has classDef foo stroke:#f00 classDef bar stroke:#0f0 classDef foobar stroke:#00f

คล้ายกับคำสั่ง class ไวยากรณ์แบบย่อก็สามารถนำหลายคลาสไปใช้ในคราวเดียวได้เช่นกัน:

                            
คัดลอก
ฝัง
nodeId:::className1,className2

คลาสเริ่มต้น

หากคลาสใดมีชื่อว่า default มันจะถูกกำหนดให้กับโหนดทั้งหมดที่ไม่มีคำจำกัดความคลาสเฉพาะ

                            
คัดลอก
ฝัง
classDef default fill:pink,stroke:#333,stroke-width:4px;

หมายเหตุ: สไตล์แบบกำหนดเองที่มาจากคำสั่ง style หรือคำสั่งคลาสอื่นมีลำดับความสำคัญสูงกว่า และจะเขียนทับสไตล์เริ่มต้น (ตัวอย่างเช่น คลาส default ตั้งค่าพื้นหลังสีชมพูให้กับโหนด แต่หากนำคลาส blue ไปใช้ จะให้สีพื้นหลังสีน้ำเงินกับโหนดนั้น)

โค้ด
                            
คัดลอก
ฝัง
erDiagram CAR { string registrationNumber string make string model } PERSON { string firstName string lastName int age } PERSON:::foo ||--|| CAR : owns PERSON o{--|| HOUSE:::bar : has classDef default fill:pink,stroke-width:4px classDef foo stroke:#f90 classDef bar stroke:#ff0 classDef foobar stroke:#69f

การกำหนดค่า

เลย์เอาต์

เลย์เอาต์ของแผนภาพจัดการโดย render() เลย์เอาต์เริ่มต้นคือเลย์เอาต์ ELK ซึ่งเหมาะสำหรับแผนภาพขนาดใหญ่และซับซ้อนกว่า

หากต้องการเปลี่ยนไปใช้เลย์เอาต์ Dagre แบบคลาสสิก คุณสามารถตั้งค่าได้ใน config ของ YAML frontmatter

โค้ด
                            
คัดลอก
ฝัง
--- config: layout: dagre ---

เนื้อหาโค้ด Mermaid มีดังนี้:

โค้ด
                            
คัดลอก
ฝัง
--- title: Order example config: layout: elk --- erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ LINE-ITEM : contains CUSTOMER }|..|{ DELIVERY-ADDRESS : uses