Dolt 是数据的 Git!
Dolt 是一个 SQL 数据库,你可以像 Git 仓库一样进行 fork、clone、branch、merge、push 和 pull。
连接 Dolt 就像连接任何 MySQL 数据库一样,可以读取或修改模式和数据。版本控制功能通过系统表、函数和存储过程在 SQL 中暴露。
或者,使用类似 Git 的命令行界面来导入 CSV 文件、提交更改、推送到远程或合并同事的更改。你熟悉的所有 Git 命令对 Dolt 也同样适用。
Git 版本控制文件。Dolt 版本控制表。它就像 Git 和 MySQL 的结合体。
我们还构建了 DoltHub,一个共享 Dolt 数据库的地方。我们免费托管公共数据。如果你想托管自己的 DoltHub 版本,我们有 DoltLab。 如果你希望我们为你运行 Dolt 服务器,我们提供 Hosted Dolt。 如果你正在寻找 Dolt 的 Postgres 版本,我们构建了 DoltgreSQL。警告,它还处于早期 Alpha 阶段。Dolt 已经可以用于生产环境。
加入我们的 Discord 打招呼和提问,或者 查看我们的路线图 了解我们接下来要构建的内容。
视频介绍
它有什么用?
很多用途! Dolt 是一个通用工具,有无数应用。但如果你想要一些想法,这里是人们目前如何使用它的。
Dolt 可以设置为现有 MySQL 或 MariaDB 数据库的副本, 使用标准的 MySQL binlog 复制。每次写入都会成为一个 Dolt 提交。这是一种获得 Dolt 版本控制好处并保留现有 MySQL 或 MariaDB 数据库的好方法。
Dolt CLI
dolt
CLI 具有与 git
相同的命令,还有一些额外的命令。
$ dolt
Dolt 的有效命令包括
init - 创建一个空的 Dolt 数据仓库。
status - 显示工作树状态。
add - 将表更改添加到暂存的表更改列表中。
diff - 比较表的差异。
reset - 从暂存的表更改列表中删除表更改。
clean - 从工作集中删除未跟踪的表。
commit - 记录对仓库的更改。
sql - 针对仓库中的表运行 SQL 查询。
sql-server - 启动兼容 MySQL 的服务器。
sql-client - 启动内置的 MySQL 客户端。
log - 显示提交日志。
branch - 创建、列出、编辑、删除分支。
checkout - 检出分支或从 HEAD 覆盖表。
merge - 合并分支。
conflicts - 用于查看和解决合并冲突的命令。
cherry-pick - 应用现有提交引入的更改。
revert - 撤消提交中引入的更改。
clone - 从远程数据仓库克隆。
fetch - 从远程数据仓库更新数据库。
pull - 从 dolt 远程数据仓库获取并合并。
push - 推送到 dolt 远程。
config - Dolt 配置。
remote - 管理跟踪的仓库集。
backup - 管理服务器备份集。
login - 登录到 dolt 远程主机。
creds - 用于管理凭证的命令。
ls - 列出工作集中的表。
schema - 用于显示和导入表模式的命令。
table - 用于复制、重命名、删除和导出表的命令。
tag - 创建、列出、删除标签。
blame - 显示修改表每行的最后修订版本和作者。
constraints - 用于处理约束的命令。
migrate - 执行数据库迁移以使用最新的 Dolt 数据格式。
read-tables - 将特定提交中的表获取到新的 dolt 仓库中
gc - 清理仓库中未引用的数据。
filter-branch - 使用提供的查询编辑提交历史。
merge-base - 查找两个提交的共同祖先。
version - 显示当前 Dolt cli 版本。
dump - 将工作集中的所有表导出到文件中。
安装
Dolt 是一个约 103 兆字节的单一程序。
dolt $ du -h /Users/timsehn/go/bin/dolt
103M /Users/timsehn/go/bin/dolt
安装非常简单。下载它并将其放在你的 PATH
中。
我们有多种方法可以让大多数平台更容易安装。
从最新版本
要在基于 Linux 或 Mac 的系统上安装,请在终端中运行以下命令:
sudo bash -c 'curl -L https://github.com/dolthub/dolt/releases/latest/download/install.sh | bash'
这将下载最新的 dolt
发布版并将其放在 /usr/local/bin/
中,这很可能在你的 $PATH
上。
安装脚本需要 sudo 权限才能将 dolt
放入 /usr/local/bin
。如果你没有 root
权限或不愿意使用 root 权限运行脚本,你可以从最新发布版下载适用于你平台的 dolt 二进制文件,
解压缩,并将二进制文件放在 $PATH
上的某个位置。
Linux
Arch Linux
Dolt 已被打包在 Arch Linux 的官方仓库中。
pacman -S dolt
Mac
Homebrew
Dolt 在 Homebrew 上,每次发布都会更新。
brew install dolt
MacPorts
在 macOS 上,Dolt 也可以通过 MacPorts 的社区管理端口安装:
sudo port install dolt
Windows
下载releases中最新的 Microsoft 安装程序(.msi
文件)并运行它。
有关在 Windows 上运行的信息,请参见此处。
Chocolatey
你可以使用 Chocolatey 安装 dolt
:
choco install dolt
Docker
Dolt 有以下官方 Docker 镜像:
dolthub/dolt
用于将 Dolt 作为 CLI 工具运行。dolthub/dolt-sql-server
用于在服务器模式下运行 Dolt。
从源代码
确保你已安装 Go,并且 go
在你的路径中。Dolt 依赖于 cgo,因此你还需要一个可用的 C 编译器和工具链。
克隆这个仓库并进入 go
目录。然后运行:
go install ./cmd/dolt
输出将在 $GOPATH/bin
中,默认为 ~/go/bin
。要测试你的构建,请尝试:
~/go/bin/dolt version
配置
通过在终端中运行 dolt
来验证你的安装是否成功。
$ dolt
Dolt 的有效命令包括
[...]
使用你的用户名和电子邮件配置 dolt
,你需要这些来创建提交。这些命令的工作方式与 git 完全相同。
$ dolt config --global --add user.email YOU@DOMAIN.COM
$ dolt config --global --add user.name "YOUR NAME"
入门
导航到你想存储数据的目录
Dolt 需要一个地方来存储你的数据库。我将把我的数据库放在 ~/dolt
中。
% cd ~
% mkdir dolt
% cd dolt
你创建的任何数据库都将存储在这个目录中。因此,对于这个例子,一旦你运行 create database getting_started
,这里将创建一个名为 getting_started
的目录。导航到 ~/dolt/getting_started
将允许你使用 Dolt 命令行访问这个数据库。
注意:对于这个例子,在创建模式部分的 SQL shell 中运行 create database getting_started;
之后,将创建 getting_started
目录。现在除了创建目录并导航到它之外,什么都不要做。
启动兼容 MySQL 的数据库服务器
Dolt 内置了兼容 MySQL 的数据库服务器。要启动它,你使用 dolt sql-server
命令。运行此命令会在端口 3306 上启动服务器。
dolt sql-server
Starting server with Config HP="localhost:3306"|T="28800000"|R="false"|L="info"
你的终端将停在那里。这意味着服务器正在运行。任何错误都将打印在这个终端中。就让它保持这样,然后打开一个新的终端。
使用任何 MySQL 客户端连接
在新的终端中,我们现在将使用客户端连接到正在运行的数据库服务器。Dolt 还附带了一个兼容 MySQL 的客户端。
% dolt -u root -p "" sql
# 欢迎使用 Dolt MySQL 客户端。
# 语句必须以 ';' 结尾。
# "exit" 或 "quit"(或 Ctrl-D)退出。
mysql>
在运行 dolt sql-server
的另一个终端中,你会看到以下日志行。
2022-06-06T13:14:32-07:00 INFO [conn 1] NewConnection {DisableClientMultiStatements=false}
你已连接!
当我们在这里时,让我们获取一份 MySQL 的副本,这样我们就可以使用该客户端进行连接。前往 MySQL 入门文档,在你的机器上安装 MySQL。我使用 Homebrew 在我的 Mac 上安装了 MySQL。
MySQL 带有一个名为 mysqld
的 MySQL 服务器和一个名为 mysql
的 MySQL 客户端。你只对客户端感兴趣。按照 MySQL 文档中的说明操作后,确保你的路径上有 mysql
客户端的副本:
% mysql --version
mysql Ver 8.0.29 for macos12.2 on x86_64 (Homebrew)
现在,要将 mysql
客户端连接到 Dolt,你将通过传入主机和端口来强制 MySQL 客户端通过 TCP 接口。默认是套接字接口,Dolt 支持它,但只在 localhost
上可用。因此,最好展示 TCP 接口。MySQL 客户端还要求你指定用户,在本例中为 root
。
% mysql --host 127.0.0.1 --port 3306 -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9-Vitess
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
再次确保客户端实际连接,你应该在 dolt sql-server
终端中看到以下内容
2022-06-06T13:26:55-07:00 INFO [conn 2] NewConnection {DisableClientMultiStatements=false}
如您所见,Dolt支持任何兼容MySQL的客户端。Dolt自带一个客户端,但您也可以使用任何MySQL客户端,比如MySQL自带的客户端。
创建架构
现在我们准备做一些有趣的事情了。我将继续使用mysql
客户端,执行以下SQL语句来创建一个名为getting_started
的数据库。getting_started
数据库将包含三个表:employees
、teams
和employees_teams
。
mysql> create database getting_started;
Query OK, 1 row affected (0.04 sec)
mysql> use getting_started;
Database changed
mysql> create table employees (
id int,
last_name varchar(255),
first_name varchar(255),
primary key(id));
Query OK, 0 rows affected (0.01 sec)
mysql> create table teams (
id int,
team_name varchar(255),
primary key(id));
Query OK, 0 rows affected (0.00 sec)
mysql> create table employees_teams(
team_id int,
employee_id int,
primary key(team_id, employee_id),
foreign key (team_id) references teams(id),
foreign key (employee_id) references employees(id));
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+---------------------------+
| Tables_in_getting_started |
+---------------------------+
| employees |
| employees_teams |
| teams |
+---------------------------+
3 rows in set (0.00 sec)
Dolt支持外键、二级索引、触发器、检查约束和存储过程。它是一个现代、功能丰富的SQL数据库。
创建Dolt提交
现在是时候使用您的第一个Dolt功能了。我们将创建一个Dolt 提交。Dolt提交允许您进行时间旅行和查看历史记录。当您想要恢复或比较某个时间点时,就可以创建一个Dolt提交。
Dolt通过Git风格的界面暴露版本控制功能。在命令行上,Dolt命令与Git完全对应,只是目标是表而不是文件。在SQL中,Dolt将版本控制读取操作暴露为系统表,将版本控制写入操作暴露为存储过程。
系统表和存储过程的命名遵循dolt_<command>
模式。因此,命令行上的dolt add
在存储过程中变成dolt_add
。传递选项也遵循命令行模型。例如,要指定要添加的表,将表名作为选项传递给dolt_add
过程。对于命名参数,比如向dolt_commit
命令发送消息,使用两个连续的参数,如('-m', 'This is a message')
。如果您熟悉Git,版本控制过程和系统表应该感觉很熟悉。
因此,我们像这样添加并提交我们的新架构。
mysql> call dolt_add('teams', 'employees', 'employees_teams');
+--------+
| status |
+--------+
| 0 |
+--------+
1 row in set (0.03 sec)
mysql> call dolt_commit('-m', 'Created initial schema');
+----------------------------------+
| hash |
+----------------------------------+
| ne182jemgrlm8jnjmoubfqsstlfi1s98 |
+----------------------------------+
1 row in set (0.02 sec)
mysql> select * from dolt_log;
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
| commit_hash | committer | email | date | message |
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema |
| vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | Initialize data repository |
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
2 rows in set (0.01 sec)
就是这样。您的架构已创建,并且您有一个Dolt提交跟踪创建过程,如dolt_log
系统表所示。
请注意,Dolt提交与标准SQL事务COMMIT
不同。在这种情况下,我运行数据库时启用了AUTOCOMMIT
,因此每个SQL语句都会自动生成一个事务COMMIT
。如果您希望系统为每个事务生成一个Dolt提交,请使用系统变量@@dolt_transaction_commit
。
插入一些数据
现在,我将在数据库中填充一些DoltHub的员工。然后,我将把员工分配到两个团队:工程和销售。在初创公司中,CEO需要承担多个角色,所以他将被分配到多个团队。
mysql> insert into employees values
(0, 'Sehn', 'Tim'),
(1, 'Hendriks', 'Brian'),
(2, 'Son','Aaron'),
(3, 'Fitzgerald', 'Brian');
Query OK, 4 rows affected (0.01 sec)
mysql> select * from employees where first_name='Brian';
+------+------------+------------+
| id | last_name | first_name |
+------+------------+------------+
| 1 | Hendriks | Brian |
| 3 | Fitzgerald | Brian |
+------+------------+------------+
2 rows in set (0.00 sec)
mysql> insert into teams values
(0, 'Engineering'),
(1, 'Sales');
Query OK, 2 rows affected (0.00 sec)
mysql> insert into employees_teams values
(0,0),
(1,0),
(2,0),
(0,1),
(3,1);
ERROR 1452 (HY000): cannot add or update a child row - Foreign key violation on fk: `rv9ek7ft`, table: `employees_teams`, referenced table: `teams`, key: `[2]`
哎呀,我违反了一个约束。看起来我在创建员工表之前创建了团队表。插入时应该始终指定列,而不是依赖自然顺序。这是我自作自受!Dolt具有现代SQL关系数据库的全部功能,以确保数据完整性。
mysql> insert into employees_teams(employee_id, team_id) values
(0,0),
(1,0),
(2,0),
(0,1),
(3,1);
Query OK, 5 rows affected (0.01 sec)
mysql> select first_name, last_name, team_name from employees
join employees_teams on (employees.id=employees_teams.employee_id)
join teams on (teams.id=employees_teams.team_id)
where team_name='Engineering';
+------------+-----------+-------------+
| first_name | last_name | team_name |
+------------+-----------+-------------+
| Tim | Sehn | Engineering |
| Brian | Hendriks | Engineering |
| Aaron | Son | Engineering |
+------------+-----------+-------------+
3 rows in set (0.00 sec)
看起来所有内容都已插入并且正确。我能够使用三表JOIN
列出工程团队的成员。Dolt支持最多十二个表的JOIN
。再次强调,Dolt是一个现代SQL关系数据库,配备了Git风格的版本控制。
检查差异
现在,如果您想在提交之前查看工作集中发生了什么变化,可以使用dolt_status
和dolt_diff_<tablename>
系统表。
mysql> select * from dolt_status;
+-----------------+--------+----------+
| table_name | staged | status |
+-----------------+--------+----------+
| teams | 0 | modified |
| employees | 0 | modified |
| employees_teams | 0 | modified |
+-----------------+--------+----------+
3 rows in set (0.01 sec)
mysql> select * from dolt_diff_employees;
+--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
| to_last_name | to_first_name | to_id | to_commit | to_commit_date | from_last_name | from_first_name | from_id | from_commit | from_commit_date | diff_type |
+--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
| Sehn | Tim | 0 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
| Hendriks | Brian | 1 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
| Son | Aaron | 2 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
| Fitzgerald | Brian | 3 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
+--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
4 rows in set (0.00 sec)
从差异中可以看出,我已经向employees
表添加了正确的值。这些值以前是NULL
,现在已经填充。
让我们用另一个Dolt提交来结束,这次使用-am
添加所有受影响的表。
mysql> call dolt_commit('-am', 'Populated tables with data');
+----------------------------------+
| hash |
+----------------------------------+
| 13qfqa5rojq18j84d1n2htjkm6fletg4 |
+----------------------------------+
1 row in set (0.02 sec)
您可以使用dolt_log
检查日志,并使用未限定的dolt_diff
查看每次提交中哪些表发生了变化。未限定的dolt_diff
会告诉您特定提交中表的架构、数据或两者是否发生了变化。
mysql> select * from dolt_log;
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
| commit_hash | committer | email | date | message |
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 使用数据填充表 |
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | 创建初始架构 |
| vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | 初始化数据存储库 |
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
3 行结果 (0.00 秒)
mysql> select * from dolt_diff;
+----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
| commit_hash | table_name | committer | email | date | message | data_change | schema_change |
+----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 使用数据填充表 | 1 | 0 |
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 使用数据填充表 | 1 | 0 |
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 使用数据填充表 | 1 | 0 |
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | 创建初始架构 | 0 | 1 |
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | 创建初始架构 | 0 | 1 |
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | 创建初始架构 | 0 | 1 |
+----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
6 行结果 (0.00 秒)
糟糕!我犯了个错误。
Dolt 支持通过 call dolt_reset()
撤销更改。让我们假设我不小心删除了一个表。
mysql> drop table employees_teams;
Query OK, 0 行受影响 (0.01 秒)
mysql> show tables;
+---------------------------+
| Tables_in_getting_started |
+---------------------------+
| employees |
| teams |
+---------------------------+
2 行结果 (0.00 秒)
在传统数据库中,这可能是灾难性的。在 Dolt 中,你只需一个命令就可以恢复表。
mysql> call dolt_reset('--hard');
+--------+
| status |
+--------+
| 0 |
+--------+
1 行结果 (0.01 秒)
mysql> show tables;
+---------------------------+
| Tables_in_getting_started |
+---------------------------+
| employees |
| employees_teams |
| teams |
+---------------------------+
3 行结果 (0.00 秒)
Dolt 使操作数据库不那么容易出错。你总是可以回退正在进行的更改或者回滚到已知的良好状态。你还可以使用 dolt_revert()
撤销特定的提交。即使你不小心在错误的数据库上运行了 drop database
,Dolt 也允许你通过调用 dolt_undrop()
存储过程 来撤销该操作。
在 SQL 工作台中查看数据
讨厌命令行?让我们使用 Tableplus 进行一些修改。Tableplus 是一个免费的 SQL 工作台。请按照他们网站上的安装说明进行操作。
现在,要连接必须选择 MySQL 作为连接类型。然后为你的连接输入一个名称,getting_started
作为你的数据库,root
作为你的用户。
点击连接,你将看到一个熟悉的数据库工作台 GUI。
在分支上进行更改
要在分支上进行更改,我使用 dolt_checkout()
存储过程。使用 -b
选项创建一个分支,就像在 Git 中一样。
Tableplus 让我可以在 SQL 标签页中输入多行 SQL 脚本。我输入了以下 SQL 来检出一个分支,更新,插入,删除,最后 Dolt 提交我的更改。
call dolt_checkout('-b','modifications');
update employees SET first_name='Timothy' where first_name='Tim';
insert INTO employees (id, first_name, last_name) values (4,'Daylon', 'Wilkins');
insert into employees_teams(team_id, employee_id) values (0,4);
delete from employees_teams where employee_id=0 and team_id=1;
call dolt_commit('-am', '在分支上进行修改');
这是 Tableplus 中的结果。
回到我的终端,我无法看到在 Tableplus 中进行的表修改,因为它们发生在与我在会话中检出的不同分支上。
mysql> select * from dolt_branches;
+---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
| name | hash | latest_committer | latest_committer_email | latest_commit_date | latest_commit_message |
+---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
| main | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 使用数据填充表 |
| modifications | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | 在分支上进行修改 |
+---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
2 行结果 (0.00 秒)
mysql> select active_branch();
+-----------------+
| active_branch() |
+-----------------+
| main |
+-----------------+
1 行结果 (0.00 秒)
mysql> select * from employees;
+------+------------+------------+
| id | last_name | first_name |
+------+------------+------------+
| 0 | Sehn | Tim |
| 1 | Hendriks | Brian |
| 2 | Son | Aaron |
| 3 | Fitzgerald | Brian |
+------+------------+------------+
4 行结果 (0.00 秒)
我可以使用 SQL as of
语法查询分支,无论我检出了什么。
mysql> select * from employees as of 'modifications';
+------+------------+------------+
| id | last_name | first_name |
+------+------------+------------+
| 0 | Sehn | Timothy |
| 1 | Hendriks | Brian |
| 2 | Son | Aaron |
| 3 | Fitzgerald | Brian |
| 4 | Wilkins | Daylon |
+------+------------+------------+
5 行结果 (0.01 秒)
如果我想查看两个分支之间的差异,我可以使用 dolt_diff()
表函数。它需要两个分支和表名作为参数。
mysql> select * from dolt_diff('main', 'modifications', 'employees');
+--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
| to_last_name | to_first_name | to_id | to_commit | to_commit_date | from_last_name | from_first_name | from_id | from_commit | from_commit_date | diff_type |
+--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
| Sehn | Timothy | 0 | modifications | 2022-06-07 16:41:49.847 | Sehn | Tim | 0 | main | 2022-06-07 16:39:32.066 | modified |
| Wilkins | Daylon | 4 | modifications | 2022-06-07 16:41:49.847 | NULL | NULL | NULL | main | 2022-06-07 16:39:32.066 | added |
+--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
2 行结果 (0.00 秒)
如你所见,使用 Dolt,你在 SQL 数据库中拥有 Git 风格分支和差异的全部功能。
在另一个分支上进行架构更改
我还可以在分支上进行架构更改,以便对新架构进行隔离测试。我将在一个新分支上添加一个 start_date
列并填充它。
mysql> call dolt_checkout('-b', 'schema_changes');
+--------+
| status |
+--------+
| 0 |
+--------+
1 行结果 (0.01 秒)
mysql> alter table employees add column start_date date;
Query OK, 0 行受影响 (0.02 秒)
mysql> update employees set start_date='2018-09-08';
Query OK, 4 行受影响 (0.01 秒)
匹配的行: 4 更改: 4 警告: 0
mysql> update employees set start_date='2021-04-19' where last_name='Fitzgerald';
Query OK, 1 行受影响 (0.01 秒)
匹配的行: 1 更改: 1 警告: 0
mysql> select * from employees;
+------+------------+------------+------------+
| id | last_name | first_name | start_date |
+------+------------+------------+------------+
| 0 | Sehn | Tim | 2018-09-08 |
| 1 | Hendriks | Brian | 2018-09-08 |
| 2 | Son | Aaron | 2018-09-08 |
| 3 | Fitzgerald | Brian | 2021-04-19 |
+------+------------+------------+------------+
4 rows in set (0.00 sec)
mysql> call dolt_commit('-am', '添加了start_date列到employees表');
+----------------------------------+
| hash |
+----------------------------------+
| pg3nfi0j1dpc5pf1rfgckpmlteaufdrt |
+----------------------------------+
1 row in set (0.01 sec)
在分支上更改架构为您提供了一种新方法来对新架构更改进行隔离集成测试。
## 将所有内容合并在一起
假设在`schema_changes`分支上对新架构的所有测试以及在`modifications`分支上的数据测试都完美无缺。现在是时候将我们所有的编辑合并到`main`分支上了。这是通过`dolt_merge`存储过程完成的。
mysql> call dolt_checkout('main'); +--------+ | status | +--------+ | 0 | +--------+ 1 row in set (0.01 sec)
mysql> select * from dolt_status; Empty set (0.00 sec)
mysql> call dolt_merge('schema_changes'); +--------------+ | no_conflicts | +--------------+ | 1 | +--------------+ 1 row in set (0.01 sec)
mysql> select * from employees; +------+------------+------------+------------+ | id | last_name | first_name | start_date | +------+------------+------------+------------+ | 0 | Sehn | Tim | 2018-09-08 | | 1 | Hendriks | Brian | 2018-09-08 | | 2 | Son | Aaron | 2018-09-08 | | 3 | Fitzgerald | Brian | 2021-04-19 | +------+------------+------------+------------+ 4 rows in set (0.00 sec)
架构更改成功。我们现在有了开始日期。接下来是数据更改。
mysql> call dolt_merge('modifications'); +--------------+ | no_conflicts | +--------------+ | 1 | +--------------+ 1 row in set (0.02 sec)
mysql> select * from employees; +------+------------+------------+------------+ | id | last_name | first_name | start_date | +------+------------+------------+------------+ | 0 | Sehn | Timothy | 2018-09-08 | | 1 | Hendriks | Brian | 2018-09-08 | | 2 | Son | Aaron | 2018-09-08 | | 3 | Fitzgerald | Brian | 2021-04-19 | | 4 | Wilkins | Daylon | NULL | +------+------------+------------+------------+ 5 rows in set (0.00 sec)
数据更改也成功了。如您所见,我现在是"Timothy"而不是"Tim",Daylon被添加了,我们都有开始日期,除了在不同分支上添加的Daylon。
mysql> select first_name, last_name, team_name from employees join employees_teams on (employees.id=employees_teams.employee_id) join teams on (teams.id=employees_teams.team_id) where team_name='Sales'; +------------+------------+-----------+ | first_name | last_name | team_name | +------------+------------+-----------+ | Brian | Fitzgerald | Sales | +------------+------------+-----------+ 1 row in set (0.01 sec)
我也从销售团队中消失了。工程就是生活。
我必须提交所有更改,因为最后的合并不是快进合并。
mysql> call dolt_commit('-m', '合并所有分支'); +----------------------------------+ | hash | +----------------------------------+ | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | +----------------------------------+ 1 row in set (0.01 sec)
mysql> select * from dolt_log; +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+ | commit_hash | committer | email | date | message | +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+ | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim Sehn | tim@dolthub.com | 2022-06-07 17:10:02.07 | 合并所有分支 | | pg3nfi0j1dpc5pf1rfgckpmlteaufdrt | Tim Sehn | tim@dolthub.com | 2022-06-07 16:44:37.513 | 添加了start_date列到employees表 | | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | 在分支上进行修改 | | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | 用数据填充表 | | ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | 创建初始架构 | | vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | 初始化数据仓库 | +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+ 6 rows in set (0.00 sec)
现在,我们有了一个包含所有架构和数据更改的数据库,已经合并好并准备使用。
## 审计单元格历史
哪个提交更改了我的名字?使用Dolt,您可以追踪数据库中每个单元格的历史。让我们使用`dolt_history_<表名>`和`dolt_diff_<表名>`来探索Dolt中的历史追踪功能。
`dolt_history_<表名>`显示每次提交时行的状态。
mysql> select * from dolt_history_employees where id=0 order by commit_date; +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+ | id | last_name | first_name | start_date | commit_hash | committer | commit_date | +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+ | 0 | Sehn | Tim | NULL | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | 2022-06-07 16:39:32.066 | | 0 | Sehn | Timothy | NULL | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | 2022-06-07 16:41:49.847 | | 0 | Sehn | Tim | 2018-09-08 | pg3nfi0j1dpc5pf1rfgckpmlteaufdrt | Tim Sehn | 2022-06-07 16:44:37.513 | | 0 | Sehn | Timothy | 2018-09-08 | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim Sehn | 2022-06-07 17:10:02.07 | +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+ 4 rows in set (0.00 sec)
`dolt_diff_<表名>`允许您将历史过滤到只包含相关单元格发生变化的提交。在这种情况下,我对更改我名字的提交感兴趣。注意,有两个提交更改了我的名字,因为一个是原始更改,另一个是合并提交。
mysql> select to_commit,from_first_name,to_first_name from dolt_diff_employees where (from_id=0 or to_id=0) and (from_first_name <> to_first_name or from_first_name is NULL) order by to_commit_date; +----------------------------------+-----------------+---------------+ | to_commit | from_first_name | to_first_name | +----------------------------------+-----------------+---------------+ | 13qfqa5rojq18j84d1n2htjkm6fletg4 | NULL | Tim | | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim | Timothy | | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim | Timothy | +----------------------------------+-----------------+---------------+ 3 rows in set (0.01 sec)
Dolt提供了强大的数据审计功能,可以追踪到单个单元格。您的数据库中的每个单元格在何时、如何以及为什么发生了变化?
# 更多阅读
现在您已经对Dolt有了感觉,请查看[我们的文档](https://docs.dolthub.com/introduction/what-is-dolt)。您还可以阅读[我们的博客](https://www.dolthub.com/blog/)了解我们一直在做什么。
# 安全政策
[Dolt的当前安全政策](https://github.com/dolthub/dolt/blob/main/SECURITY.md)在此存储库中维护。请遵循那里的披露说明。请不要最初在此存储库的公共GitHub问题中报告安全问题。
# 致谢和许可
Dolt在很大程度上依赖于[Noms](https://github.com/attic-labs/noms)项目的开源代码和想法。我们非常感谢Noms团队免费提供这些代码,如果没有它,我们就无法如此快速地构建Dolt。
Dolt根据Apache许可证2.0版获得许可。有关详细信息,请参阅[LICENSE](https://github.com/dolthub/dolt/blob/master/LICENSE)。