图数据库使用及业务场景

news2024/11/24 17:47:25

一. 前言

来学习下图数据以及图数据库

二. 图数据库的简单原理

2.1 图数据

我认为图数据结构就是点线面的关系,图大致分为以下概念 :

  • 节点 : 图中的基本元素,可以用来表示现实世界中的一个**实体 **
  •  : 节点之间连接的线,用来描述实体之间的关系 边可以有方向,有起始节点到终止节点边可以包含属性
  • 属性 :节点和边都可以包含属性,属性存储有关实体的信息
  • 权重 :权重指边上的一个值,用来标识成本,强度等等概念 (最短路径,最低消耗等)
  • 路径 :一个节点到另外一个节点的路程表示路径,一个路径可以包含多个节点多个边
分类
  • 按照图的方向性可以分为 :有向图,无向图
  • 按照边是否带权重可以分为 :有权图,无权图
  • 按照边的多少可以分为 : 稠密图,稀疏图
  • 按照特定类型包括 : 邻接矩阵、邻接表、关联矩阵

2.2 图数据案例

  • Neo4j: Neo4j是最受欢迎的图数据库之一,采用图结构来存储数据,并提供高效的图查询和遍历功能。Neo4j支持Cypher查询语言,适用于各种图数据分析任务
  • OrientDB : 一个多模型数据库,支持图数据库、文档数据库和对象数据库
  • Dgraph : 一个分布式图数据库,支持属性图和图数据库功能

好了,图的基本概念是清楚了,用法我们基于 Neo4j 来看

三. 图数据库 Neo4j

2.1 创建图数据库 Neo4j

可惜找了几个云服务商都没能薅羊毛,没看到可以免费领取的图数据库,所以只能自己安装下 Neo4j 了,简单点还是基于 Docker :

准备 docker-compose.yml
version: '3'
services:
  neo4j:
    image: neo4j:latest
    container_name: neo4j
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
      NEO4J_AUTH: neo4j/test123456
安装运行
docker-compose up -d

> 访问地址
http://localhost:7474/

2.2 弄清楚 Neo4j 里面的一些知识点

  • 可以通过配置创建多个Neo4j 实例,但是这种创建属于物理层面,需要修改底层配置
  • 不同于关系型数据库和NoSQL , 一个 Neo4j 实例里面只有一个主图多个子图(Enterprise版本才有子图)
  • 标签和属性更像一种分类,而不是单纯的看成节点的字段
支持的索引
  • 节点索引 :基于节点的属性创建索引
  • 关系索引 :用于关系的查找操作,基于关系的属性创建索引
  • 全文索引 :在节点的文本属性上创建,执行全文搜索查询
  • 空间索引 :用于地理空间数据 ,支持范围搜索和最近搜索
  • 时间/属性/组合等自定义索引 :其他的索引类型
CREATE INDEX ON :Person(name)

2.3 Neo4j 使用流程

使用层面上我们首先创建一个人物画像/社交网络,用于后续的分析 :

S1 : 创建节点
  • 语法 : CREATE (node:Label {property: value})
  • node 是节点变量名,可以通过 return 返回这个变量,用于后续使用,本身无含义
  • property 表示节点的属性,键值对关系,可以有多个
  • label :节点标签,用来标识节点的类型
CREATE (n1:User {name:'会员A',level:'1'}) RETURN n1;
CREATE (n2:User {name:'会员B',level:'2'}) RETURN n2;
CREATE (n3:User {name:'会员C',level:'3'}) RETURN n3;
CREATE (n4:User {name:'会员D',level:'4'}) RETURN n4;
CREATE (n5:User {name:'会员E',level:'5'}) RETURN n5;


// 创建节点的时候创建关系
CREATE (a:User {name:'会员F'})-[r:FRIENDS]->(b:User {name:'会员D'})
S2 : 查询节点
  • 查询所有节点 :MATCH (n:User {}) RETURN n
  • 查询特定属性 :MATCH (n:User {name:'会员A'}) RETURN n

查询到的结果

S3 : 为节点创建关系
MATCH (startNode:Label1), (endNode:Label2)
CREATE (startNode)-[:RELATIONSHIP_TYPE]->(endNode)
  • MATCH 子句用于匹配起始节点(startNode)和结束节点(endNode),通常使用标签和属性来过滤节点
  • CREATE 子句用于创建关系,表示连接起始节点和结束节点
  • [:RELATIONSHIP_TYPE] 是关系的类型,可以替换为想要创建的关系类型
  • 箭头表示关系的方向,从起始节点指向结束节点
// 创建 User 节点间的关系 (关系为朋友)
MATCH (a:User {name:'会员A'}), 
      (b:User {name:'会员B'}) 
MERGE (a)-[:FRIENDS]->(b)

// ↑↑↑↑ 解释
- 这里的 a 和 b 都是节点别名,用于创建关系时使用
- User 标识的是节点类型,查询这一类节点
- name 才是匹配节点的关联关系,这里是 name ,也可以是 id 等更加具体的属性

S4 : 关系查询

PS : 这里的 sn ,en 都是别名,表示是 startNode 、 endNode ,篇幅有限

- 查询特定的关系的关系 :MATCH ()-[relation:FRIENDS]->() RETURN relation
- 查询有特定关系的节点 :MATCH (n)-[:FRIENDS]-() RETURN n
- 查询特定节点和关系   :MATCH (n:User)-[:FRIENDS]-(friend:User) RETURN n, friend

// 复杂查询
- 复杂语句 :MATCH (sn)-[relation]-(en) WHERE sn.name = '会员A' AND en.name = '会员B' RETURN relation
- 特定关系 :MATCH (sn)-[rl:FRIENDS]->(en) WHERE sn.name = '会员A' RETURN rl, en
- 查询属性 :MATCH ()-[relation:FRIENDS]->() RETURN relation.propertyName
- 查询数量 :MATCH (sn)-[rl]->(en) WHERE sn.name = '会员A' RETURN COUNT(rl)
- 查询路径 :MATCH path = (sn)-[rl*]->(en) WHERE sn.name = '会员A' AND en.name = '会员C' RETURN path

以上基础就完成了,后续就进行相关的业务扩展了

S5 : 创建更多类型的节点
CREATE (n1:address {name:'武汉'}) RETURN n1;
CREATE (n2:address {name:'上海'}) RETURN n2;
CREATE (n3:address {name:'北京'}) RETURN n3;
CREATE (n4:address {name:'深圳'}) RETURN n4;
CREATE (n5:address {name:'杭州'}) RETURN n5;
S6 : 创建复杂的关系图
// 地址关联
MATCH (a:User {name:'会员A'}), (b:address {name:'武汉'}) MERGE (a)-[:ADDRESS]->(b);
MATCH (a:User {name:'会员B'}), (b:address {name:'武汉'}) MERGE (a)-[:ADDRESS]->(b);
MATCH (a:User {name:'会员C'}), (b:address {name:'武汉'}) MERGE (a)-[:ADDRESS]->(b);
MATCH (a:User {name:'会员D'}), (b:address {name:'上海'}) MERGE (a)-[:ADDRESS]->(b);
MATCH (a:User {name:'会员E'}), (b:address {name:'北京'}) MERGE (a)-[:ADDRESS]->(b);
MATCH (a:User {name:'会员A'}), (b:address {name:'深圳'}) MERGE (a)-[:FRIENDS]->(b);
MATCH (a:User {name:'会员A'}), (b:address {name:'杭州'}) MERGE (a)-[:FRIENDS]->(b);

// 朋友关联 : 
MATCH (a:User {name:'会员B'}), (b:User {name:'会员E'}) MERGE (a)-[:FRIENDS]->(b);
S7 : 最终效果
// 查询所有节点和节点间的关系 :
MATCH (n) RETURN n

// 查询所有有关系的节点
MATCH (a)--() RETURN a


// 查询所有对外有关系的节点,以及关系类型
MATCH (a)-[r]->() RETURN a.name, type(r)

S8 : 基于图的业务价值
// 查询与武汉节点关联的节点
MATCH (a:address {name: '武汉'})-[r]-(b) RETURN b
MATCH (a:address {name: '武汉'})-[r]-(b) RETURN a,b
- PS : 这里 return 可以返回多个,展示的效果是不同的


// 查询朋友的朋友
MATCH (a:User {name:'会员A'})-[r1:FRIENDS]-()-[r2:FRIENDS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName
S9 : 补充语法
// 修改节点属性
MATCH (a:User {name:'会员A'}) SET a.city="武汉"

// 删除节点属性
MATCH (a:User {name:'会员A'}) REMOVE a.city

// 删除节点
MATCH (a:User {name:'会员G'}) DELETE a

// 删除关系
MATCH (a:User {name: '会员G'})-[r:FRIENDS]-(b:User {name: '会员D'}) DELETE r

// 删除节点及关系
MATCH (alice:User {name: '会员G'}) DETACH DELETE alice

三. 性能对比

性能比较主要集中在特定的场景,图数据库因为其特殊的形式,在深度遍历等方面的效率是远大于关系型数据库的,取自Neo4j 官方的博文 : @ http://neo4j.com/news/how-mu…

在 一百万数据 里面抽取 1000 个样本进行计算,查询朋友的朋友,按照不同的深度进行查询。

对于简单的好友的好友查询,Neo4j 比 MySQL 快 60%。对于朋友的朋友的朋友来说,Neo 的速度快了 180 倍。对于深度四查询,Neo4j 的速度快了 1,135 倍

四. 业务上怎么使用它更受益

在此期间比较浅显的读了一下 Neo4j 实战,大概可以从这几个方面来描述一下图数据库的优势 :

4.1 图数据库的使用场景

想看使用场景我们直接去官方看案例即可 :

我打交道比较多的就是社交和零散,主要看看这两块

社交关系

不知道大家有没有听过一个理论叫六度分隔理论,这个理论说的就是 : 世界上任意两个人之间的联系最多需要通过不超过六个中介,即通过六个人,就可以建立起联系

我们假设这个理论上成立的,我想知道我和一个陌生人之间可以是通过哪几个人进行关联的,首先从 MySQL 角度看 :

  • S1 : 构建一个人员信息表 , 为每个人员分配一个主键,标识现实中的实体
  • S2 : 构建一个关联信息表,构建这个人会和哪些人员进行关联
  • S3 : 走3个left join 或者逻辑中进行 for 循环+算法进行判断

很明显,这种方式占用资源很多,一不小心就会形成笛卡尔积,几何倍数

那么如果用图数据库,该怎么做?

// 展示会员A 朋友的朋友的朋友
MATCH (start:User {name: '会员A'})-[:FRIENDS*3]-(foaf:User) RETURN start, foaf
零售行业

最直接的包括最短路径算法,最优库存的实现 , 其次包括会员关系,精准有效都有些作用。

最短路径最直接的场景就是送外卖,哪些外卖分配更加合理。往更高级方向想就是物流。

总结

图数据库的使用是能解决很多复杂场景的问题的,但是这需要达到一定的量级。没达到量级使用关系型数据一样能满足。

但是整体来说,针对特定场景提高效率,优化业务,精准消费的效果还是很可观的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/845379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口自动化测试Mock Get和Post请求

Mock可以模拟一个http接口的后台响应,可以模拟request,response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…

恶意软件和反病毒

1. 什么是恶意软件? 恶意软件(Malware)是指以恶意目的而设计和开发的计算机软件。恶意软件的目标是在未经授权或知情的情况下入侵用户的计算机系统、窃取敏感信息、破坏系统功能或进行其他有害活动。恶意软件可以采取多种形式&#x…

VUE vue天气预报 高德接口 和风天气

方法一: 高德天气 1、引入axios import axios from "axios"; 2、 发生请求 getWeatherData() {let url https://restapi.amap.com/v3/weather/weatherInfo?city杨浦区&keyd77b4c08b2718e4e06def82570d3e834&extensionsbase;axios.get(url).then(res >…

Windows下安装Sqoop

Windows下安装Sqoop 一、Sqoop简介二、Sqoop安装2.1、Sqoop官网下载2.2、Sqoop网盘下载2.3、Sqoop安装(以version:1.4.7为例)2.3.1、解压安装包到 D:\bigdata\sqoop\1.4.7 目录2.3.2、新增环境变量 SQOOP_HOME2.3.3、环境变量 Path 添加 %SQO…

【统计学精要】:使用 Python 实现的统计检验— 1/10

一、介绍 欢迎来到“掌握 Python 统计测试:综合指南”,它将介绍本手册中您需要熟悉使用 Python 的所有基本统计测试和分析方法。本文将为您提供统计测试及其应用的全面介绍,无论您是新手还是经验丰富的数据科学家。 使用来自现实世界的实际示…

Linux学习之sed替换命令讲解

cat /etc/redhat-release看到操作系统是CentOS Linux release 7.6.1810,uname -r看到内核版本是3.10.0-957.el7.x86_64,bash --version可以看到bash版本是4.2.46(2)。 sed(sed strem editor)可以理解为行编辑器,但它…

C++ Lambda表达式的完整介绍

一、Lambda表达式概述 c在c11标准中引入了lambda表达式,一般用于定义匿名函数,lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步…

SpringBoot对接OpenAI

SpringBoot对接OpenAI 随着人工智能技术的飞速发展,越来越多的开发者希望将智能功能集成到自己的应用中,以提升用户体验和应用的功能。OpenAI作为一家领先的人工智能公司,提供了许多先进的自然语言处理和语言生成模型,其中包括深…

eclipse Java Code_Style Code_Templates

Preferences - Java - Code Style - Code Templates Eclipse [Java_Code_Style_Code_Templates_ZengWenFeng] 2023.08.07.xml 创建一个新的工程,不然有时候不生效,旧项目可能要重新导入eclipse 创建一个测试类试一试 所有的设置都生效了

【雕爷学编程】Arduino动手做(195)---HT16k33 矩阵 8*8点阵屏模块5

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

Nginx(2)

目录 1.安装Nginx1.yum安装2.编译安装3.Nginx命令 2.配置文件详解 1.安装Nginx 1.yum安装 [rootdocker ~]# yum -y install nginx通过 rpm -ql nginx 查看安装信息 2.编译安装 2.1安装所需要的依赖 yum install -y gcc gcc-c make libtool wget pcre pcre-devel zlib zlib-…

4. C++构造函数和析构函数

一、对象的初始化和清理 C中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置,对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知的使用完一个对象或变量&#x…

CentOS7安装Maven详细教程

😊 作者: Eric 💖 主页: https://blog.csdn.net/weixin_47316183?typeblog 🎉 主题:CentOS7安装Maven详细教程 ⏱️ 创作时间: 2023年08月06日 第一步:上传或下载安装包&#x…

【Element】el-cascader 级联选择器

ElementUI label 为空的不展示 将children设为undefined dg(list) {list.forEach(item > {item.label item.nameitem.value item.iditem.children item.childrenList.length ! 0 ? item.childrenList : undefinedif (item.children) {this.dg(item.children)}}) },第…

拦截器对接口细粒度权限校验

文章目录 一、逻辑分析二、校验规则1.规则类型2.规则划分3.规则配置信息4.规则案例说明5.规则加载 三、拦截器定义1.自定义拦截器2.注册拦截器 四、获取请求参数1.获取get提交方式参数2.获取post提交方式参数(1)定义RequestWrapper类(2&#…

pinctrl_desc结构体注册

pinctrl_desc结构体注册 文章目录 pinctrl_desc结构体注册pinctrl_registerpinctrl_register_pins注册所有的引脚 pinctrl_register 构建好struct pinctrl_desc结构以后,会调用pinctrl_register函数注册一个pinctrl控制器,得到一个pinctrl_dev struct …

【大数据】Flink 详解(二):核心篇 Ⅰ

Flink 详解(二):核心篇 Ⅰ 14、Flink 的四大基石是什么? ​ Flink 的四大基石分别是: Checkpoint(检查点)State(状态)Time(时间)Window&#xff…

【机器学习2】什么是Jupyter notebook 新手使用Jupter notebook

什么是Jupyter notebook? Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享程序文档,支持实时代码&#x…

Redis 7.X Linux 环境安装

Redis 简介 作为一名开发人员,想必大家对Redis一定是耳熟能详,因此在此只做简单介绍。 Remote Dictionary Server(远程字典服务)是完全开源的,使用ANSIC语言编写遵守BSD协议,是一个高性能的Key-Value内存数据库,它提…

命令模式(C++)

定义 将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 应用场景 在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合——比…