初识 OrientDB
文章目录
- 初识 OrientDB
- OrientDB 的安装与连接
- OrientDB 二进制包安装
- Docker 安装
- 连接 OrientDB
- 可视化界面连接
- OrientDB 的使用
- 数据库管理
- 用户管理
- Classes 操作
- Cluster 操作
- 通用 CRUD 操作
- 插入数据
- 查询数据
- 修改数据
- 删除数据
- 图操作
- 创建顶点
- 删除顶点
- 创建边
- 删除边
- 遍历语句
OrientDB 的安装与连接
OrientDB 二进制包安装
OrientDB 的下载地址: http://www.orientdb.org/download
代码语言:javascript复制# 上传并解压压缩包
tar -zxf orientdb-community-3.2.5.tar.gz
# 进入启动脚本所在目录
cd orientdb-community-3.2.5/bin/
# 启动 OrientDB
./server.sh
# 关闭 OrientDB (请将 root_password 更换为真正的 root 用户密码 )
./shutdown.sh -p ROOT_PASSWORD
Ps: 第一次启动是会要求输入 root 用户密码,输入完后会自动保存到配置文件中
Docker 安装
代码语言:javascript复制# 拉取镜像
docker pull orientdb:3.2.5
# 通过镜像启动容器 (请将 root 更换为真正的 root 用户密码 )
docker run -d --name orientdb -p 2424:2424 -p 2480:2480 -e ORIENTDB_ROOT_PASSWORD=root orientdb:3.2.5
连接 OrientDB
代码语言:javascript复制# 进入 OrientDB 所在的解压目录下的脚本文件所在目录
cd orientdb-community-3.2.5/bin/
# 启动连接的控制台
./console.sh
# 在控制台中使用连接命令连接 (本地连接可以直接将 ip 换为 localhost)
connect remote:192.168.159.139 root root_password
# Ps: OrientDB 默认的连接端口为 2424
可视化界面连接
OrientDB 的的可视化界面为 http://localhost:2480
Ps 可以根据情况将 localhost 更改为 OrientDB 所安装的服务器的 ip
OrientDB 的使用
- Class: OrientDB 中的 Class 的概念类似于面向对象编程中的类,用户可以按照需求定义自己需要的属性。Class 一般默认会包含 0~多个 Cluster。创建一个 class 时,一般会创建 8 个 Cluster
- Cluster: Cluster 一般用于存放多条数据记录,Cluster 可以脱离 Class 而存在。
- record: 记录一般在 Cluster 中,每一条记录都有一个唯一的
rid
。rid
一般由 cluser_id 和记录在 cluster 中的位置组成,格式类似于#<cluster_id>:<id>
数据库管理
代码语言:javascript复制# 列出所有的数据库
list databases
# 创建本地数据库,名为 demo,指定数据库的存储位置
CREATE DATABASE PLOCAL:/usr/local/orientdb/databases/demo
# 创建远端数据库,名为 trick,加上用户名密码,存储方式为本地,如果要将数据放入内存中则需将 PLOCAL 改为 MEMORY
CREATE DATABASE REMOTE:192.168.1.1/trick root root_pwd PLOCAL
# 创建数据库,名为mydb, 加上用户名密码,本地存储方式,数据库模式为图数据库,指定备份目录位置为 /tmp/backup
create database remote:localhost/mydb root root_pwd plocal graph -restore=/tmp/backup
# 切换到名为 demodb 的数据库,并指定用户名密码
use remote:localhost/demodb root root_pwd
# 修改数据库自定义属性(禁用 SQL 严格解析)
ALTER DATABASE CUSTOM strictSQL=false
# 移除当前正在使用的数据库
DROP DATABASE
# 移除远程数据库
DROP DATABASE REMOTE:localhost/demo root root_password
用户管理
代码语言:javascript复制# 创建用户 Foo 密码为 bar 角色为管理员
CREATE USER Foo IDENTIFIED BY bar ROLE admin
# 为 Foo 授予集群 account 的 更新权限
GRANT UPDATE ON database.cluster.account TO Foo
# 回收 Foo 对所有集群的删除权限
REVOKE DELETE ON database.cluster.* FROM Foo
# 删除用户 Foo
DROP USER Foo
权限列表
权限 | 描述 |
---|---|
NONE | 该资源上不授予任何权限 |
CREATE | 为该资源授予创建权限,对应为 CREATE 语句和 INSERT |
READ | 为该资源授予读取权限,对应为 SELECT 语句 |
UPDATE | 为该资源授予更新权限,对应为 UPDATE 语句 |
DELETE | 为该资源授予删除权限,对应为 DROP 语句 |
ALL | 为该资源授予所有权限 |
资源列表
资源 | 描述 |
---|---|
database | 为当前数据库授予权限 |
database.class. | 为数据库中某个类授予权限,使用 * 代表所有的类 |
database.cluster. | 为数据库中某个集群授予权限,使用 * 代表所有的集群 |
database.query | 授予执行查询的能力 |
database.command. | 授予执行语句的权限, |
database.config. | 授予配置管理能力,合法的权限仅有 READ 和 UPDATE |
database.hook.record | 授予能够设置钩子的能力 |
server.admin |
Classes 操作
Classes 的概念类似于面向对象编程中的 Class。Class 是 OrientDB 中的一个数据模型,他允许用户为记录定义特定的规则。
代码语言:javascript复制# 列出所有的 Class
list classes
# 创建一个学生的类
CREATE CLASS Student
# 为学生类添加属性
CREATE PROPERTY Student.name STRING
# 为学生类添加属性
CREATE PROPERTY Student.birthDate DATE
# 创建属性时添加相应约束
CREATE PROPERTY student.sexuality STRING ( REGEXP "[M|F]")
# 为属性添加规则(最短)
ALTER PROPERTY Student.name MIN 3
# 为属性添加规则 (强制)
ALTER PROPERTY Student.name MANDATORY true
# 为属性添加多跳规则
CREATE PROPERTY Student.name STRING (MANDATORY TRUE, MIN 5, MAX 25)
# 设置属性的类型为一个嵌入式字符串列表
CREATE PROPERTY Profile.tags EMBEDDEDLIST STRING
# 添加一个属性 friends ,用于存放 当前 profile 对象对其他 profile 对象的映射(Profile 也是一个类)
CREATE PROPERTY Profile.friends EMBEDDEDMAP Profile
# 修改属性名,将 age 修改为 born
ALTER PROPERTY Account.age NAME "born"
# 将某属性更改为强制填写
ALTER PROPERTY Account.age MANDATORY TRUE
# 为某属性设置正则表达式限制
ALTER PROPERTY Account.gender REGEXP "[M|F]"
# 为属性设置默认值
ALTER PROPERTY Client.created DEFAULT "sysdate()"
# 删除属性
DROP PROPERTY User.name
# 移除类中所有记录
TRUNCATE CLASS Profile
# 删除类
DROP CLASS Account
# 展示学生类类信息
INFO CLASS Student
# 展示类的所有数据
BROWSE CLASS Student
Clsaaes 支持的类型
- 布尔类型:
BOOLEAN
- 整数类型:
INTEGER
、SHORT
、LONG
- 浮点数类型:
DOUBLE
、FLOAT
、DECIMAL
- 字符串类型:
STRING
- 时间类型:
DATE
、DATETIME
- 字节类型:
BINARY
、BYTE
- 嵌入与链接类型:
EMBEDDED
、LINK
、LINKBAG
- 嵌入式集合类型:
EMBEDDEDLIST
、EMBEDDEDSET
、EMBEDDEDMAP
- 链式集合类型:
LINKLIST
、LINKSET
、LINKMAP
Ps: Embedded 类型的记录会保存在记录本身,并没有 RecordID Link 是指向其他类型的链接
有关类型的介绍可以参考:https://www.w3cschool.cn/orientdb/orientdb_data_types.html
Cluster 操作
代码语言:javascript复制# 往一个类中添加一个 Cluster
ALTER CLASS Customer ADDCLUSTER UK_Customers
# 查看集合内的所有数据
BROWSE CLUSTER OUser
# 修改 Cluster 的名称
ALTER CLUSTER profile NAME "profile2"
# 根据 Cluster 的 id 修改 Cluster 的名称
ALTER CLUSTER 9 NAME "profile2"
# 修改 Cluster 的冲突策略
ALTER CLUSTER V CONFLICTSTRATEGY "automerge"
# 将 Cluster 的状态设置为离线
ALTER CLUSTER V_2012 STATUS "OFFLINE"
# 将 Emplyee 为开头的 Cluster 的状态全部设置为离线
ALTER CLUSTER employee* status "offline"
# 依据名称删除 Cluster
DROP CLUSTER Account
# 依据 Cluster-id 删除 Cluster
Drop Cluster 177
通用 CRUD 操作
插入数据
代码语言:javascript复制# 往 Profile 类中插入一条数据(SQL-92 规范)
INSERT INTO Profile (name, surname) VALUES ('Jay', 'Miner')
# 往 Profile 类中插入一条数据
INSERT INTO Profile SET name = 'Jay', surname = 'Miner'
# 往 Profile 类中插入一条数据(JSON 格式)
INSERT INTO Profile CONTENT {"name": "Jay", "surname": "Miner"}
# 将数据插入到 Profile 类的特定 Cluster 中(SQL-92 规范)
INSERT INTO Profile CLUSTER profile_recent (name, surname) VALUES ('Jay', 'Miner')
# 将数据插入到 Profile 类的特定 Cluster 中
INSERT INTO Profile CLUSTER profile_recent SET name = 'Jay', surname = 'Miner'
# 同时向 Profile 类中插入多条数据
INSERT INTO Profile(name, surname) VALUES ('Jay', 'Miner'),('Frank', 'Hermier'), ('Emily', 'Sout')
# 插入一条记录并添加一个关系(SQL-92 规范)
INSERT INTO Employee (name, boss) VALUES ('jack', #11:09)
# 插入一条记录并添加一个关系
INSERT INTO Employee SET name = 'jack', boss = #11:99
# 插入一条记录并添加多条关系(SQL-92 规范)
INSERT INTO Profile (name, friends) VALUES ('Luca', [#10:3, #10:4])
# 插入一条记录并添加多条关系
INSERT INTO Profiles SET name = 'Luca', friends = [#10:3, #10:4]
# 采用子查询进行数据插入
INSERT INTO Diver SET name = 'Luca', buddy = (SELECT FROM Diver WHERE name = 'Marko')
# 往 cluster 中插入一条数据
INSERT INTO CLUSTER:asiaemployee (name) VALUES ('Matthew')
# 往某类的其他 Cluster 中插入数据的其他写法
INSERT INTO CLUSTER:asiaemployee (@class, content) VALUES ('Employee', 'Matthew')
# 插入数据时还插入一个嵌入式文档
INSERT INTO Profile (name, address) VALUES ('Luca', { "@type": "d", "street": "Melrose Avenue", "@version": 0 })
# 从其他类中复制某些数据
INSERT INTO GermanyClient FROM SELECT FROM Client WHERE country = 'Germany'
# 当新类比旧类多出一个 bool 属性时,从旧类中复制数据到新类中
INSERT INTO GermanyClient FROM SELECT *, true AS copied FROM Client WHERE country = 'Germany'
查询数据
代码语言:javascript复制# 查出类中所有数据
SELECT FROM Person
# 按名称进行模糊查询
SELECT FROM Person WHERE name LIKE 'Luk%'
# 查询名称前三个为 Luk 的
SELECT FROM Person WHERE name.left(3) = 'Luk'
# 同上
SELECT FROM Person WHERE name.substring(0,3) = 'Luk'
# 获取 Profile 类中任一属性含有 danger 字段的所有记录
SELECT FROM Profile WHERE ANY() LIKE '�nger%'
# 输出 Profile 类的特定字段
SELECT nick, followings, followers FROM Profile
# 对需要的字段进行特殊处理后输出
SELECT name.toUppercase(), address.city.country.name FROM Profile
# 依据 rid 输出相关记录
SELECT FROM [#10:3, #10:4, #10:5]
# 查询后对结果进行排序
SELECT FROM Profile ORDER BY name DESC
# 依据 Account 类的 city 属性进行分组,并统计其中个数
SELECT SUM(*) FROM Account GROUP BY city
# 通过索引进行检索
select from index:ouser.name where key = 'admin'
# 从某一节点开始,在十层关系或链接对象之内,寻找带有 address.city 为 rome 的记录
# 或者说是从某一节点开始遍历。
SELECT FROM 11:4 WHERE ANY() TRAVERSE(0,10) (address.city = 'Rome')
# 返回记录,该纪录的三层连接里里面,含有属性 danger
SELECT FROM Profile WHERE ANY() TRAVERSE(0, 3) ( ANY().toUpperCase().indexOf('danger') > -1 )
修改数据
代码语言:javascript复制# 依据条件更改数据
UPDATE Profile SET nick = 'Luca' WHERE nick IS NULL
# 从所有记录中移除某字段
UPDATE Profile REMOVE nick
# 往集合中添加一个引用值(链接)
UPDATE Account ADD address=#12:0
# 移除集合中的一个引用值(链接)
UPDATE Account REMOVE address = #12:0
# 移除集合中的一个 String 类型的值
UPDATE Account REMOVE addresses = 'Foo'
# 按条件移除列表中的特定元素
UPDATE Account REMOVE addresses = addresses[city = 'Rome']
# 移除列表中特定位置元素
UPDATE Account REMOVE addresses = addresses[1]
# 将一个数据放入到一个 map 中
UPDATE Account PUT addresses = 'Luca', #12:0
# 移除 map 中的一个元素
UPDATE Account REMOVE addresses = 'Luca'
# 插入一个 嵌入式文档
UPDATE Account SET address={ "street": "Melrose Avenue", "city": { "name": "Beverly Hills" } }
# 更新 20 条满足条件的记录
UPDATE Profile SET nick = 'Luca' WHERE nick IS NULL LIMIT 20
删除数据
代码语言:javascript复制# 依据条件删除数据
DELETE FROM Profile WHERE surname.toLowerCase() = 'unknown'
图操作
创建顶点
代码语言:javascript复制# 创建一个顶点类 V1 并继承顶点基类 V
CREATE CLASS V1 EXTENDS V
# 创建一个 V1 类顶点
CREATE VERTEX V1
# 创建一个 V1 类顶点并为其指定特定 Cluster
CREATE VERTEX V1 CLUSTER recent
# 创建顶点并设置属性
CREATE VERTEX SET brand = 'fiat'
# 创建 V1 类顶点并设置属性
CREATE VERTEX V1 SET brand = 'fiat', name = 'wow'
# 使用 JSON 内容创建顶点
CREATE VERTEX Employee CONTENT { "name" : "Jay", "surname" : "Miner" }
删除顶点
代码语言:javascript复制# 依据 id 删除顶点
DELETE VERTEX #10:231
# 依据属性删除顶点
DELETE VERTEX EMailMessage WHERE isSpam = TRUE
# 依聚其他顶点的类来删除顶点
DELETE VERTEX Account WHERE in.@Class CONTAINS 'BadBehaviorInForum'
# 依据连续的两条边的类型进行查询
DELETE VERTEX Attachment WHERE in[@Class = 'HasAttachment'].date
<= "1990" AND in.out[@Class = "Email"].from = 'some...@example.com'
# 一次删除 1000 条数据
DELETE VERTEX v BATCH 1000
创建边
代码语言:javascript复制# 创建一条普通的边
CREATE EDGE FROM #10:3 TO #11:4
# 创建一个新的边类 E1 并继承边的基类
CREATE CLASS E1 EXTENDS E
# 创建一条 E1 边的类
CREATE EDGE E1 FROM #10:3 TO #11:4
# 往指定的 Cluster 中插入一条边
CREATE EDGE E1 CLUSTER EuropeEdges FROM #10:3 TO #11:4
# 创建边,并且为边设置属性
CREATE EDGE FROM #10:3 TO #11:4 SET brand = 'fiat'
# 创建边并设置多个属性
CREATE EDGE E1 FROM #10:3 TO #11:4 SET brand = 'fiat', name = 'wow'
# 根据条件创建边
CREATE EDGE Watched FROM (SELECT FROM account WHERE name = 'Luca') TO
(SELECT FROM movies WHERE type.name = 'action')
# 使用 JSON 格式为边插入数据
CREATE EDGE E FROM #22:33 TO #22:55 CONTENT { "name": "Jay",
"surname": "Miner" }
删除边
代码语言:javascript复制# 依据 rid 删除边
DELETE EDGE #22:38482
# 依据多个 rid 删除边
DELETE EDGE [#22:38482,#23:232,#33:2332]
# 依据起点终点和条件删除边
DELETE EDGE FROM #11:101 TO #11:117 WHERE date >= "2012-01-15"
# 依据类型和属性删除边
DELETE EDGE FROM #11:101 TO #11:117 WHERE @class = 'Owns' AND comment
LIKE "regex of forbidden words"
# 依据类型和属性删除边
DELETE EDGE Owns WHERE date < "2011-11"
# 批量删除一千条数据
DELETE EDGE Owns WHERE date < "2011-11" BATCH 1000
# 删除所有的基类 E 的边
DELETE EDGE E WHERE @rid IN (SELECT @rid FROM E)
遍历语句
代码语言:javascript复制# 从根节点遍历所有的字段
TRAVERSE * FROM #10:1234
# 从根节点开始遍历,指定深度和边的类型,并指定采用广度优先策略
TRAVERSE out("Friend") FROM #10:1234 MAXDEPTH 3 STRATEGY BREADTH_FIRST
# 对遍历的深度进行筛选输出
SELECT FROM (TRAVERSE out("Friend") FROM #10:1234 MAXDEPTH 3) WHERE $depth >= 1
# 对遍历的结果进行筛选输出
SELECT FROM (TRAVERSE out("Friend") FROM #10:1234 MAXDEPTH 3) WHERE city = 'Rome'
# 以满足要求的部分节点为起点进行遍历,并筛选输出相关的类
SELECT FROM (TRAVERSE out("Actors"), out("Movies") FROM (SELECT FROM
Movie WHERE producer = "J.J. Abrams") MAXDEPTH 3) WHERE
@class = 'Movie'
# 展示遍历的步骤
SELECT $path FROM ( TRAVERSE out() FROM V MAXDEPTH 10 )
# 两步 follow 遍历
SELECT FROM (TRAVERSE out('follow') FROM TwitterAccounts MAXDEPTH 2 )
WHERE $depth = 2
# 两步 follow 遍历
SELECT out('follow').out('follow') FROM TwitterAccounts