SurreAldB简介
#database #distributedsystems #rust #surrealdb

阅读有关SurrealDB Blog

的原始文章

什么是产品?

如果您正在阅读本文,您可能想知道如何从刚发现的这款出色的产品开始,SurseAldB。这是一个可以执行许多例程的数据库,因此您可以专注于对您重要的事情 - 处理数据。

在这篇博客文章中,我将描述如何设置和使用客户,同时解释SurreAldB背后的一些基本概念。

快速安装surseLDB

最初,我想使用Alpine Linux 1.13.1的新安装进行本教程。这很棘手,因为高山使用MUSL代替GNU LIBC结合。因此,本教程改用Ubuntu Desktop 22.04.01。哪个分布完全没有关系 - 我正在这样做是为了证明没有依赖性。

我们可以跟随instructions to install SurrealDB

curl -sSf https://install.surrealdb.com | sh

最后,我们可以启动服务器和客户端。我在tmux的顶部面板和底部面板中的客户端运行数据库。

Screenshot of tmux terminal where SurrealDB is launched in top panel and surreal REPL is in the bottom panel

使用该设置,我们准备好了!

名称空间和数据库

如果您像我一样,您首次使用数据库。

INSERT INTO person [{name:'Hugh'}, {name:'Rushmore'}];
[{"time":"7.608µs","status":"ERR","detail":"Specify a namespace to use"}]

我们尚未声明我们正在使用的名称空间和数据库。您可以通过包裹陈述来解决此问题。

USE NAMESPACE test; USE DATABASE testdb; INSERT INTO person [{name:'Hugh'}, {name:'Rushmore'}];
[{"time":"5.448µs","status":"OK","result":null},{"time":"1.855µs","status":"OK","result":null},{"time":"31.966464ms","status":"OK","result":[{"id":"person:7fsqx0q0iyeoltyjsr7c","name":"Hugh"},{"id":"person:2fdjz6j6luih4bn44u9c","name":"Rushmore"}]}]

但是,对于每个查询,这都是不便的。相反,我们将在指定数据库和名称空间时重新连接。

hugh@hugh-VirtualBox:~$ surreal sql --conn http://0.0.0.0:8000 -u root -p root --ns testns --db testdb
INSERT INTO person [{name:'Hugh'}, {name:'Rushmore'}];
[{"time":"109.351µs","status":"OK","result":[{"id":"person:adfy4qj5254b8l4po7bp","name":"Hugh"},{"id":"person:g5wkfgggpfayj6j453hg","name":"Rushmore"}]}]

更方便!

那么这些名称空间和数据库是什么?
用最简单的术语来说,它们是确保您没有得到名称碰撞的方法(这里谁的表有一个称为“请求”或“版本”的表?)。但实际上,这种分离还有更多。

在最高级别,我们有名称空间。名称空间是分开安全区域的一种方式。它们是使毯子访问一组数据库的一种方式。数据库将不会由2个名称空间共享,因此,将需要为他们无法访问的名称空间提供特殊访问权限的用户。这是多租户的基本概念。

因此,如果我们在名称空间的最高级别上进行此分离,那么拥有数据库的目的是什么?同样,这与独特性碰撞和安全性有关。您可以将数据库(存储,而不是称为surreal的DBMS系统)视为要执行名称唯一性的空间。因此,通过拥有单独的数据库,您可以避免这种唯一性,就像上面的示例一样,带有称为“请求”和“版本”的表。

这听起来可能不便,但目的是拥有一个SurreAldB群集。如果要开发新的应用程序或服务,请创建一个新的数据库(或名称空间,如果是针对新客户端或项目)。

表与文档

在上面的示例中,我们已经将2个条目插入了一个名为person的表中。我们可以通过做一个非常熟悉的选择查询来确认。

SELECT * FROM person;
[{"time":"1.151239ms","status":"OK","result":[{"id":"person:adfy4qj5254b8l4po7bp","name":"Hugh"},{"id":"person:g5wkfgggpfayj6j453hg","name":"Rushmore"}]}]

布里!我们可以看到“ ID”字段已填充,并且ID包括表名。但是,如果我们想使用可能与请求ID,旧系统,用户名或其他变量绑定的自定义ID?

INSERT INTO person {id: 'tobie', name: 'Tobie'};
[{"time":"90.142µs","status":"OK","result":[{"id":"person:tobie","name":"Tobie"}]}]
SELECT * FROM person;
[{"time":"63.091µs","status":"OK","result":[{"id":"person:adfy4qj5254b8l4po7bp","name":"Hugh"},{"id":"person:g5wkfgggpfayj6j453hg","name":"Rushmore"},{"id":"person:tobie","name":"Tobie"}]}]

图与链接

因此,我们创建了一个文件(人)(Hugh,Rushmore,Tobie)的表格。文档与关系表有何不同?

INSERT INTO person {name: 'complex', shoes: ['red', 'green', {colour: 'blue', favourite: true}]};
[{"time":"110.782µs","status":"OK","result":[{"id":"person:1vjjz8xi2pbau1zh07ob","name":"complex","shoes":["red","green",{"colour":"blue","favourite":true}]}]}]

好,非常不同!我们已经创建了一个名为“鞋子”的新专栏。该列包含此条目的数组。并不是数组的所有元素都是相同类型的!我们将“红色”和“绿色”作为shoes列的字符串元素,但随后是“蓝色”颜色的整个对象。这是如此不同,以至于将这些“列”称为有点伸展。这就是为什么我们不将文档中的条目称为列的原因,仅为记录。

SELECT id FROM person;
[{"time":"1.21102ms","status":"OK","result":[{"id":"person:1vjjz8xi2pbau1zh07ob"},{"id":"person:adfy4qj5254b8l4po7bp"},{"id":"person:g5wkfgggpfayj6j453hg"},{"id":"person:tobie"}]}]
SELECT shoes FROM person;
[{"time":"125.074µs","status":"OK","result":[{"shoes":["red","green",{"colour":"blue","favourite":true}]},{"shoes":null},{"shoes":null},{"shoes":null}]}]
SELECT shoes.colour FROM person;
[{"time":"89.063µs","status":"OK","result":[{"shoes":{"colour":[null,null,"blue"]}},{"shoes":{"colour":null}},{"shoes":{"colour":null}},{"shoes":{"colour":null}}]}]

您可能想知道结果中为什么有一个不寻常的[null,null,'blue'] - 这些是对象的3个值:id,faster和color。

我们可以使用这些嵌套记录来做一些很酷的事情。我们可以创建记录链接。记录链接是您如何在关系数据库中使用外国键来指向相同的桌子条目,甚至是其他桌子条目?与嵌套的文档记录不同,这些链接指向表格中可能不属于链接文档的条目。这意味着,如果宣布所有文档条目,所有文件都可以包括所有其他文档条目。而且它们不需要更新 - 它们是指数。您现在可以放下C ++书;您不需要知道使用它们;)。

UPDATE person:tobie SET friends=[person:g5wkfgggpfayj6j453hg, person:adfy4qj5254b8l4po7bp];
[{"time":"90.815µs","status":"OK","result":[{"friends":["person:g5wkfgggpfayj6j453hg","person:adfy4qj5254b8l4po7bp"],"id":"person:tobie","name":"Tobie"}]}]
SELECT friends.name FROM person:tobie;
[{"time":"185.621µs","status":"OK","result":[{"friends":{"name":["Rushmore","Hugh"]}}]}]

漂亮整洁。

这些图是吗?好吧,不完全。这些只是可复合的文档。我们在单向上而不是双向遍历。我们如何将文档链接在一起作为图表?

RELATE person:tobie->works_with->person:g5wkfgggpfayj6j453hg SET last_updated = time::now();
RELATE person:tobie->works_with->person:adfy4qj5254b8l4po7bp SET last_updated = time::now();
[{"time":"38.104611ms","status":"OK","result":[{"id":"works_with:fl9wgahk9pl4eqj33es7","in":"person:tobie","last_updated":"2023-02-06T18:33:41.131956605Z","out":"person:g5wkfgggpfayj6j453hg"}]},{"time":"88.334µs","status":"OK","result":[{"id":"works_with:zccalviq0oj6o36wylgy","in":"person:tobie","last_updated":"2023-02-06T18:33:41.156103917Z","out":"person:adfy4qj5254b8l4po7bp"}]}]
SELECT * FROM person WHERE ->works_with->person;
[{"time":"1.31216ms","status":"OK","result":[{"friends":["person:g5wkfgggpfayj6j453hg","person:adfy4qj5254b8l4po7bp"],"id":"person:tobie","name":"Tobie"}]}]

我们已经确定了Mega节点!

唤醒

在本教程中,我们已经安装了SursteLDB,启动了它,连接到它,创建了数据并解释了它如何拟合。希望现在您很愿意使用它,并且可以使用应用程序或数据集进行测试。