结果和最终代码:

结果和最终代码:

代码中的创造力时刻已经到来!

我想做一个实体关系模型(ER模型)使用tikzpicture环境。

我发现TikZ实际上有一个用于该内容的库(\usetikzlibrary{er})和其他东西,但实际上我不需要颜色或奇怪的形状来创建以下通用 ER 图:

我想要的 ER 图

手册er没有提到创建关系也没有提到围绕实体的标签,所以这对我来说很困难。

一般注意事项

  • 存在四种关系可能性(其组合则处于另一个极端):关系类型
  • 一个实体可以有一个、几个或没有属性,一个属性在另一个属性之下(字母大小小于实体的文本)。
  • 实体必须有坐标才能添加标签(尺寸小于属性)。注意其子实体is in之间的标签。Entity C
  • 实体之间的关系可能具有折叠/正交性。
  • 属性必须有\scriptsize字体。

使其发生!

编辑(MWE 添加)

谢谢CarLaTeX 的有用评论我又取得了一些进步:

\documentclass{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}

\usepackage{pdflscape}

% code for "one to omany", etc. is taken from https://tex.stackexchange.com/q/141797/101651
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
    \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-8pt}{6pt}}% 
    \pgfusepathqstroke%
}

\pgfarrowsdeclare{omany}{omany}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
    \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%  
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}% 
    \pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
    \pgfusepathqstroke%
}

\pgfarrowsdeclare{one}{one}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-6pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-6pt}{6pt}}% 
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-8pt}{6pt}}%    
    \pgfusepathqstroke%
}
\makeatother

\tikzset{%
    pics/entity/.style n args={3}{code={%
        \node[draw,
        rectangle split,
        rectangle split parts=2,
        text height=1.5ex,
        ] (#1)
        {#2 \nodepart{second}
            \begin{tabular}{>{\raggedright\arraybackslash}p{8.5em}}
                #3
            \end{tabular}
        };%
    }},
    pics/entitynoatt/.style n args={2}{code={%
        \node[draw,
        text height=1.5ex,
        ] (#1)
        {#2};%
    }},
    zig zag to/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag to/.default=0.5,   
    one to one/.style={
        one-one, zig zag to
    },
    one to oone/.style={            % I do not how to make "one to Optional-one" rel
        one-one, zig zag to
    },
    one to many/.style={
        one-crow's foot, zig zag to,
    },
    one to omany/.style={
        one-omany, zig zag to
    }
}

\begin{document}

\begin{landscape}
    \begin{center}
        \begin{tikzpicture}
            \pic {entity={A}{Entity A}{%
                attribute 1 \\
                attribute 2 \\        
                ... \\
                attribute i
            }};
            \pic[right=7em of A] {entity={AB}{Entity A for Entity B}{%
                attribute 1 \\
                attribute 2
            }};
            \pic[right=7em of AB] {entity={B}{Entity B}{%
                attribute 1 \\
                attribute 2 \\        
                ... \\
                attribute i
            }};
            \pic[below=16ex of B] {entity={C}{Entity C}{%
                attribute 1    
            }};
            \pic[below=15ex of AB] {entitynoatt={C1}{Entity C\_1}};
            \pic[below=9ex of C1] {entitynoatt={C2}{Entity C\_2}};
            \draw[one to omany] (A.east) -- node[above]{\footnotesize is in} (AB.west);
            \draw[one to omany] (B.west) -- node[above]{\footnotesize is in} (AB.east);
            \draw[one to one] (B.south) -- node[right]{\footnotesize is in} (C.north);
            \draw[one to oone] (C.west) -| ($(C.west)!.5!(C1.east)$) |- node[above]{\footnotesize is in} (C1.east);  % Make "oone" rel
            \draw[one to oone] (C.west) -| ($(C.west)!.5!(C2.east)$) |- node[below]{\footnotesize is in} (C2.east);  % Make "oone" rel
            \end{tikzpicture}
    \end{center}
\end{landscape}

\end{document}

我走了多远

不过,有些地方我想修改一下:

  • 在实体的#1参数(标签)中添加新行。
  • 在可选基数中用白色圆圈代替透明圆圈。
  • 当两个曲线关系在同一点时,减少该部分的厚度,因为从远处看它似乎更厚:减小厚度
  • 建立“一对可选一”和“可选一对可选一”的关系。
  • 将关系之间的标签放置在实体的外边缘。

CarLaTeX 的评论之后我想要什么

一些链接

谢谢!

答案1

在实体的 #1 参数(标签)中添加新行

只需声明一个text width=...,然后就可以\\在节点描述中使用。

在可选基数中用白色圆圈代替透明圆圈。

\pgfsetfillcolor{white}和已完成\pgfusepathqfillstroke

当在同一点找到两个弯曲关系时,减少该部分的厚度,因为从远处看它似乎更厚:减少厚度。

确实,因为它被绘制了两次所以更厚,我采用了一个技巧只绘制一次(第二条路径只绘制到交叉点)。

建立“一对可选一”和“可选一对可选一”的关系。

创建one to ooneoone to none或多或少oone to oone复制自我之前的回答,也是从这里

将关系之间的标签放置在实体的外边缘。

由于标签与路径并不严格相关,只需将一些节点放在所需的位置即可。

属性必须有\scriptsize字体。

添加[font=\scriptsize]\nodepart

\documentclass{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}

\usepackage{pdflscape}

% code for "one to omany", etc. is taken from https://tex.stackexchange.com/q/141797/101651
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
    \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-8pt}{6pt}}% 
    \pgfusepathqstroke%
}

\pgfarrowsdeclare{omany}{omany}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
    \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%  
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}% 
    \pgfusepathqstroke%
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
    \pgfusepathqfillstroke%
}

\pgfarrowsdeclare{one}{one}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-6pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-6pt}{6pt}}% 
    \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-8pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-8pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-8pt}{6pt}}%    
    \pgfusepathqstroke%
}

\pgfarrowsdeclare{oone}{oone}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    %\advance\pgfutil@tempdima by.25\pgflinewidth%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
     \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
    \pgfpathmoveto{\pgfqpoint{-4pt}{-6pt}}% 
    \pgfpathlineto{\pgfqpoint{-4pt}{-6pt}}%  
    \pgfpathlineto{\pgfqpoint{-4pt}{6pt}}% 
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
    \pgfusepathqfillstroke%
}
\makeatother

\tikzset{%
    mylabel/.style={font=\footnotesize},
    pics/entity/.style n args={3}{code={%
        \node[draw,
        rectangle split,
        rectangle split parts=2,
        text height=1.5ex,
        text width=8.5em,
        text centered
        ] (#1)
        {#2 \nodepart[font=\scriptsize]{second}
            \begin{tabular}{>{\raggedright\arraybackslash}p{9em}}
                #3
            \end{tabular}
        };%
    }},
    pics/entitynoatt/.style n args={2}{code={%
        \node[draw,
        text height=1.5ex,
        text width=8.5em,
        text centered
        ] (#1)
        {#2};%
    }},
    zig zag to/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag to/.default=0.5,   
    one to one/.style={
        one-one, zig zag to
    },
    one to oone/.style={% One to Optional-one
        one-oone, zig zag to
    },
    oone to none/.style={% Optional-one to none
        oone-, zig zag to
    },
    oone to oone/.style={% Optional one to Optional-one
        oone-oone, zig zag to
    },
    one to many/.style={
        one-crow's foot, zig zag to,
    },
    one to omany/.style={
        one-omany, zig zag to
    },
    one to none/.style={
        one-, zig zag to
    },    
}

\begin{document}

\begin{landscape}
    \begin{center}
        \begin{tikzpicture}
            \pic {entity={A}{Entity A}{%
                attribute 1 \\
                attribute 2 \\        
                ... \\
                attribute i
            }};
            \pic[right=7em of A] {entity={AB}{{Entity A \\ for \\ Entity B}}{%
                attribute 1 \\
                attribute 2
            }};
            \pic[right=7em of AB] {entity={B}{Entity B}{%
                attribute 1 \\
                attribute 2 \\        
                ... \\
                attribute i
            }};
            \pic[below=16ex of B] {entity={C}{Entity C}{%
                attribute 1    
            }};
            \pic[below=15ex of AB] {entitynoatt={C1}{Entity C\textunderscore 1}};
            \pic[below=9ex of C1] {entitynoatt={C2}{Entity C\textunderscore 2}};
            \draw[one to omany] (A.east) -- (AB.west);
            \node[mylabel, anchor=south east] at (A.north east) {is in};
            \draw[one to omany] (B.west) -- (AB.east);
            \node[mylabel, anchor=south west] at (B.north west) {is in};
            \draw[one to one] (B.south) -- (C.north);
            \node[mylabel, anchor=south west] at (B.south east) {is in};
            \node[mylabel, anchor=north west] at (C.north east) {is in};
            %From section 13.3 of the TikZ manual, (2,1 |- 3,4) and (3,4 -| 2,1) both yield the same as (2,4) 
            \coordinate (mymiddle) at ($(C.west)!.5!(C1.east)$);
            \coordinate (mylink) at (C.west -| mymiddle);
            \draw[one to oone] (C.west) -| (mymiddle) node[mylabel, above=10pt]{is in} |- (C1.east);  % Make "oone" rel
            \draw[oone to none] (C2.east) -|  node[mylabel, below=2pt]{is in} (mylink);
            \end{tikzpicture}
    \end{center}
\end{landscape}
\end{document}

在此处输入图片描述

答案2

我回答得太晚了,没能获得赏金,但@CarLaTeX 值得,因为她为你做了大量研究。

您的问题和杰出贡献者的评论激励我解决您的问题。对此我表示感谢。

首先,使用pdflscape包来拥有格式的页面是没有意义的landscape:它是文章类的原生选项:\documentclass[landscape]{article}

将旧代码 v 1.18 与新代码 3.0.1a 进行转录:

您的代码的操作\pgfarrowsdeclare未记录在 TikZ 3.0.1a 版中。此操作可在手册第 317 页找到1.18(可用这里可供下载)。

我按照手册的语法转录了他的代码3.0.1a,现在调用该操作\pgfdeclarearrow(名称被反转,参见 3.0.1a 手册第 1017 页)。

我注意到这个旧代码很笨拙:许多操作根本没有必要,而且什么也不做。我删除了所有注释行,因为在前面加 是没用的\pgfpathlineto\pgfpathmoveto\pgfpathlineto足够了。

    \pgfarrowsdeclare{omany}{omany}
{
    \pgfarrowsleftextend{+-.5\pgflinewidth}%
    \pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
    \pgfutil@tempdima=0.6pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\pgfutil@tempdima}}%
    \pgfpathlineto{\pgfqpoint{-13\pgfutil@tempdima}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\pgfutil@tempdima}}%
 %   \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%  
 %   \pgfpathmoveto{\pgfqpoint{0\pgfutil@tempdima}{0\pgfutil@tempdima}}%
  %  \pgfpathmoveto{\pgfqpoint{-6pt}{-6pt}}% 
    \pgfpathcircle{\pgfpoint{-11.5pt}{0}} {3.5pt}
    \pgfusepathqstroke%
}

因此我清除了所有关系箭头的代码。

箭头现在根据线条的粗细改变比例。

\arrowsize我使用了一个为此调用的 TeX 注册表。

从现在开始,箭头会根据线的粗细略微增加\pgflinewidth

\arrowsize=0.5pt%
\advance\arrowsize by .25\pgflinewidth

C和之间的线的粗细问题C1 C2

这是由于您在放置C1和时计算错误C2,因为这两个节点的中间不在的正中间 C

因此,为了避免复杂的计算,我以不同的方式构建了你的图表:我放置C1C2 相对的C不是正如您对 所做的那样AB

\pic[above left=2ex and 7em of C] {entitynoatt={C1}{Entity C\_1}};
\pic[below left=2ex and 7em of C] {entitynoatt={C2}{Entity C\_2}};

为了放置标签,我创建了一个名为的图片,is in其参数是angle它的anchor

is in/.pic={\node[label=#1:is in,outer sep=0pt,minimum size=0pt]{};}

实体关系图符号

由于我不知道实体关系图符号,所以我在网上搜索了一下。看来这些符号没有标准化,因此我们可以自由地根据自己的喜好进行设计。

因此,在这一点上地点,绘制如下:

er1

这个以及:

er2

ETC。

这是我的建议:

我画了不同粗细的线来直观地展示箭头长度的变化。名称箭头上写着多于, 这线尺寸以下。

我的建议

我刚刚打电话给他们:

  • mmany表示“强制性的许多”;
  • omany表示“可选多个”;
  • mone为“强制性的”;
  • oone“可选”

他们的代码如下:

\documentclass[tikz,border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mmany,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
    \pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
    \pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}% 
    \pgfusepathqstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = omany,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
    \pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
    \pgfusepathqstroke%
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
    \pgfusepathqfillstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mone,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}% 
    \pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%    
    \pgfusepathqstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = oone,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth
    \pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}% 
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
    \pgfusepathqfillstroke%
    },
defaults = { }
}

\begin{document}

\begin{tikzpicture}[every node/.style={font=\scriptsize}]
\draw[mmany - mmany,very thin] (0,0) -- node[above]{ mmany}node[below]{very thin} (5,0);
\draw[omany - omany] (0,-1) -- node[above]{omany}node[below]{normal size} (5,-1);
\draw[mone - mone,thick] (0,-2) -- node[above]{mone}node[below]{thick} (5,-2);
\draw[oone - oone,very thick] (0,-3) -- node[above]{ oone}node[below]{very thick} (5,-3);
\end{tikzpicture}
\end{document}

使用边缘操作连接实体

zig-zag从样式中删除了该选项relationship。这样就可以edges用它来构建relationship arrows它们entities,然后只需通过它们的名称来调用它们。

\draw[one to omany] (A) edge  (AB);
\draw[one to omany] (B) edge  (AB);
\draw[one to one] (B) edge  (C);
\path[one to oone,zig zag] (C1) edge (C); % by default zig zag=.5
\path[one to oone,zig zag=.5 ] (C2) edge (C);% 

结果和最终代码:


图表

\documentclass[landscape]{article}
\usepackage{array}
\renewcommand{\arraystretch}{1.1}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
%\usetikzlibrary{er}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mmany,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
    \pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
    \pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}% 
    \pgfusepathqstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = omany,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{0pt}{-9\arrowsize}}%
    \pgfpathlineto{\pgfqpoint{-13\arrowsize}{0pt}}%
    \pgfpathlineto{\pgfqpoint{0pt}{9\arrowsize}}%
    \pgfusepathqstroke%
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
    \pgfusepathqfillstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = mone,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth%
    \pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}% 
    \pgfpathmoveto{\pgfqpoint{-19\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-19\arrowsize}{10\arrowsize}}%    
    \pgfusepathqstroke%
    },
defaults = { }
}

\pgfdeclarearrow{ %page 1020 of 3.0.1a manual
name = oone,
parameters = { },
setup code = { },
drawing code = {
    \newdimen\arrowsize%
    \arrowsize=0.5pt%
    \pgfsetdash{}{+0pt}%
    \pgfsetmiterjoin%
    \advance\arrowsize by .25\pgflinewidth
    \pgfpathmoveto{\pgfqpoint{-9\arrowsize}{-10\arrowsize}}% 
    \pgfpathlineto{\pgfqpoint{-9\arrowsize}{10\arrowsize}}% 
    \pgfsetfillcolor{white}
    \pgfpathcircle{\pgfpoint{-19\arrowsize}{0}} {6\arrowsize}%
    \pgfusepathqfillstroke%
    },
defaults = { }
}


\tikzset{%
    is in/.pic={\node[label=#1:is in,outer sep=0pt,minimum size=0pt]{};},
    pics/entity/.style n args={3}{code={%
        \node[draw,
        rectangle split,
        rectangle split parts=2,
        text height=1.5ex,
        ] (#1)
        {#2 \nodepart{second}
            \begin{tabular}{>{\raggedright\arraybackslash}p{8.5em}}
                #3
            \end{tabular}
        };%
    }},
    pics/entitynoatt/.style n args={2}{code={%
        \node[draw,
        text height=1.5ex,
        ] (#1)
        {#2};%
    }},
    zig zag/.style={
        to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
    },
    zig zag/.default=0.5, 
    one to one/.style={
        mone-mone, 
    },
    one to oone/.style={
        mone-oone
    },
    one to many/.style={
        mone-mmany,
    },
    one to omany/.style={
        mone-omany
    }
}
\begin{document}

\begin{center}
\begin{tikzpicture}
[every node/.style={ minimum width=4cm},
every second node part/.style={font=\small},
every label/.style={minimum size=0pt}
]
\pic {entity={A}{Entity A}{%
    attribute 1 \\
    attribute 2 \\        
    ... \\
    attribute i
}};
\pic at (A.north east){is in=0};
\pic[right=7em of A] {entity={AB}{Entity A for Entity B}{%
    attribute 1 \\
    attribute 2
}};
\pic[right=7em of AB] {entity={B}{Entity B}{%
    attribute 1 \\
    attribute 2 \\        
    ... \\
    attribute i
}};
\pic at (B.north west){is in=180};
\pic at (B.south east){is in=0};

\pic[below=16ex of B] {entity={C}{Entity C}{%
    attribute 1    
}};
\pic at (C.north east){is in=0};
\pic[above left=2ex and 7em of C] {entitynoatt={C1}{Entity C\_1}};
\pic[below left=2ex and 7em of C] {entitynoatt={C2}{Entity C\_2}};
\pic at (C1.north east){is in=30};
\pic at (C2.south east){is in=-30};
\draw[one to omany] (A) edge  (AB);
\draw[one to omany] (B) edge  (AB);
\draw[one to one] (B) edge  (C);
\path[one to oone,zig zag] (C1) edge (C);  
\path[one to oone,zig zag] (C2) edge (C);% 

\end{tikzpicture}
\end{center}

\end{document}

使用 www.DeepL.com/Translator 翻译

相关内容