当前位置: 首页 > news >正文

门户网站开发要多少钱淮安市工程造价信息网

门户网站开发要多少钱,淮安市工程造价信息网,深圳建设网站制作公司,如何提高网站的收录量一、背景 在社交网络、知识图谱、推荐系统等领域,常常需要处理 大规模、多跳、多属性的复杂关系网络。以社交网络为例: 用户之间存在「单向或双向」的关注、好友关系。 常见的业务场景包括:查找共同好友、N跳关系路径、基于属性筛选的路径…

一、背景

在社交网络、知识图谱、推荐系统等领域,常常需要处理 大规模、多跳、多属性的复杂关系网络。以社交网络为例:

用户之间存在「单向或双向」的关注、好友关系。

常见的业务场景包括:查找共同好友、N跳关系路径、基于属性筛选的路径分析等。

随着用户数量和关系数量增长,传统关系型数据库在表示、维护及查询这些关系时将面临性能瓶颈。

我们可以把这些问题抽象为图问题:

用户是节点(顶点)

关系是边

查询变成在图上找路径、多跳连接、筛选满足属性条件的节点

初始做法:用关系型数据库模拟图

在没用图数据库前,我们可能这么实现:

一张 user 表存用户信息

一张 user_relation 表存用户关系(from_id、to_id、type)

多跳查询靠 BFS、DFS 遍历模拟

但是当数据规模上来,比如几百万用户、上千万条关系,多跳查询会非常慢,因为每一跳都要在数据库里查,产生大量随机 I/O。

扩展性问题也很明显:
如果要加公司、城市等新类型实体

要改表结构,还要改查询逻辑,很难维护

图数据库就是为这种结构复杂、关系密集、查询灵活的问题设计的。

基本概念:

名称含义
图(Graph)实体 + 关系 构成的结构
顶点(Vertex)也叫节点,代表具体实体,如“用户”、“城市”
边(Edge)顶点之间的关系,如“朋友”、“工作于”
属性(Property)节点或边上的附加信息,如“用户年龄”、“关系时间”

图数据库的两种存储模型

原生图(Native Graph DB)
底层就是用图结构存储,比如 Neo4j:

节点之间直接有引用(指针)

遍历节点时无需查索引(Index-free adjacency)

查询性能随子图规模线性增长(而不是整个数据量)

适合高频、多跳、实时的图计算场景。

非原生图(Non-native)
底层存的是其他数据库(如关系型),只是加了一层图语义支持,比如:

Apache TinkerPop + 外部存储

查询效率不如原生图,但接入简单、通用性好

Neo4j 简要介绍

Neo4j 是目前最广泛使用的图数据库之一,特点是:

原生图存储引擎

提供 Cypher 查询语言(类 SQL,很易上手)

查询效率高,尤其在多跳、多关系链场景表现优秀

提供 REST API 或嵌入式调用

Cypher

  1. 节点表示

节点使用圆括号 () 表示。

// 表示一个节点
(node)
添加标签(类似关系型数据库中的表)

// 带有 Person 标签的节点
(person:Person)
一个节点可以有多个标签

// 同时带有 Person 和 Employee 标签的节点
(person:Person:Employee)

关系可以有类型

// KNOWS 类型的关系
(person1:Person)-[:KNOWS]->(person2:Person)

节点和关系可以有属性,属性使用大括号 {} 表示

// 带属性的节点
(person:Person {name: “张三”, age: 30})

// 带属性的关系
(person1:Person)-[:KNOWS {since: 2015}]->(person2:Person)
一些常用示例:

// 创建用户节点
CREATE (:User {name: "Alice", age: 25})
// 如果需要引用这个节点,可以给节点一个变量名
CREATE (u:User {name: "Alice", age: 30})
// 创建关系
MATCH (a:User {name: "Alice"}), (b:User {name: "Bob"})
CREATE (a)-[:FRIEND {since: 2020}]->(b)// 查询 Alice 的所有朋友
MATCH (a:User {name: "Alice"})-[:FRIEND]->(friend)
RETURN friend.name// 查询 Alice 的“朋友的朋友”
MATCH (a:User {name: "Alice"})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN DISTINCT fof.name//修改数据
// 修改 Bob 的年龄
MATCH (u:User {name: "Bob"})
SET u.age = 35// 给 Charlie 增加城市属性
MATCH (u:User {name: "Charlie"})
SET u.city = "Beijing"
//删除数据
// 删除某个用户节点及其所有关系
MATCH (u:User {name: "Alice"})
DETACH DELETE u
//创建带属性的复杂结构
// 创建用户、公司、工作关系
CREATE (u:User {name: "Diana"})
CREATE (c:Company {name: "OpenAI"})
CREATE (u)-[:WORKS_AT {role: "Engineer", since: 2021}]->(c)
//路径与最短路径查询// 查询 Alice 到 Charlie 的最短路径
MATCH (a:User {name: "Alice"}), (c:User {name: "Charlie"}),
p = shortestPath((a)-[*..5]-(c))
RETURN p
//使用 WHERE 条件过滤
// 查询30岁以上的用户
MATCH (u:User)
WHERE u.age > 30
RETURN u.name, u.age// 查询工作在“OpenAI”的用户
MATCH (u:User)-[:WORKS_AT]->(c:Company {name: "OpenAI"})
RETURN u.name

底层结构

作为「原生图」模式的图数据库,免索引邻接是实现高效查询性能的重要因素,因此免索引邻接的实现机制就是neo4j 底层存储结构设计的关键。
在 neo4j 中,点、关系和属性等组成元素的结构长度是固定的,同时基于内部维护的ID进行访问。所以知道某点/关系/属性的ID,就能计算得到在对应文件中的偏移位置,直接进行访问。在遍历图时就省去了基于索引扫描的中间过程。
底层存储逻辑图:包括节点(label)、关系、属性要素,并通过指针维护关系

节点结构(指向关系和属性的单向链表,neostore.nodestore.db):共15字节。
<1bytes: 标志是否被使用>、<4bytes: 第一个关系ID>、<4bytes: 第一个属性ID>、<5bytes: 节点标签>、<1bytes: extra保留位>
关系结构(双向链表,neostore.relationshipstore.db):共34bytes
<1bytes: 标志是否被使用>、<4bytes: 起始节点ID>、<4bytes:结束节点ID>、<4bytes: 关系类型>、<4bytes: 起始节点上个关系>、<4bytes: 起始节点下个关系>、<4bytes: 结束节点上个关系>、<4bytes: 结束节点下个关系> 、<4bytes: 第一个属性ID>、<1bytes: 是否为该起点和终点的第一个关系>
属性结构(单项链表,neostore.propertystore.db):属性结构同理

golang使用Neo4j

go get github.com/neo4j/neo4j-go-driver/v5/neo4j

package mainimport ("context""fmt""log""github.com/neo4j/neo4j-go-driver/v5/neo4j"
)func main() {// 创建 driver 实例uri := "neo4j://localhost:7687"username := "neo4j"password := "your_password" // 请替换成你自己的密码// 连接数据库driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(username, password, ""))if err != nil {log.Fatal("创建 Neo4j driver 失败:", err)}defer driver.Close(context.Background())// 开始一个会话session := driver.NewSession(context.Background(), neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite,})defer session.Close(context.Background())// 执行 Cypher 创建节点_, err = session.ExecuteWrite(context.Background(), func(tx neo4j.ManagedTransaction) (any, error) {_, err := tx.Run(context.Background(),`CREATE (a:Person {name: $name, age: $age}) RETURN a`,map[string]any{"name": "Alice","age":  30,})return nil, err})if err != nil {log.Fatal("写入节点失败:", err)}fmt.Println("成功创建节点")// 执行查询result, err := session.ExecuteRead(context.Background(), func(tx neo4j.ManagedTransaction) (any, error) {res, err := tx.Run(context.Background(),`MATCH (a:Person) RETURN a.name AS name, a.age AS age LIMIT 10`,nil)if err != nil {return nil, err}var results []map[string]anyfor res.Next(context.Background()) {record := res.Record()results = append(results, map[string]any{"name": record.Values[0],"age":  record.Values[1],})}return results, nil})if err != nil {log.Fatal("查询失败:", err)}// 输出结果for _, r := range result.([]map[string]any) {fmt.Printf("Person: name=%v, age=%v\n", r["name"], r["age"])}
}

Java使用neo4j

springdata-neo4j的实例:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId></dependency>
</dependencies>

application.yml:

spring:neo4j:uri: bolt://localhost:7687authentication:username: neo4jpassword: your_password

person.java:

import org.springframework.data.neo4j.core.schema.*;import java.util.HashSet;
import java.util.Set;@Node
public class Person {@Id @GeneratedValueprivate Long id;private String name;@Relationship(type = "KNOWS", direction = Relationship.Direction.OUTGOING)private Set<Person> friends = new HashSet<>();public Person() {}public Person(String name) {this.name = name;}// getter 和 setter
}

repository:

import org.springframework.data.neo4j.repository.Neo4jRepository;public interface PersonRepository extends Neo4jRepository<Person, Long> {Person findByName(String name);
}

PersonService.java:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class PersonService {private final PersonRepository personRepository;public PersonService(PersonRepository personRepository) {this.personRepository = personRepository;}@Transactionalpublic void createData() {Person alice = new Person("Alice");Person bob = new Person("Bob");alice.getFriends().add(bob);personRepository.save(alice); // 会级联保存 bob 和关系}public Person findByName(String name) {return personRepository.findByName(name);}
}

controller:

import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/person")
public class PersonController {private final PersonService personService;public PersonController(PersonService personService) {this.personService = personService;}@PostMapping("/init")public String init() {personService.createData();return "ok";}@GetMapping("/{name}")public Person get(@PathVariable String name) {return personService.findByName(name);}
}
http://www.yayakq.cn/news/487683/

相关文章:

  • 网站管理人员队伍建设有待加强宁德市高中阶段招生信息平台
  • 企业建设门户网站成本如何网站建设前端
  • 佛山新网站制作公司挖矿网站怎么免费建设
  • 天涯网站建设路小学wordpress博客手机发布
  • 怎么给自己的网站做排名wordpress 终极优化
  • 贵州省遵义市建设局网站如何制作网页链接教程
  • 织梦古典网站模板网页框架结构有哪些
  • 残疾人信息无障碍网站建设软件开发平台是指什么
  • 做网站属于技术开发吗网络市场调研的步骤
  • 可以做高中题目的网站如何把做的网站放到百度上
  • typecho做网站绿植租摆网站建设
  • 网上做网站资金大概多少建设网站怎么输入分子式
  • 国内知名域名注册网站物流网站html5模板
  • 建设银行网站怎么基本转个人地产网
  • 金塔网站建设电影订票网站怎么做
  • 专业的网站建设服务商网站做任务领q币
  • 北京seo公司网站厦门网络营销公司
  • 宿迁网站建设开发网站建设公司响应式网站模板
  • 怎么建立自己的网站免费想办个网站怎么做
  • 柳州网站建设公司哪家好建站宝盒设置
  • 建设电影会员网站成都网站建设与推广
  • 宁波关键词网站排名免费做的网站怎么设置域名
  • 黄埔网站开发公司媒约网网址是多少
  • 沧州网站艰涩很游戏开发需要学什么编程语言
  • 网站建行接口企业网站ui设计
  • 中小企业建设网站建站教程下载
  • 建站seo怎么赚钱网站收录教程
  • 网站建设开发有什么好处网站怎么做快推广方案
  • 海沧区建设局网站 破路申请内网怎么做网站服务器
  • 青岛建设房地产招聘信息网站猎头公司网站建设