【图分析】基于Nebula Graph的图平台建设

本文介绍了基于图形数据库的平台设计,包括数据汇聚和数据分析。对象定义模块允许用户预定义数据结构,通过目录树管理,支持与三维数据和实时数据的融合。对象管理模块则实现了数据的创建、删除、查询和修改。文章详细阐述了对象定义与三维数据、实时数据流的关系,以及如何处理特殊属性类型,如三维倾斜摄影和实时数据。最后,展示了如何在NebulaGraph中创建schema和管理实体。

背景

2019年,基于“图形”(Graph)的存储、分析相关技术被Gartner评为十大数据与分析技术之一。据说基于“图”实现的存储可以进行高效的建模,进而可以探索与查询具有相互复杂关系的数据。而后研究“图”这类数据以及相关技术就成了是我的一个兴趣爱好。

但随着不断的深入,渐渐发现这种数据结构可以解决很多问题。例如,不同类型的数据如何联系在一起,如何根据这些联系进行数据挖掘等等。这些数据特征不一,在实际应用中会选用不同数据库进行管理。但是实际上这些数据在真实世界中往往有千丝万缕的关系。所以我着手研究“图”在其中的作用。

在我的工作内容中,需要处理不同类型的数据,例如:时序数据,三维图形数据,和业务对象等。从产品的角度出发,我需要将它们三者统一起来,进行存储,为数据挖掘和知识沉淀建立基础。

总体设计

平台架构
在这里插入图片描述
平台总体采用Spring Cloud的应用架构,主要选型:

spring cloud:2020.0.2
spring boot:2.4.3
mybatis:2.1.2

关于如何在idea创建Spring cloud项目和使用MyBatis自动生成代码可以分别参考以下两篇blogs

https://blog.youkuaiyun.com/sword_csdn/article/details/104961624
https://blog.youkuaiyun.com/sword_csdn/article/details/124607699

图平台需要促进不同类型数据的融合,并进行分析。所以整个平台的总体思路包含两个部分:数据汇聚数据分析

数据汇聚

要获得有意义的分析结果,则需要融合大量数据。如何对数据进行有效地组织和管理,是数据挖掘和分析的前提。所以在数据“入库”之前,我们可以提供一个定义对象的功能。使得数据入库之后以预先定义的规则来管理数据。

对象定义,schema_manager

“对象定义”模块概述

我们需要定义一个对象的抽象概念,所谓对象,往往对应真实世界中一个客观实体,不仅如此,对象还包含实体之间的关系。总而言之,对象包含客观世界中的“实体”,以及实体之间的“关系”。当平台具备了定义它们的能力时,理论上便已经具备了容纳所有数据的能力了。因为几乎所有的数据,都是围绕客观对象产生的。

具体而言,平台是给用户提供了一个自定义对象的机制。这里可以称为“对象定义”。例如:我们需要汇聚一份传感系统数据,我们就需要定义传感系统里都包含哪些类型的传感终端,这些终端是使用哪些属性来描述的。
在这里插入图片描述
此外,还有与终端相连接的“传感服务器A”(假设有),以及它们之间的电路连接,这些可以在对象定义中加以定义。
在这里插入图片描述
定义完成后,我们就可以在“对象管理”模块(后续会说明),按照定义来添加数据。

在这里插入图片描述

“对象定义”模块实现
目录树

用户可以基于目录树的方式管理对象定义。

目录树的功能可以基于Hutool的TreeUtils功能实现(详情可访问https://www.hutool.cn/),这里有关目录树的表结构创建对应的SQL语句可以参考。

DROP TABLE IF EXISTS "public"."schema_catalog";
CREATE TABLE "public"."schema_catalog" (
  "id" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "token" varchar(255) COLLATE "pg_catalog"."default",
  "name" varchar(255) COLLATE "pg_catalog"."default",
  "parentid" varchar(255) COLLATE "pg_catalog"."default",
  "level" int8,
  "createtime" date,
  "updatetime" date,
  "pos" int8
);
COMMENT ON COLUMN "public"."schema_catalog"."id" IS '主键id';
COMMENT ON COLUMN "public"."schema_catalog"."token" IS '该节点所属标识,一般是角色';
COMMENT ON COLUMN "public"."schema_catalog"."name" IS '节点名称';
COMMENT ON COLUMN "public"."schema_catalog"."parentid" IS '父节点id';
COMMENT ON COLUMN "public"."schema_catalog"."level" IS '节点层级';
COMMENT ON COLUMN "public"."schema_catalog"."createtime" IS '创建时间';
COMMENT ON COLUMN "public"."schema_catalog"."updatetime" IS '更新时间';
COMMENT ON COLUMN "public"."schema_catalog"."pos" IS '排序';
-- ----------------------------
-- Primary Key structure for table schema_catalog
-- ----------------------------
ALTER TABLE "public"."schema_catalog" ADD CONSTRAINT "schema_catalog_pkey" PRIMARY KEY ("id");

相关新增,修改,删除等接口可按需实现。而值得记录的是关于级联删除的方法。我这里在对应schema_catalog数据表的MyBaties的Mapper XMl文件中自定义了该方法的SQL语句,如下所示:

<delete id="deleteAllChildren">
        with ctl as (
        delete
        from schema_catalog
        where id in (select c1.id
                     from schema_catalog c1
                     where c1.id = #{id}
                       and c1.token = #{token}
                     union all
                     select c2.id
                     from schema_catalog c2
                              inner join schema_catalog c1 on c1.id = c2.parentid) returning *),

        obj as (
        delete
        from schema_object
        where catalog_id in (select id from ctl) returning *)
        delete
        from schema_field
        where object_id in (select id from obj)
    </delete>

而关于级联查询的SQL语句如下:

<select id="selectAllChildren" resultType="com.southsmart.sgeocserver.schema.entity.SchemaCatalog">
        with recursive ctl as (select c1.id, c1.name, c1.parentid, c1.level, c1.createtime, c1.updatetime, c1.pos
                               from schema_catalog c1
                               where c1.id = #{id}
                                 and c1.token = #{token}
                               union all
                               select c2.id, c2.name, c2.parentid, c2.level, c2.createtime, c2.updatetime, c2.pos
                               from schema_catalog c2
                                        inner join ctl c3 on c3.id = c2.parentid)
        select *
        from ctl
    </select>
对象定义

对象定义的实现比较简单,有两个表,一个是对象表schema_object,一个是对象属性表schema_field,它们的表结构SQL分别是:

schema_object

-- ----------------------------
-- Table structure for schema_object
-- ----------------------------
DROP TABLE IF EXISTS "public"."schema_object";
CREATE TABLE "public"."schema_object" (
  "id" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "catalog_id" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "name_cn" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "type" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "token" varchar(255) COLLATE "pg_catalog"."default",
  "createtime" date,
  "updatetime" date
)
;
COMMENT ON COLUMN "public"."schema_object"."id" IS '数据记录唯一标识';
COMMENT ON COLUMN "public"."schema_object"."catalog_id" IS '所属目录id';
COMMENT ON COLUMN "public"."schema_object"."name" IS '对象名称,用于创建schema';
COMMENT ON COLUMN "public"."schema_object"."name_cn" IS '对象中文名称';
COMMENT ON COLUMN "public"."schema_object"."type" IS '对象类型。0:实体对象,1:关系对象';
COMMENT ON COLUMN 
### Nebula Graph 安装与使用教程概述 Nebula Graph 是一款分布式数据库,适用于社交网络分析、推荐系统、知识谱等多种场景[^1]。以下是关于其安装、使用教程和技术文档的相关信息。 #### 安装教程 Nebula Graph 的安装需要配置存储服务组件(NebulaStorage)。在首次启动时,用户可能会遇到“Host not enough”的错误提示[^4]。这是因为尚未注册 Storage 服务。解决方法是在 NebulaGraph Studio 界面的命令行中执行以下命令以添加主机: ```sql ADD HOSTS <ip>:<port>; ``` 这里的 `<ip>` 和 `<port>` 需要替换为实际的 IP 地址和端口号。 #### 使用教程 Nebula Graph 提供了丰富的查询功能,支持复杂的数据操作需求。用户可以通过 nGQL(Nebula Graph Query Language)进行数据的增删改查。例如,创建一个空间可以使用以下语句: ```sql CREATE SPACE IF NOT EXISTS my_space( partition_num = 10, replica_factor = 1, vid_type = FIXED_STRING(30) ); ``` 此外,Nebula Graph 支持索引的创建,以便优化查询性能。具体语法可参考官方文档[^2]。 #### 技术文档 Nebula Graph 的技术文档详细描述了其内核代码结构和功能实现。例如,在 `src/common/clients/` 目录下提供了 meta 和 storage 客户端的 C++ 实现[^3]。对于开发者而言,了解这些工具包有助于深入理解 Nebula Graph 的工作机制。 ```python # 示例:通过 Python SDK 连接 Nebula Graph from nebula3.Config import SessionPoolConfig from nebula3.gclient.net import ConnectionPool config = SessionPoolConfig() connection_pool = ConnectionPool() if not connection_pool.init(['127.0.0.1:9669'], config): print("Failed to connect to Nebula Graph") else: session = connection_pool.get_session('root', 'nebula') result = session.execute('SHOW SPACES;') print(result) session.release() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值