neo4j图数据库练习题
2.
请结合自身电商网站购物经历,思考电商购物平台涉及的关键实体及它们之间的业务
关系.
(1)画出涵盖客户、商品、商家、订单、支付账户、商品评价相关实体及其关系的属性图
要求每个节点至少包含5个属性,每个关系至少包含两个属性.
(2)写出创建该属性图的图数据CQL语句序列.
(Customer)---[Purchases]--->(Product)
(Customer)---[Places]------>(Order)
(Order)---[Contains]------>(Product)
(Customer)---[Reviews]----->(Product)
(Seller)---[Sells]-------->(Product)
(Customer)---[Uses]-------->(Payment Account)
// 创建客户节点
CREATE (:Customer {
customer_id: 'C001',
name: 'Alice',
email: 'alice@example.com',
phone: '1234567890',
address: '123 Main St'
});
// 创建商品节点
CREATE (:Product {
product_id: 'P001',
name: 'Laptop',
category: 'Electronics',
price: 1200.00,
stock: 50
});
// 创建商家节点
CREATE (:Seller {
seller_id: 'S001',
name: 'TechShop',
rating: 4.5,
location: 'City Center',
contact: 'seller@techshop.com'
});
// 创建订单节点
CREATE (:Order {
order_id: 'O001',
order_date: '2024-10-12',
total_amount: 1200.00,
status: 'Shipped',
shipping_address: '123 Main St'
});
// 创建支付账户节点
CREATE (:PaymentAccount {
account_id: 'PA001',
account_type: 'Credit Card',
balance: 5000.00,
currency: 'USD',
linked_to: 'Alice'
});
// 创建商品评价节点
CREATE (:ProductReview {
review_id: 'R001',
rating: 5,
comment: 'Great product!',
review_date: '2024-10-13',
customer_id: 'C001'
});
// Customer 购买 Product
MATCH (c:Customer {customer_id: 'C001'}), (p:Product {product_id: 'P001'})
CREATE (c)-[:Purchases {purchase_date: '2024-10-10', quantity: 1}]->(p);
// Customer 生成 Order
MATCH (c:Customer {customer_id: 'C001'}), (o:Order {order_id: 'O001'})
CREATE (c)-[:Places {order_date: '2024-10-10', quantity: 1}]->(o);
// Order 包含 Product
MATCH (o:Order {order_id: 'O001'}), (p:Product {product_id: 'P001'})
CREATE (o)-[:Contains {quantity: 1, price: 1200.00}]->(p);
// Customer 评价 Product
MATCH (c:Customer {customer_id: 'C001'}), (p:Product {product_id: 'P001'})
CREATE (c)-[:Reviews {rating: 5, comment: 'Great product!'}]->(p);
// Seller 销售 Product
MATCH (s:Seller {seller_id: 'S001'}), (p:Product {product_id: 'P001'})
CREATE (s)-[:Sells {availability: 'In Stock', price: 1200.00}]->(p);
// Customer 使用 Payment Account
MATCH (c:Customer {customer_id: 'C001'}), (pa:PaymentAccount {account_id: 'PA001'})
CREATE (c)-[:Uses {payment_date: '2024-10-12', amount: 1200.00}]->(pa);
3
请结合自身使用快递服务的经历,思考快递行业业务模型。快递企业核心服务即将寄递物品从快递发件人通过物流中转最终送达收件人。
(1)请用图数据库存储快递行业人与人之间的收发寄递关系图数据,设计画出客户、快递面单、快递员三个核心实体之间的属性图。其中客户可以是收件人,也可以是寄件人;快递员可以是上门揽件的业务员,也可以是上门送件的派件业务员:快递面单可以简化,至少包含寄件人姓名、寄件人电话、寄件省份、寄件地址、收件人姓名、收件人电话、收件省份、收件地址、寄件物品、寄件价格10个属性:客户与快递员至少包含5个属性;每个关系至少包含两个属性。(2)写出创建该属性图的CQL语句序列。
(Customer)---[Sends]------>(Shipment Order)<---[Receives]---(Customer)
|
[Collects] (Courier)
|
[Delivers]
// 创建寄件人客户节点
CREATE (:Customer {
customer_id: 'C001',
name: 'John Doe',
phone: '1234567890',
address: '123 Sender St',
province: 'Beijing'
});
// 创建收件人客户节点
CREATE (:Customer {
customer_id: 'C002',
name: 'Jane Smith',
phone: '0987654321',
address: '456 Recipient Rd',
province: 'Shanghai'
});
// 创建快递面单节点
CREATE (:ShipmentOrder {
order_id: 'SO001',
sender_name: 'John Doe',
sender_phone: '1234567890',
sender_province: 'Beijing',
sender_address: '123 Sender St',
recipient_name: 'Jane Smith',
recipient_phone: '0987654321',
recipient_province: 'Shanghai',
recipient_address: '456 Recipient Rd',
item: 'Laptop',
price: 1000.00
});
// 创建揽件快递员节点
CREATE (:Courier {
courier_id: 'CR001',
name: 'Tom Wilson',
phone: '1112223333',
region: 'Beijing',
role: 'Collector'
});
// 创建派件快递员节点
CREATE (:Courier {
courier_id: 'CR002',
name: 'Alice Brown',
phone: '4445556666',
region: 'Shanghai',
role: 'Deliverer'
});
// 客户寄送快递
MATCH (sender:Customer {customer_id: 'C001'}), (order:ShipmentOrder {order_id: 'SO001'})
CREATE (sender)-[:Sends {send_date: '2024-10-10', send_time: '10:30 AM'}]->(order);
// 客户接收快递
MATCH (recipient:Customer {customer_id: 'C002'}), (order:ShipmentOrder {order_id: 'SO001'})
CREATE (recipient)-[:Receives {receive_date: '2024-10-12', receive_time: '3:45 PM'}]->(order);
// 快递员揽件
MATCH (courier:Courier {courier_id: 'CR001'}), (order:ShipmentOrder {order_id: 'SO001'})
CREATE (courier)-[:Collects {collect_date: '2024-10-10', collect_time: '10:00 AM'}]->(order);
// 快递员派件
MATCH (courier:Courier {courier_id: 'CR002'}), (order:ShipmentOrder {order_id: 'SO001'})
CREATE (courier)-[:Delivers {deliver_date: '2024-10-12', deliver_time: '3:00 PM'}]->(order);
4
写出遍历Neo4j图数据库中以节点标识为100的节点为起点,长度小于等于5的关系路径,返回路径上包含的所有节点列表的CQL语句。
MATCH p = (n)-[*..5]-(m)
WHERE id(n) = 100
RETURN nodes(p) AS nodes_list;
7.
Neo4j索引有什么作用?属性与标签都可以建立索引吗?如果可以,请分别举例,写出具体给节点、关系的属性、标签建立索引的命令。
8.
简述Neo4i因果集群架构与高可用性集群架构有什么不同。因果集群中核心服务器与只读副本服务器的作用分别是什么?
9.
请选择一种将CSV数据文件导人Neo4i数据库的方法,思考某一应用场景,写出完整
的命令序列,并实践完成数据导人,在库中创建相应的节点及关系。10.Neo4j中如何体现事务管理?当事务发生死锁时,一般有哪些处理方法?11.Neo4j如何备份与恢复一个图数据库?请实践并总结写出备份、恢复一个图数据库实例的方法及步骤。
7. Neo4j 索引的作用及创建索引的命令
索引的作用:
Neo4j 中的索引用于加速数据查询,尤其是在使用属性进行节点或关系的查找时。通过建立索引,Neo4j 能快速查找与某些属性值匹配的节点或关系,避免对整个图进行全局扫描,从而提高查询效率。
属性与标签都可以建立索引:在 Neo4j 中,既可以对节点的属性、关系的属性,也可以对节点的标签创建索引。
示例:为节点的属性和标签建立索引
-
为节点的属性建立索引:
例如,我们有一组用户节点,每个用户都有一个name
属性。我们可以为name
属性创建索引来加速查询。CREATE INDEX FOR (n:User) ON (n.name);
这里的
User
是节点的标签,name
是属性。该命令为所有User
标签的节点上的name
属性建立索引。 -
为关系的属性建立索引:
关系也可以有属性,例如一组LIKES
关系,每个关系都有一个since
属性,我们可以为since
属性创建索引:CREATE INDEX FOR ()-[r:LIKES]-() ON (r.since);
这里的
LIKES
是关系类型,since
是关系的属性。
示例:为标签建立索引
Neo4j 允许我们对标签本身建立索引,以便快速查找特定标签的节点。通常是间接通过属性进行查询,直接为标签创建索引较少。
CREATE INDEX FOR (n:Person) ON (n.age, n.name);
这条语句为 Person
标签的节点上的 age
和 name
属性建立联合索引。
8. Neo4j 因果集群架构与高可用性集群架构的区别
因果集群架构 (Causal Cluster Architecture) 和 高可用性集群架构 (High Availability Architecture) 的主要区别在于数据一致性和节点类型的配置。
-
高可用性集群架构 (High Availability):
- 高可用性集群使用主从复制模型(Master-Slave Architecture),集群中的一个节点是主节点,其它节点是从节点。
- 所有写操作都必须通过主节点进行,然后主节点将数据复制到从节点。
- 该架构的缺点是当主节点故障时,系统需要进行重新选举,可能会导致暂时的不可用。
-
因果集群架构 (Causal Cluster):
- 因果集群引入了核心服务器 (Core Server) 和 只读副本服务器 (Read Replica)。
- 核心服务器:负责写操作,具有完全一致性。它们通过共识算法(如 Raft)来确保数据的一致性。
- 只读副本服务器:用于处理读操作,支持横向扩展,允许快速扩展只读查询的性能。读副本不会参与写操作,也不参与共识协议。
- 因果集群的优势在于提供更强的可扩展性,允许集群中有大量只读副本以提高读取性能,同时通过核心服务器的共识算法确保写操作的一致性。
9. 将 CSV 数据文件导入 Neo4j 的方法及应用场景
场景描述:
假设我们有一个社交网络的 CSV 数据文件,包含用户及其好友关系。我们要将这些数据导入到 Neo4j 数据库中,创建用户节点并建立好友关系。
CSV 文件格式:
users.csv
文件包含用户的基本信息:
userId,name,age,city
1,John Doe,30,New York
2,Jane Smith,25,Los Angeles
3,Michael Brown,35,Chicago
friendships.csv
文件包含用户之间的好友关系:
userId1,userId2,since
1,2,2015
1,3,2018
2,3,2017
导入数据的 CQL 命令序列:
- 导入用户节点:
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
CREATE (:User {userId: toInteger(row.userId), name: row.name, age: toInteger(row.age), city: row.city});
- 导入好友关系:
LOAD CSV WITH HEADERS FROM 'file:///friendships.csv' AS row
MATCH (u1:User {userId: toInteger(row.userId1)}), (u2:User {userId: toInteger(row.userId2)})
CREATE (u1)-[:FRIEND {since: toInteger(row.since)}]->(u2);
在这里:
LOAD CSV
读取 CSV 文件内容。MATCH
用于匹配已经创建的用户节点。CREATE
用于创建两个用户之间的FRIEND
关系,并将since
属性添加到关系中。
10. Neo4j 中的事务管理及死锁处理
事务管理:
在 Neo4j 中,事务管理确保数据库操作的原子性、一致性、隔离性和持久性(ACID)。事务的开始、提交和回滚操作允许我们在出现错误时回滚对数据库的修改,避免数据不一致。
BEGIN; // 开始事务
CREATE (n:Person {name: 'Alice'}); // 数据操作
COMMIT; // 提交事务
死锁处理:
当两个或多个事务互相等待对方释放资源时,会产生死锁。Neo4j 通常通过事务回滚机制来处理死锁,即中止一个或多个冲突的事务,允许其它事务继续执行。
处理方法包括:
- 增加重试机制:发生死锁时,自动重试事务。
- 优化事务逻辑:避免长时间持有锁,减少锁定的范围和时间。
- 使用合理的事务隔离级别:控制并发操作,减少竞争。
11. Neo4j 的备份与恢复
备份图数据库:
在 Neo4j 中,可以使用 neo4j-admin
工具来备份数据库。假设我们正在备份一个名为 neo4j
的数据库。
- 执行备份:
neo4j-admin backup --from=localhost:6362 --backup-dir=/path/to/backup --database=neo4j
这个命令将从本地运行的 Neo4j 实例中备份数据库到指定的备份目录中。
恢复图数据库:
- 停止数据库服务:
在恢复之前,必须停止 Neo4j 数据库服务:
neo4j stop
- 恢复数据库:
neo4j-admin restore --from=/path/to/backup --database=neo4j --force
这个命令会将备份的数据恢复到 Neo4j 数据库中。--force
参数表示如果有同名数据库存在,将其覆盖。
- 启动数据库服务:
恢复完成后,重新启动数据库:
neo4j start
通过这种方法,Neo4j 的数据库可以实现定期备份与恢复,以应对数据丢失或系统故障的情况。