在设计 Nebula Graph 的数据模型时,合理划分点(Vertex)和边(Edge)的属性是关键。这直接影响查询效率、数据冗余度和模型可维护性。以下是一些基本原则和实用技巧:
- 点(Vertex):表示实体(如用户、商品、文章),由 VID(Vertex ID) 唯一标识,包含一组 标签(Tag),每个标签可定义多个属性。
- 边(Edge):表示实体间的关系(如关注、购买、评论),由 起点、终点、边类型(Edge Type) 和 Rank(可选) 唯一标识,也可包含属性。
- 属于实体自身的特性 → 点属性
- 例如:用户的姓名、年龄、注册时间;商品的价格、品牌、类别。
- 属于实体间关系的特性 → 边属性
- 例如:用户关注的时间、购买的数量 / 金额、评论的内容 / 时间。
示例:社交网络模型
- 高基数属性(变化频繁)→ 边属性
- 例如:用户每次登录的 IP、时间;订单的支付状态。
- 低基数属性(相对固定)→ 点属性
理由:边属性可随关系变化单独更新,避免频繁修改点数据。
- 查询时常用作过滤条件的属性 → 适当冗余存储
- 例如:查询 “用户最近购买的电子产品”,可将商品类别(本属点属性)冗余到购买边中。
示例:电商模型
- 传统关系型数据库中的关联表 → Nebula 中的边
- 例如:用户 - 角色(多对多)在 Nebula 中建模为用户点与角色点之间的边。
示例:用户 - 角色关系
示例:用户点增加统计属性
ALTER TAG user ADD (
follower_count int,
- 按时间排序的关系 → 使用 Rank 或时间戳属性
示例:登录历史(使用 Rank 存储时间戳)
CREATE EDGE login_history (
ip string,
device string
);
- 图数据库适合适度冗余:为提高查询效率,可在边中存储部分点的关键属性(如商品边存储商品名称)。
- 但需权衡:冗余会增加写入成本,需根据读写比例决定。
- 点:用户(ID、姓名、年龄)
- 边:关注(关注时间、亲密度)、好友(创建时间、共同好友数)
- 点:用户(ID、姓名、注册时间)、商品(ID、名称、价格)
- 边:浏览(时间、停留时长)、购买(时间、数量、金额)
- 点:实体(名称、类型、描述)
- 边:关系(类型、权重、置信度)
-
使用 PROFILE 命令分析查询性能:
PROFILE GO FROM "user1" OVER follow YIELD follow._dst;
检查是否走了索引,是否有全图扫描。
-
为高频查询字段创建索引:
CREATE TAG INDEX idx_user_age ON user(age);
CREATE EDGE INDEX idx_follow_time ON follow(create_time);
-
定期重构数据模型:根据实际查询模式调整点边属性划分。
- ❌ 过度依赖点属性:将所有数据都放在点中,导致查询时需要频繁遍历边。
- ❌ 忽略边属性:关系特性全部缺失,无法表达复杂业务逻辑。
- ❌ 滥用多标签:一个实体用过多标签,增加查询复杂度。
合理的点边属性设计是图数据库发挥性能优势的关键。建议先从业务场景的核心查询需求出发,逐步迭代优化模型。