购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5 图结构语言

图从业者、学者和工程师普遍同意解释图数据的术语和方法。但是,技术界和学术界对这些词的使用却令人困惑。有些词对图数据库从业者来说是一种含义,而对图数据科学家来说则另有一番含义。

为了解决领域之间的困惑,我们在本书中引入并正式推出了描述图结构(graph schema)的术语。这种语言称为图结构语言或GSL。GSL是一种可视化语言,将概念应用于图数据库结构的创建。

我们创造GSL作为一种教学工具,用来说明本书所有的例子。我们打造、推介和使用GSL的目的是规范化图实践者之间沟通图的概念模型、图结构和图数据库设计的方式。对我们来说,这套术语和视觉图示补充了学术界普及的图语言和图社区内的标准。

本节中介绍的视觉提示和术语将会应用在整本书的概念图模型中。我们希望接下来即将看到的许多示例可以作为将视觉示意图转换为结构代码的良好实践。

2.5.1 顶点标签和边标签

图数据的基本元素——顶点和边——给我们提供了图结构语言的第一组术语:顶点标签和边标签。如图2-3所示,关系型模型使用表结构来描述数据,我们用顶点标签和边标签来描述一幅图的结构。

顶点标签

顶点标签是指一组语义上同构的对象。即一个顶点标签代表一类共享同样的关系和属性的对象。

边标签

边标签用来在数据库结构里给顶点标签之间的关系的类型命名。

在图建模中,我们给实体打上顶点标签,然后用边标签来描述实体之间的关系。

通常来说,顶点标签描述数据中的实体,共享相同类型的属性和相同标签的关系。边标签描述顶点标签之间的关系。

顶点和边这两个术语用来特指数据。在描述数据库的结构时,我们使用顶点标签和边标签。

对于表2-1的数据,我们同样对客户和账户进行概念图模型建模,如图2-6所示。这个概念图模型和图2-3中的ERD看起来很像,只是使用了GSL中的前两个术语。

图2-6:展示了客户和银行账户的顶点和边标签的图模型

在GSL中,顶点标签用包含标签名字的圆圈表示,见图2-6中的Customer(客户)和Account(账户)顶点标签。边标签是两个顶点标签之间带有名称的线。图2-6中可以看到边标签owns(拥有),连接了Customer和Account两个顶点标签。再看这个图示,这里暗含了客户有一条指向账户的关系,具体来说就是客户(Customer)拥有(owns)账户(Account)。稍后我们会在2.5.3节介绍边的方向。

2.5.2 属性

如图2-3所示,在关系型模型中,我们用attribute来描述数据,用图建模时,则用property来描述数据。也就是说,以前用attribute的地方,现在使用property。

属性

属性描述的是顶点标签或边标签的自有特征,例如名称、日期或是其他描述性特征。

在图2-7中,每个顶点标签都关联了一系列属性。这些属性和图2-3里的关系型ERD中的attribute是一样的。我们可以用它的唯一标识符、姓名和生日来描述一个客户顶点。和以前一样,账户则可以用它的账户ID、创建日期来描述。在这个数据模型中,我们添加了一个边标签owns(拥有)来描述这两个实体之间的关系。

图2-7:客户和银行账户的图模型

注意:术语属性(property)应用在图结构和图数据的概念中。

2.5.3 边的方向

GSL中的下一个建模概念是边的方向。在数据模型中建立边标签时,通常根据谈论数据的方式将顶点标签连接起来。我们会说客户拥有账户,在图中建模数据的时候也用这种方式。这也使得每条边有了一个方向。

边的方向有两种建模方式:有向的和双向的。

有向的

有向边是单向的:从一个顶点标签到另一个顶点标签。

双向的

双向(bidirectional或bidirected)边可以从任意方向连接顶点标签。

在GSL里,在某一端或者两端使用箭头来表明边的方向。如图2-8所示,在边标签的下面可以看到箭头。

图2-8:使用线和单向箭头来表明边标签是有向的

我们可以说图2-8中的例子表示了一条有向边标签。我们有一个边标签从客户连到账户。这个边标签用了一条有向边来建模客户拥有这个账户。

除此之外,在建模反方向的数据时,它也可能很有用。一种方式是添加第二条从账户到客户的有向边。这条边表示账户被客户拥有,如图2-9所示。我们可以说图2-9中的边都是有向边,因为它们都是单向的。

图2-9:使用两条不同方向的边使我们可以在客户和账户之间穿梭

边标签的方向来源于用语言描述数据的方式。当你描述数据时,会使用主语、谓语(比如动词)和宾语来描述你的领域。要看到这个,考虑你会如何描述本章到此为止用到过的样本数据。你可能会想到类似于“客户拥有账户”,或者“银行账户被客户拥有”之类的表达。在第一个短语中,主语是“客户”,谓语是“拥有”,宾语则是“账户”。这就给我们一个顶点标签的来源,Customer(客户),以及目标顶点标签,Account(账户)。谓语“拥有”(owns)则转化成边标签,并且方向是从客户到他们的账户。我们应用类似的方式来得到从账户到客户的边标签“被拥有”(owned_by)。

笼统地讲,识别出描述中的主谓宾可以转化为边标签的方向。主语是第一个顶点标签,也是边开始的地方。在GSL中,我们称之为领域(domain)。然后谓语转换成边标签。最后,宾语是边标签的目标或者范围。这意味着边标签从领域来,到范围去,这里提出了两个新的术语:

领域

边标签的领域是指该标签开始或源起的顶点标签。

范围

边标签的范围是指该标签结束或指向的顶点标签。

本节的最后一个概念是双向边。到这里我们讨论过的数据里,并没有语义上的含义需要双向边。也就是说,我们可以说客户拥有账户,但是“账户拥有客户”则不成立。我们需要把边标签改成“账户被客户所拥有”。

为了更好地阐述双向边,让我们在例子中加入客户之间的关系。具体来说,互为家庭成员的客户之间连上边标签。如图2-10所示,这是一个更好的例子来阐明双向边标签。

图2-10:使用一条有双箭头的边来表明这条边标签是双向的

在这个模型中,我们表示客户可以是其他客户的家庭成员。我们把这种类型的关系解释成一种相互关系:如果你是其他人的家庭成员,那么他们也是你的家庭成员。在GSL中,我们用一条带有双向箭头的线来建模这个,并说这种边标签是双向的。

在图理论中,双线边和无向边是等价的。也就是说,同时用两个方向建模一个关系,本质上和没有任何特定意义是一样的。然而,在本书的上下文中,我们使用数据之间的关系来提供应用程序的意义,因此必须考虑边的方向。

当第一次遇到方向的概念时,可能不是一个很直观的概念。在图开发中,思考方向的最佳方法是从你如何谈论数据开始。我们建议为你的数据创建一个描述,并确定如何解释其中的关系。这有助于把对数据关系的概念转化为边缘标签的方向的理解。

2.5.4 自指向边标签

虽然没有明确指出,但在图2-10中我们已经引入了一个新的概念,现在我们来定义一下。如果一条边的开始和结束都在同一个顶点标签上,我们说这是一条自指向( self-referencing )边标签。在GSL中,我们如图2-11所示描绘和标识该标签。

自指向

自指向边标签是指一条边标签的领域和范围是同一个顶点标签。

图2-11:在GSL中使用边标签来表示双向的、指向自己的边

图2-11是描述开始和结束在同一个顶点标签上的边标签的正确方式。我们说这是一条自指向边标签。在图2-11的场景中,这也是一个双向边标签,然而,不是所有的自指向标签都是双向的。

你会在后文看到有向的、自指向边标签的例子。这个场景例如,当你需要建模一个循环的关系——具体来说就是当某些东西包含在其他东西中时,或者当有父子关系时。

2.5.5 图的多样性

当你开始深入理解用图来建模数据时,你可能会想要一种方式来展示不同顶点标签之间可能存在多少种关系。

对这个问题我们有个好消息。在大多数图模型里,只有一种方式用来描述关系的数量:many(的)。

在DataStax Graph和大部分其他图数据库里,所有的边标签都代表多对多(many-to-many)关系。也就意味着,任何顶点都可以通过一条特定的边标签连接到多个其他顶点。这在ERD中被称为多对多(many-to-many),在UML中使用0..*到0..*。有时在一些关系型社区中也表示为m:n的关系。

我们用多样性来表示这个概念:

多样性

多样性是对一个组合可能承担的可允许的大小范围的一种规范。也就是说,多样性描述了与特定顶点相邻的顶点组沿着特定的边标签可能承担的、可允许的大小范围 [2]

集合(set)或合集(collection)的实际大小被称为基数(cardinality)。基数被定义为一个特定集合或合集中元素的有限数量。

为正确和清晰起见,在谈论图结构中的边标签建模时,我们只使用术语“多样性”。让我们更深入地了解一下当你在图模型中应用多样性的定义时的两种选择。

在GSL中建模多样性

多样性在图结构中的应用归根结底是要理解相邻顶点间可能会有不同类型的组合。但只有两种可能:集合或是合集。

集合

集合是一种抽象的数据类型,存储不包含重复元素的值。

合集

合集是一种抽象的数据类型,存储包含重复元素的值。

在一个相邻顶点的集合中,每个顶点只存在一个实例。在一组相邻顶点的合集中,一个顶点可能多次出现。我们用图2-12来解释这两个方式的区别。

图2-12:对某一特定边标签的相邻顶点组应用多样性的两种方式

图2-12中左图显示,与Michael相邻的顶点组合是一个集合:{acct_0}。这意味着我们希望数据库中客户和账户之间最多存在一条边。图2-12中右图显示,与Michael相邻的顶点组是一个合集:[acct_0,acct_0]。这表示我们希望数据库中客户和账户之间可以有多条边。一个需要多条边的场景是,当你希望表示一个客户既是账户的管理员又是用户的时候。

最有可能需要决定多样性类型的场景是当你对边进行时间建模的时候。你只想在数据库中找到时间上最近的边吗?那么你就可以认为边是一个集合。如果你需要知道所有的边在一段时间内的情况,那么你就可以认为边是一个合集。我们将在第7章、第9章和第12章中讨论边的时间问题。

让我们来看看如何在GSL中模拟图2-12中两张图之间的差异。

图2-13展示了我们如何使用GSL中的一条线来说明两个顶点之间最多只有一条边。

为了能够对两个顶点之间的许多边进行建模,我们需要一种方法使一条边与另一条边不同。在图2-14中,我们在边上添加了角色(role)属性,这样每条边都是不同的。图2-14展示了我们如何在GSL中使用双线和属性值来说明我们想在两个顶点之间有许多条边。

图2-13:在GSL中,我们用一条单线来表明相邻顶点的组合需要是一个集合

图2-14:在GSL中,我们用一条双线来表明相邻顶点的组合需要是一个合集

理解多样性的诀窍在于理解你的数据。如果你需要在两个顶点之间有多条边——因为你需要连接的顶点组是一个合集,而不是一个集合——那么你就需要在边上定义一个属性,使其独一无二。

2.5.6 图模型的完整示例

使用GSL将表2-1中的数据转换为图2-15中的概念图模型。

我们把图2-15中的图称为概念图模型。这个模型创建了图数据库结构。这个概念图模型显示了一个客户和三个与其有关的不同数据点。这四个实体转化为四个独立的顶点标签:客户(Customer)、账户(Account)、贷款(Loan)和信用卡(CreditCard)。

这四个数据之间有三种关系:客户拥有账户、使用信用卡,还可以借用贷款。这在概念图模型中创建了三个边标签:分别是拥有(owns)、使用(uses)和借用(owes)。所有这三个边标签都是有向的;在这个例子中没有双向的边标签。此外,我们看到边标签uses和owes在两个顶点之间最多只有一条边,而owns可以有许多条边。

图2-15中最后要探讨的是每个顶点标签上显示的属性。这些是我们可以在表2-1的数据中找到的对应属性。一个Customer有两个属性:customer_id和name。Account、CreditCard和Loan顶点标签各自只有一个属性,分别是:acct_id、cc_num和loan_id。对它们各自来说,该属性都是这个数据的唯一标识符。

图2-15:第一个例子的开端:一个金融服务客户数据的基础模型

理解图2-15和我们在图2-4中展示的实例数据之间的区别很重要。图2-15展示了使用GSL为数据库结构建立的概念图模型。图2-4展示了数据在你的图数据库中的样子。 k4R848mcBtFi+bhHoMRCzh97Lwop9rACOv/3Tl0+M2mN7B68ODjmcguuDwTDiX4Z

点击中间区域
呼出菜单
上一章
目录
下一章
×