Oracle 23ai的SQL 属性图,核心是将图数据模型与SQL语言深度融合,实现“关系数据→属性图→SQL查询”的全流程原生支持。属性图由顶点(Vertices)、边(Edges)组成,顶点代表数据实体(如用户、订单、产品),边代表实体间的关联关系(如“用户购买产品”“朋友关系”“供应链依赖”),顶点和边都可以携带键值对形式的属性(如用户的姓名、年龄,订单的金额、日期)。

与专用图数据库不同,SQL 属性图无需将数据导出到外部系统,而是直接基于企业现有关系表创建,数据仍存储在关系表中,属性图本质上是对关系数据的“视图级封装”。这一设计不仅避免了数据冗余与同步问题,还让开发者能够用熟悉的SQL语法编写图查询,无需学习新的图查询语言(如PGQL),大幅降低了图分析的门槛,实现了关系数据与图数据的统一管理与查询。

同时,SQL 属性图遵循SQL:2023标准,支持GRAPH_TABLE运算符与MATCH子句,让图查询能够与传统SQL查询无缝结合,适配企业现有的技术栈与开发习惯,真正实现了“用SQL搞定图分析”。

接下来模拟两个业务场景

场景1:社交网络好友关系图查询

需求:基于用户表与好友关系表,创建属性图,查询用户之间的好友关系、最短好友链。

  • 步骤1:创建底层关系表并插入测试数据
    -- 创建用户表(顶点表)
    CREATE TABLE users (
    user_id NUMBER PRIMARY KEY,
    user_name VARCHAR2(100) NOT NULL,
    age NUMBER,
    city VARCHAR2(50)
    );
    -- 创建好友关系表(边表)
    CREATE TABLE friend_relation (
    relation_id NUMBER PRIMARY KEY,
    from_user_id NUMBER REFERENCES users(user_id),
    to_user_id NUMBER REFERENCES users(user_id),
    relation_date DATE DEFAULT SYSDATE,
    -- 边的属性:好友关系类型(同学、同事、家人)
    relation_type VARCHAR2(20)
    );
    -- 插入测试数据
    INSERT INTO users VALUES (1, '张三', 25, '北京');
    INSERT INTO users VALUES (2, '李四', 26, '上海');
    INSERT INTO users VALUES (3, '王五', 24, '北京');
    INSERT INTO users VALUES (4, '赵六', 27, '广州');
    INSERT INTO friend_relation VALUES (101, 1, 2, SYSDATE, '同学');
    INSERT INTO friend_relation VALUES (102, 1, 3, SYSDATE, '同事');
    INSERT INTO friend_relation VALUES (103, 2, 4, SYSDATE, '朋友');
    INSERT INTO friend_relation VALUES (104, 3, 4, SYSDATE, '同学');
    COMMIT;
  • 步骤2:创建SQL 属性图
    -- 创建属性图,定义顶点与边
    CREATE PROPERTY GRAPH social_graph
    -- 定义顶点:用户
    VERTEX TABLES (
    users 
      KEY (user_id) 
      PROPERTIES (user_id, user_name, age, city)
    )
    -- 定义边:好友关系
    EDGE TABLES (
    friend_relation
      KEY (relation_id)
      SOURCE KEY (from_user_id) REFERENCES users(user_id)
      DESTINATION KEY (to_user_id) REFERENCES users(user_id)
      PROPERTIES (relation_id, relation_type, relation_date)
    );
  • 步骤3:执行图查询
    -- 1. 查询张三(user_id=1)的所有好友
    SELECT t.user_name AS 好友姓名, t.age AS 好友年龄, t.relation_type AS 关系类型
    FROM GRAPH_TABLE (
    social_graph
    MATCH (u:users)-[r:friend_relation]->(v:users)
    WHERE u.user_id = 1
    COLUMNS (v.user_name, v.age, r.relation_type)
    ) t;
    -- 2. 查询张三(user_id=1)到赵六(user_id=4)的最短好友链
    SELECT t.path_length, t.user_names
    FROM GRAPH_TABLE (
    social_graph
    MATCH SHORTEST PATH (u:users)-[*]->(v:users)
    WHERE u.user_id = 1 AND v.user_id = 4
    COLUMNS (
    COUNT(r.relation_id) AS path_length,
    LISTAGG(u.user_name || '->' || v.user_name, ',') WITHIN GROUP (ORDER BY r.relation_id) AS user_names
    )
    ) t;

    场景2:电商产品关联推荐查询

    需求:基于用户、订单、产品表,创建属性图,查询“购买了某产品的用户还购买了哪些产品”,用于产品推荐。

  • 步骤1:复用电商订单底层表(前文已创建),创建属性图
    -- 创建电商产品关联属性图
    CREATE PROPERTY GRAPH product_recommend_graph
    -- 定义顶点:用户、产品
    VERTEX TABLES (
    customer 
      KEY (cust_id) 
      PROPERTIES (cust_id, cust_name),
    order_item
      KEY (item_id)
      PROPERTIES (item_id, product_name, unit_price)
    )
    -- 定义边:用户购买产品(通过订单关联)
    EDGE TABLES (
    orders
      KEY (order_id)
      SOURCE KEY (cust_id) REFERENCES customer(cust_id)
      DESTINATION KEY (order_id) REFERENCES order_item(order_id)
      PROPERTIES (order_id, total_amount, order_date)
    );

    步骤2:查询产品关联推荐数据

    -- 查询购买了“手机”的用户还购买了哪些产品
    SELECT t.recommend_product, COUNT(t.recommend_product) AS 购买次数
    FROM GRAPH_TABLE (
    product_recommend_graph
    MATCH (c:customer)-[o:orders]->(i1:order_item),
        (c)-[o2:orders]->(i2:order_item)
    WHERE i1.product_name = '手机' AND i2.product_name != '手机'
    COLUMNS (i2.product_name AS recommend_product)
    ) t
    GROUP BY t.recommend_product
    ORDER BY 购买次数 DESC;

    执行后,会返回购买过手机的用户同时购买的其他产品及购买次数,可直接用于产品推荐场景。

Related Posts