Operational Property Graphs,中文通常译为“操作属性图”。

作为23ai中被官方highlight出的新特性之一,我们先看下官方的原文描述:

  • Operational Property Graphs in SQL

Developers can now build real-time graph analysis applications against operational

data directly in the Oracle Database, utilizing its industry leading security, high

availability and performance capabilities.

简单说,开发者可以直接在Oracle 23ai中进行实时图分析,而不需要额外的图数据库。

为了不纯扯概念,更好的直观体验,下面我们直接按照官方文档给出的一个简单示例来动手练习体验下:

本次测试环境: Oracle Database 23ai(23.4.0.24.05)

本次用到技术: 原生JSON数据类型、操作属性图。

本次测试意义: 直观体验Oracle数据库多模、融合的设计理念所带来的便利性。

  • 1.准备测试表和测试数据
  • 2.创建属性图
  • 3.体验SQL查询属性图

1.准备测试表和测试数据

这里创建的示例,整体构成了一个基本的数据库结构,测试表 university、persons、students、friendships 分别用于存储大学、人员、学生和朋友关系的数据。

特别需要注意的是,persons 表中的 person_data 字段是 JSON 类型,用于存储原生 JSON 数据。这也是23ai在其多模能力上的一种体现,使其能够更适合用来构建现代的应用平台。

-- 1.CREATE TABLE university
CREATE TABLE university (
id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
name VARCHAR2(10),
CONSTRAINT u_pk PRIMARY KEY (id)); INSERT INTO university (name) VALUES ('ABC');
INSERT INTO university (name) VALUES ('XYZ');
commit; -- 2.CREATE TABLE persons
-- 包含存放原生的JSON数据类型字段person_data,这里是存放了这个人的部门信息和岗位角色
CREATE TABLE persons (
person_id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT
BY 1),
name VARCHAR2(10),
birthdate DATE,
height FLOAT DEFAULT ON NULL 0,
person_data JSON,
CONSTRAINT person_pk PRIMARY KEY (person_id)
); INSERT INTO persons (name, height, birthdate, person_data)
VALUES ('John', 1.80, to_date('13/06/1963', 'DD/MM/YYYY'), '{"department":"IT","role":"Software Developer"}');
INSERT INTO persons (name, height, birthdate, person_data)
VALUES ('Mary', 1.65, to_date('25/09/1982', 'DD/MM/YYYY'), '{"department":"HR","role":"HR Manager"}');
INSERT INTO persons (name, height, birthdate, person_data)
VALUES ('Bob', 1.75, to_date('11/03/1966', 'DD/MM/YYYY'), '{"department":"IT","role":"Technical Consultant"}');
INSERT INTO persons (name, height, birthdate, person_data)
VALUES ('Alice', 1.70, to_date('01/02/1987', 'DD/MM/YYYY'), '{"department":"HR","role":"HR Assistant"}');
commit; -- 3.CREATE TABLE students
-- 这里官方文档有个错误,属于低级错误,插入字段数量和具体赋值对应不上,此处已修正
CREATE TABLE students (
s_id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
s_univ_id NUMBER,
s_person_id NUMBER,
subject VARCHAR2(10),
CONSTRAINT stud_pk PRIMARY KEY (s_id),
CONSTRAINT stud_fk_person FOREIGN KEY (s_person_id) REFERENCES persons(person_id),
CONSTRAINT stud_fk_univ FOREIGN KEY (s_univ_id) REFERENCES university(id)
); INSERT INTO students(s_univ_id, s_person_id, subject) VALUES (1,1,'Arts');
INSERT INTO students(s_univ_id, s_person_id, subject) VALUES (1,3,'Music');
INSERT INTO students(s_univ_id, s_person_id, subject) VALUES (2,2,'Math');
INSERT INTO students(s_univ_id, s_person_id, subject) VALUES (2,4,'Science');
commit; -- 4.CREATE TABLE friendships
-- 这里 meeting_date 可理解为朋友之间相遇的日期
CREATE TABLE friendships (
friendship_id NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
person_a NUMBER,
person_b NUMBER,
meeting_date DATE,
CONSTRAINT fk_person_a_id FOREIGN KEY (person_a) REFERENCES persons(person_id),
CONSTRAINT fk_person_b_id FOREIGN KEY (person_b) REFERENCES persons(person_id),
CONSTRAINT fs_pk PRIMARY KEY (friendship_id)
); INSERT INTO friendships (person_a, person_b, meeting_date) VALUES (1, 3, to_date('01/09/2000', 'DD/MM/YYYY'));
INSERT INTO friendships (person_a, person_b, meeting_date) VALUES (2, 4, to_date('19/09/2000', 'DD/MM/YYYY'));
INSERT INTO friendships (person_a, person_b, meeting_date) VALUES (2, 1, to_date('19/09/2000', 'DD/MM/YYYY'));
INSERT INTO friendships (person_a, person_b, meeting_date) VALUES (3, 2, to_date('10/07/2001', 'DD/MM/YYYY'));
commit;

2.创建属性图

-- 5.CREATE PROPERTY GRAPH students_graph
-- 这里是关键的属性图创建:
CREATE PROPERTY GRAPH students_graph
VERTEX TABLES (
persons KEY (person_id)
LABEL person
PROPERTIES (person_id, name, birthdate AS dob)
LABEL person_ht
PROPERTIES (height),
university KEY (id)
)
EDGE TABLES (
friendships AS friends
KEY (friendship_id)
SOURCE KEY (person_a) REFERENCES persons(person_id)
DESTINATION KEY (person_b) REFERENCES persons(person_id)
PROPERTIES (friendship_id, meeting_date),
students AS student_of
SOURCE KEY (s_person_id) REFERENCES persons(person_id)
DESTINATION KEY (s_univ_id) REFERENCES university(id)
PROPERTIES (subject)
);

这个对于DBA出身的小伙伴们来说,可能会很陌生,也稍难理解些。所以这里详细解释说明下:

上面的SQL语句是在Oracle数据库中,直接创建了一个属性图students_graph,具体包含两个顶点表(persons和university)和两个边表(friendships和students)。

那什么是顶点表?边表又是啥?

在图数据库中,顶点(Vertex)和边(Edge)是构建图数据模型的基本元素:

顶点表(Vertex Table):表示图中的实体或对象。

边表(Edge Table):表示图中的关系或连接,定义了两个顶点之间的关系。

具体在我们这个例子中,顶点表personsuniversity表示人员和大学。

边表friendshipsstudents表示人员之间的友谊关系和人员与大学之间的学生关系。

了解了基本概念后,再回过头来看这个SQL定义的属性图,拆解分析后是不是很清晰了呢?

  • VERTEX TABLES(顶点表)
-- persons 表:
KEY (person_id):指定主键。
LABEL person:给顶点赋予person标签。
PROPERTIES (person_id, name, birthdate AS dob):指定属性,其中birthdate属性重命名为dob。
LABEL person_ht:给顶点赋予person_ht标签。
PROPERTIES (height):指定属性height。 -- university 表:
KEY (id):指定主键。
  • EDGE TABLES(边表)
-- friendships 表(别名friends):
KEY (friendship_id):指定主键。
SOURCE KEY (person_a) REFERENCES persons(person_id):源顶点引用persons表的person_id。
DESTINATION KEY (person_b) REFERENCES persons(person_id):目标顶点引用persons表的person_id。
PROPERTIES (friendship_id, meeting_date):指定属性。 -- students 表(别名student_of):
SOURCE KEY (s_person_id) REFERENCES persons(person_id):源顶点引用persons表的person_id。
DESTINATION KEY (s_univ_id) REFERENCES university(id):目标顶点引用university表的id。
PROPERTIES (subject):指定属性。

3.体验SQL查询属性图

实际使用了Oracle的图表查询语言来查找名为“John”的人的朋友,并返回这些朋友的名字。

SELECT *
FROM GRAPH_TABLE ( students_graph
MATCH (a IS person) -[e IS friends]- (b IS person)
WHERE a.name = 'John'
COLUMNS (b.name)
);

这个SQL同样会让DBA觉得不适应,看起来怪怪的,但对开发人员应该很容易理解了。为了让DBA出身的小伙伴们也能理解,我们继续逐一来解释:

-- FROM GRAPH_TABLE:
使用 GRAPH_TABLE 函数来查询图数据。 -- students_graph:
这是之前创建的属性图的名称。 -- MATCH (a IS person) -[e IS friends]- (b IS person):
MATCH:定义图的模式。
(a IS person):匹配标签为 person 的顶点 a。
-[e IS friends]-:匹配标签为 friends 的边 e,连接顶点 a 和 b。
(b IS person):匹配标签为 person 的顶点 b。 -- WHERE a.name = 'John':
过滤条件:顶点 a 的 name 属性为 'John'。 -- COLUMNS (b.name):
定义返回的列:返回顶点 b 的 name 属性。

当然,除了返回朋友的名字,还可以返回更多信息,比如和这位朋友友谊开始的日期:

SELECT *
FROM GRAPH_TABLE ( students_graph
MATCH (a IS person) -[e IS friends]- (b IS person)
WHERE a.name = 'John'
COLUMNS (b.name, e.meeting_date)
);

只是在COLUMNS条件中,增加了e.meeting_date,是不是咋一看很晦涩难懂,实际理解了,其实跟普通SQL一样的简单清晰呢?

上面示例的两个SQL的查询结果如下:

23:02:23 PRIMARY @ORCL -> JINGYU @PDB1> SELECT *
FROM GRAPH_TABLE ( students_graph
MATCH (a IS person) -[e IS friends]- (b IS person)
WHERE a.name = 'John'
COLUMNS (b.name)
);23:02:23 2 23:02:23 3 23:02:23 4 23:02:23 5 23:02:23 6 NAME
----------
Mary
Bob Elapsed: 00:00:00.00
23:02:24 PRIMARY @ORCL -> JINGYU @PDB1> SELECT *
FROM GRAPH_TABLE ( students_graph
MATCH (a IS person) -[e IS friends]- (b IS person)
WHERE a.name = 'John'
COLUMNS (b.name, e.meeting_date)
);23:02:35 2 23:02:35 3 23:02:35 4 23:02:35 5 23:02:35 6 NAME MEETING_D
---------- ---------
Mary 19-SEP-00
Bob 01-SEP-00 Elapsed: 00:00:00.01
23:02:35 PRIMARY @ORCL -> JINGYU @PDB1>

清理实验环境:

删除本次测试的表和属性图,方便快速清理环境或重新测试:

-- 先删除有外键约束的表:
drop table students purge;
drop table friendships purge; -- 再删除其他表:
drop table university purge;
drop table persons purge; -- 删除属性图:
drop PROPERTY GRAPH students_graph;

参考的官方文档链接:

注:官方文档给出的例子有些小问题,已在文章中代码部分修正,方便大家直接复制粘贴文中代码来进行快速测试验证。

最后总结一下本文都涵盖了哪些内容:

  • 例子中提到的原生JSON数据类型,其实还比较容易理解,无非就是把JSON数据存储到对应这个数据类型的字段中。注意这里并没有提到JSON关系二元性,这个话题以后空了再单独研究讨论。

  • 有个细节,创建表语句中使用的自增id,GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),这其实不算是一个很新的功能,但如果读者对Oracle的认知还停留在11g时代,可能还会认为Oracle不支持类似像MySQL这种自增ID的设计,需要序列配合实现。而实际上,早在12c之后就已经支持了这种方式。

  • 介绍并演示操作属性图这个特性。

回到本文实验的主题,操作属性图(Operational Property Graphs)其实对传统偏管理方向的DBA来说,理解上还是有一些技术挑战的。

比如开始很可能照例子创建成功了,也不知道如何用,创建出来的属性图想直接查询看到底是个啥内容,发现自己还不会正确的使用语法。

笔者也是,但静下心来,花些时间看看文档,理解这类新特性之后,就会发现其强大之处,也容易积极推广给有需要的开发人员来使用,实现简化开发,降低使用属性图的门槛,提升工作效率。

Operational Property Graphs到底是个啥?的更多相关文章

  1. Python的特性(property)

    特性(property) 特性是对类的一个特定属性进行拦截,在操作这个属性时,执行特定的函数,对属性的操作进行拦截. 特性的实现 特性使用property类来实现,也可以使用property装饰器实现 ...

  2. Neo4j沙盒实验申请过程步骤(图文详解)

    不多说,直接上干货! 参考博客 http://blog.csdn.net/u012318074/article/details/72793632    (对此表示感谢) 前期博客 我暂时是将Neo4j ...

  3. Python第七章-面向对象高级

    面向对象高级 一. 特性 特性是指的property. property这个词的翻译一直都有问题, 很多人把它翻译为属性, 其实是不恰当和不准确的. 在这里翻译成特性是为了和属性区别开来. 属性是指的 ...

  4. 论文阅读: CCF A 2022 MVD: 基于流敏感图神经网络的内存相关漏洞检测 (ICSE)

    Motivation: 内存相关漏洞会导致性能下降和程序崩溃,严重威胁到现代软件的安全性. 静态分析方法使用一些预定义的漏洞规则或模式来搜索不正确的内存操作,然而,定义良好的漏洞规则或模式高度依赖于专 ...

  5. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  6. 在开发中到底要不要用var?

    var是.net的一个语法糖,在Resharper中推荐都使用这个关键字,平常我也是经常用:但是在跟其他程序员推广使用时,他的一些考虑引发了我的深思,到底该不该使用这个关键字呢? 我使用的理由 我使用 ...

  7. iOS多线程到底不安全在哪里?

    iOS多线程安全的概念在很多地方都会遇到,为什么不安全,不安全又该怎么去定义,其实是个值得深究的话题. 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从P ...

  8. OC中的@property详解

    简介: @property 生成了变量的get set 方法,同时指定了变量名称. 例如@property (nonatomic,strong) NSString *name;表示生成了_name私有 ...

  9. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  10. Property和attribute的区别[转]

    Attribute和Property都可以翻译成“属性”,有的地方用Attribute表示“属性”,有的地方又在用Property,初 学者常常在这两个单词间“迷失”,甚至认为二者没有区别,是一样的. ...

随机推荐

  1. [ELK] Docker 运行 Elastic Stack 支持 TLS 的两种简单方式

    第一种就是 按照官方文档进行配置,指定证书位置开启. Run the Elastic Stack in Docker with TLS enabled. 第二种就是 9200 端口只暴露给本机,127 ...

  2. 使用 SizeBench 分析 Exe 文件体积

    本文将介绍微软开源免费的 SizeBench 工具,使用 SizeBench 工具可以用来分析 Exe 二进制文件的体积,分析 Exe 文件大小里面有哪些是可以优化的 下载安装方式: 请前往应用商店安 ...

  3. WPF 全屏窗口将让 Chrome 97 视频停止播放

    无论是使用 WPF 全屏窗口,还是高性能全屏透明窗口,都会在 Chrome 97 以及使用 chromium 对应版本内核的应用的视频停止播放.这是 chromium 的一个优化,因为 chromiu ...

  4. dotnet C# 只创建对象不调用构造函数方法

    有时我期望只是创建出对象,但是不要调用对象的构造方法,可以通过使用 FormatterServices 的 GetUninitializedObject 函数来实现只创建对象不调用构造函数方法 这个 ...

  5. dotnet 读 WPF 源代码笔记 插入触摸设备的初始化获取设备信息

    在 WPF 触摸应用中,插入触摸设备,即可在应用里面使用上插入的触摸设备.在 WPF 使用触摸设备的触摸时,需要获取到触摸设备的信息,才能实现触摸 获取触摸设备插入 在 WPF 中,通过 Window ...

  6. Win10下小米路由器4A百兆版刷Openwrt固件【图片详细版】

    将原来的小米路由器换成了华为,早就听闻刷软路由可以实现去广告,解锁灰色歌单等诸多骚操作.就来榨取这个小米4A的剩余价值来着的. 注意 1. 必须使用路由模式,中继模式是打不开telnet的 更新固件 ...

  7. 一个完整的可以输出移动端当前省市(地理坐标)的html页面

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Kimi:文本解析利器,你相信光么?

    缘起 第一次接触 kimi 是在微信群,开始以为是推广薅羊毛产品,后来在其他渠道也了解到 kimi,据说是"国产之光".我知道很多同学苦不能使用魔法久矣,索性就先踩踩这个" ...

  9. 五:大数据架构回顾-LambdaPlus架构

    Blink是阿里云在 Apache Flink 基础上深度改进的实时计算平台,Blink旨在将流处理和批处理统一,实现了全新的 Flink SQL 技术栈,在功能上,Blink支持现在标准 SQL 几 ...

  10. ansible(7)--ansible的file模块

    1. file模块 功能:为被控端创建文件或目录,设定权限属性: 主要参数如下: 参数 说明 path 指定远程服务器的路径,也可以写成'dest','name' state 状态,可以将值设定为di ...