本文通过一个简单的零售场景阐述如何根据传统的表数据进行图建模,从而得到图数据。
表数据
零售场景中最基础的三张表分别是客户表、商户表、交易表。其中交易表记录了客户在购买商品时向商户支付钱款的转账行为。
- 客户表 CUSTOMER 字段:
字段名 | 含义 | 举例 |
---|---|---|
cust_no | 客户号(主键) | 100250090 |
cust_name | 客户姓名 | Zhang San |
risk_level | 风险评级(1~10) | 4 |
card_level | 持卡等级(1~10) | 3 |
balance | 余额 | 10000.11 |
... | ... | ... |
- 商户表 MERCHANT 字段:
字段名 | 含义 | 举例 |
---|---|---|
merchant_no | 商户号(主键) | RS00JF1DF |
merchant_name | 商户名称 | Beijing Science and Technology Co. Ltd |
type | 类别 | IV |
... | ... | ... |
- 交易表 TRANSCTION 字段:
字段名 | 含义 | 举例 |
---|---|---|
cust_no | 客户号(外键) | 100250090 |
merchant_no | 商户号(外键) | RS00JF1DF |
tran_date | 交易日期(timestamp) | 2022-03-21 22:12:56 |
tran_amount | 交易金额 | 123.45 |
tran_type | 交易类型(1~20) | 13 |
result | 是否成功(Y/N) | Y |
... | ... | ... |
TRANSCTION 中的“外键”如果超出了 CUSTOMER、MERCHANT 中“主键”的范围,入图时可将该外键所在的交易数据视为无效,或先创建该外键所代表的客户或商户之后将该外键所在的交易数据视为有效,对于这一点,Manager 和 Transporter 的处理方式不同。
图数据
将表数据转为图数据的过程即为图建模。最简单的建模方法是将表数据划分为实体表和关系表两类,将每一张实体表作为图的一个点 schema,将每一张关系表作为图的一个边 schema,表中的字段作为其所对应 schema 的属性。
实体表通常比较容易识别,上面的客户表 CUSTOMER 和商户表 MERCHANT 就是实体表,它们分别代表了零售场景下的客户、商户这两类实体。
关系表的识别则依赖于实体表,因为关系表体现的是多张实体表之间的关系,所以,一张关系表中需要有至少两个代表实体表主键的外键。上面的交易表 TRANSACTION 的两个外键分别为客户表主键 cust_no
和商户表主键 merchant_no
,因此可以将交易表视为一张关系表。
有时为了业务需要,可能会将关系表也定性为实体表,评判的依据包括但不限于图模型的可扩展性、业务 UQL 语句的复杂程度以及运行效率等,此处不做深入讨论。
将上面的客户表和商户表分别作为点 schema customer
和 merchant
,将交易表作为边schema transfer
。请注意,这里边 schema 没有延用交易表的名称,而是使用了一个动词,原因是 Ultipa 图系统中的边是有方向的,即边是由起点指向终点的,边上的动词代表起点发出的动作,这能更好地从语义层面解释边的方向。

以下分别是 customer
、merchant
、transfer
这三个 schema 的属性:
- 点 schema
customer
属性名 | 数据类型 | 属性类型 |
---|---|---|
_id | string | 系统属性 |
cust_name | string | 自定义属性 |
risk_level | int32 | 自定义属性 |
card_level | int32 | 自定义属性 |
balance | float | 自定义属性 |
... | ... | ... |
系统属性 _id
是图集内点的唯一标识符(不隶属于schema),在此处就是原先客户表的主键 cust_no
,其数据类型 string 的最大长度为 128;其余自定义属性的数据类型 string 的最大长度为 65535。Ultipa 支持的小数类型有 float 和 double,所占字节数和数据精度各不相同,请根据数据要求、数据量以及磁盘大小等合理选择。
- 点 schema
merchant
属性名 | 数据类型 | 属性类型 |
---|---|---|
_id | string | 系统属性 |
merchant_name | string | 自定义属性 |
type | string | 自定义属性 |
... | ... | ... |
此处的系统属性 _id
就是原先商户表的主键 merchant_no
。
- 边 schema
transfer
属性名 | 数据类型 | 属性类型 |
---|---|---|
_from | string | 系统属性 |
_to | string | 系统属性 |
tran_date | timestamp | 自定义属性 |
tran_amount | float | 自定义属性 |
tran_type | int32 | 自定义属性 |
result | string | 自定义属性 |
... | ... | ... |
系统属性 _from
是边起点的 _id
,此处就是外键之一 cust_no
;_to
是边终点的 _id
,此处就是另一个外键 merchant_no
。入图时必须提供这两个属性的值。
schema 和属性的命名规则:2~64个字符,以字母开始,由字母、数字、下划线构成。
有时为了业务需要,可能会将原始数据表中的某个字段定义为 schema,评判的依据包括但不限于图模型的可扩展性、业务 UQL 语句的复杂程度以及运行效率等。这部分与前面提到的“将关系表定性为实体表”的情况类似,不做深入讨论。