Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Operational Property Graphs到底是个啥?

Operational Property Graphs到底是个啥?

作者头像
Alfred Zhao
发布于 2024-06-22 01:04:11
发布于 2024-06-22 01:04:11
11800
代码可运行
举报
运行总次数:0
代码可运行

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在其多模能力上的一种体现,使其能够更适合用来构建现代的应用平台。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 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.创建属性图

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 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(顶点表)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 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(边表)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 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”的人的朋友,并返回这些朋友的名字。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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出身的小伙伴们也能理解,我们继续逐一来解释:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 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 属性。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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的查询结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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>

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 先删除有外键约束的表:
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来说,理解上还是有一些技术挑战的。

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
EDB分区表的又一个“坑”
下周有一个应用上线,其中涉及一个夜维删除逻辑的应用,大体功能是按照时间删除一张表的历史数据,这张表的主键是另外一张时间分区表的外键,使用的是EDB(9.2)数据库,这次测试就意外发现了一个说是隐藏,也不算隐藏,至少和Oracle分区表有很大不同的地方,或者可以称他为KENG,“坑”。
bisal
2019/01/29
7250
MySQL基础SQL编程学习2
描述:主要学习数据库的DDL数据库定义语言,比如CREATE , DROP, ALTER 等等:
全栈工程师修炼指南
2022/09/29
7.5K0
MySQL基础SQL编程学习2
Oracle基础教程之手动创建 emp 表 与 dept 表
说明: 有时候我们需要通用的实验数据,emp表 与 dept表  但是Oracle数据库中有没有。 这时,我们可以手动创建。
星哥玩云
2022/08/16
1.8K0
使用exchange方式切换普通表到分区表
      随着数据库数据量的不断增长,有些表需要由普通的堆表转换为分区表的模式。有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表;使用EXCHANGE PARTITION方式来转换为分区表以及使用DBMS_REDEFINITION来在线重定义分区表。本文描述的是使用EXCHANGE PARTITION方式来实现,下面是具体的操作示例。
Leshami
2018/08/13
6010
【D2RQ】:D2RQ Mapping Language
知识抽取是指从不同来源、不同结构的数据中进行知识提取,提取出数据内涵的事实性信息并供给知识图谱做进一步加工处理后会形成知识,存入到知识图谱。
WEBJ2EE
2021/09/02
1.6K0
【D2RQ】:D2RQ Mapping Language
使用导出导入(datapump)方式将普通表切换为分区表
      随着数据库数据量的不断增长,有些表需要由普通的堆表转换为分区表的模式。有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表;使用EXCHANGE PARTITION方式来转换为分区表以及使用DBMS_REDEFINITION来在线重定义分区表。本文描述的是使用导出导入方式来实现,下面是具体的操作示例。
Leshami
2018/08/13
9840
【赵渝强老师】Oracle数据库的客户端工具
安装并成功创建Oracle数据库后,便可以使用客户端工具来连接Oracle数据库。Oracle官方提供的客户端工具主要有:SQL*Plus和SQL Developer。
赵渝强老师
2025/03/26
740
【赵渝强老师】Oracle数据库的客户端工具
重新学习Mysql数据库1:无废话MySQL入门
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/11/29
1.3K0
LeetCode 数据库专题
写一段SQL查询来展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。你可以以 任意 顺序返回结果表。查询结果的格式如下例所示:
wywwzjj
2023/05/09
1.5K0
LeetCode 数据库专题
【愚公系列】2023年03月 Java教学课程 118-Mybatis(多表操作)
多表模型是一种关系型数据库设计模式,它使用多个表格来存储和管理数据。在多表模型中,每个表格都包含一组相关的数据,并使用外键等关系来与其他表格建立连接。这种模型通常用于处理复杂的数据结构,例如具有多个关系的实体或需要动态添加或删除属性的实体。
愚公搬代码
2023/04/04
6480
【愚公系列】2023年03月 Java教学课程 118-Mybatis(多表操作)
一个小时学会MySQL数据库
随着移动互联网的结束与人工智能的到来大数据变成越来越重要,下一个成功者应该是拥有海量数据的,数据与数据库你应该知道。
杨奉武
2019/02/13
3.8K0
一个小时学会MySQL数据库
【MySQL】SQL语句查询、约束、备份与恢复
SELECT * FROM product ORDER BY price DESC;
陶然同学
2023/02/24
2K0
【MySQL】SQL语句查询、约束、备份与恢复
SQL FOREIGN KEY 约束- 保障表之间关系完整性的关键规则
SQL FOREIGN KEY 约束用于防止破坏表之间关系的操作。FOREIGN KEY 是一张表中的字段(或字段集合),它引用另一张表中的主键。具有外键的表称为子表,具有主键的表称为被引用表或父表。
小万哥
2023/12/08
3450
SQL FOREIGN KEY 约束- 保障表之间关系完整性的关键规则
OB 运维 | 一则 Oracle 迁移到 OB 后存储过程语法报错问题诊断案例
客户反馈一个存储过程从 Oracle 迁移到 OB Oracle 模式后,执行报语法错误。报错如下:
爱可生开源社区
2024/02/21
4020
OB 运维 | 一则 Oracle 迁移到 OB 后存储过程语法报错问题诊断案例
不是吧,阿Sir,MySQL约束你竟然还不懂!
符号规定:下面展示一些定义的时候,为简便理解,使用中文配合符号表述(会有具体举例,不用担心理解不了)
BWH_Steven
2020/06/22
5830
不是吧,阿Sir,MySQL约束你竟然还不懂!
使用DBMS_REDEFINITION在线切换普通表到分区表
      随着数据库数据量的不断增长,有些表需要由普通的堆表转换为分区表的模式。有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表;使用EXCHANGE PARTITION方式来转换为分区表以及使用DBMS_REDEFINITION来在线重定义分区表。本文描述的是使用DBMS_REDEFINITION来实现,下面是具体的操作示例。
Leshami
2018/08/13
4060
oracle数据库文本类型_oracle修改字段数据类型
insert into courses values(‘ss01′,’.NET’,0,TO_DATE(‘2009-8-28′,’yyyy-mm-dd’),94)
全栈程序员站长
2022/10/04
6270
Oracle应用实战四——约束+Scott表结构
约束 在数据库开发中,约束是必不可少,使用约束可以更好的保证数据的完整性。 1 主键约束(掌握) 主键约束都是在id上使用,而且本身已经默认了内容不能为空,可以在建表的时候指定。 创建一张表,把pid作为主键 create table person( pid number(10) primary key, name varchar2(10), gender number(1) default 1, birthday date ); 主键不可重复,
Java帮帮
2018/03/19
1K0
Oracle应用实战四——约束+Scott表结构
Oracle 数据库学习笔记 (三)
语法:RENAME table_ name TO new_ table_ name;
Gorit
2021/12/09
4040
Oracle 12c 数据库scott用户不存在的解决方案
Oracle 12c 数据库做了很大的改变,集成了SQLDeveloper,可以方便大家的使用,scott用户已经被移除了,需要的话可以自己创建,并授予权限。这个稍微有点基础的话都是很简单的……按着步骤来就可以。
星哥玩云
2022/08/17
1.3K0
相关推荐
EDB分区表的又一个“坑”
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验