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 服务器,我们有托管的 Dolt。如果您正在寻找 Dolt 的 Postgres 版本,我们构建了 DoltgreSQL。请注意,这还处于早期 Alpha 阶段。Dolt 已准备好用于生产环境。

加入我们的 Discord 说声你好并提问,或查看我们的路线图以了解我们接下来要构建的内容。

视频介绍

Dolt 是用于什么的呢?

很多用途!Dolt 是一个通用的工具,具有无数的应用场景。但如果你想要一些想法,以下是人们迄今为止如何使用它的方式。

Dolt 可以被设置为现有 MySQL 或 MariaDB 数据库的副本,使用标准的 MySQL binlog 复制。每次写操作都成为 Dolt 提交。这是一种获得 Dolt 版本控制好处并保持现有 MySQL 或 MariaDB 数据库的好方法。

Dolt CLI

dolt CLI 具有与 git 相同的命令,还有一些额外的命令。

  1. $ dolt
  2. dolt 的有效命令包括
  3. init - 创建一个空的 Dolt 数据存储库。
  4. status - 显示工作树状态。
  5. add - 将表更改添加到已暂存表更改的列表中。
  6. diff - 比较表。
  7. reset - 从已暂存表更改的列表中删除表更改。
  8. clean - 从工作集中删除未跟踪的表。
  9. commit - 记录对存储库的更改。
  10. sql - 对存储库中的表运行 SQL 查询。
  11. sql-server - 启动一个兼容 MySQL 的服务器。
  12. sql-client - 启动内置的 MySQL 客户端。
  13. log - 显示提交日志。
  14. branch - 创建、列出、编辑、删除分支。
  15. checkout - 检出分支或从 HEAD 覆盖表。
  16. merge - 合并分支。
  17. conflicts - 用于查看和解决合并冲突的命令。
  18. cherry-pick - 应用由现有提交引入的更改。
  19. revert - 撤销提交中引入的更改。
  20. clone - 从远程数据存储库克隆。
  21. fetch - 从远程数据存储库更新数据库。
  22. pull - dolt 远程数据存储库获取并合并。
  23. push - 推送到 dolt 远程。
  24. config - Dolt 配置。
  25. remote - 管理一组已跟踪的存储库。
  26. backup - 管理一组服务器备份。
  27. login - 登录到 dolt 远程主机。
  28. creds - 用于管理凭据的命令。
  29. ls - 列出工作集中的表。
  30. schema - 用于显示和导入表模式的命令。
  31. table - 用于复制、重命名、删除和导出表的命令。
  32. tag - 创建、列出、删除标签。
  33. blame - 显示表的每行最后一次修改的修订和作者。
  34. constraints - 用于处理约束的命令。
  35. migrate - 执行数据库迁移以使用最新的 Dolt 数据格式。
  36. read-tables - 在新的 dolt 存储库中获取特定提交的表格。
  37. gc - 从存储库中清理未引用的数据。
  38. filter-branch - 使用提供的查询编辑提交历史。
  39. merge-base - 查找两个提交的共同祖先。
  40. version - 显示当前 Dolt CLI 版本。
  41. dump - 将工作集中的所有表导出到文件中。

安装

Dolt 是一个约 103 兆字节的单个程序。

  1. dolt $ du -h /Users/timsehn/go/bin/dolt
  2. 103M /Users/timsehn/go/bin/dolt

安装非常简单。下载并将其放在 PATH 中。我们有很多方法让这对大多数平台更加简便。

从最新版本下载

要在 Linux 或基于 Mac 的系统上安装,请在终端中运行以下命令:

  1. 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 权限或不愿意以它们运行脚本,您可以从最新版本下载适用于您平台的 dolt 二进制文件,解压缩它,然后将二进制文件放在 $PATH 的某个位置。

Linux

Arch Linux Dolt 已打包到 Arch Linux 的官方存储库中。

  1. pacman -S dolt

Mac

Homebrew Dolt 在 Homebrew 上有,每次发布都会更新。

  1. brew install dolt

MacPorts 在 macOS 上,也可以通过 MacPorts 提供的社区管理端口进行安装:

  1. sudo port install dolt

Windows

在 releases 中下载最新的 Microsoft Installer (.msi 文件) 并运行它。

有关在 Windows 上运行的信息,请参见这里。

Chocolatey

您可以使用 Chocolatey 安装 dolt:

  1. choco install dolt

Docker

有以下官方 Docker 镜像可供使用:

  • dolthub/dolt 用于将 Dolt 作为 CLI 工具运行。
  • dolthub/dolt-sql-server 用于以服务器模式运行 Dolt。

从源代码构建

确保已安装 Go,并且 go 已在您的路径中。

克隆此存储库并切换到 go 目录。然后运行:

  1. go install ./cmd/dolt

输出将位于 $GOPATH/bin,其默认值为 ~/go/bin。要测试构建,请尝试:

  1. ~/go/bin/dolt version

配置

通过在终端中运行 dolt 来验证您的安装是否成功。

  1. $ dolt
  2. dolt 的有效命令包括
  3. [...]

使用您的用户名和电子邮件配置 dolt,您将需要这些信息来创建提交。这些命令与 git 完全相同。

  1. $ dolt config --global --add user.email YOU@DOMAIN.COM
  2. $ dolt config --global --add user.name "YOUR NAME"

入门

导航到您希望存储数据的目录

Dolt 需要一个地方来存储您的数据库。我将把我的数据库放在 ~/dolt。

  1. % cd ~
  2. % mkdir dolt
  3. % cd dolt

您创建的任何数据库都将存储在此目录中。因此,例如,一旦运行 create database getting_started,将在此目录下创建一个名为 getting_started 的目录。导航到 ~/dolt/getting_started 将允许您使用 Dolt 命令行访问此数据库。

注意:在本示例中,getting_started 目录将在您在 Create a schema 部分的 SQL shell 中运行 create database getting_started; 后创建。在此之前只需创建目录并导航到该目录即可。

启动一个与 MySQL 兼容的数据库服务器

Dolt 随附了一个内置的 MySQL 兼容数据库服务器。要启动它,您可以使用 dolt sql-server 命令。运行此命令将在端口 3306 上启动服务器。

  1. dolt sql-server
  2. Starting server with Config HP="localhost:3306"|T="28800000"|R="false"|L="info"

您的终端将停在那里。这意味着服务器正在运行。任何错误都将在此终端中打印。只需将其保留在那里并打开一个新的终端。

使用任何 MySQL 客户端连接

在新的终端中,我们现在将使用客户端连接到运行的数据库服务器。Dolt 还附带了一个与 MySQL 兼容的客户端。

  1. % dolt -u root -p "" sql
  2. # Welcome to the Dolt MySQL client.
  3. # Statements must be terminated with ';'.
  4. # "exit" or "quit" (or Ctrl-D) to exit.
  5. mysql>

在您运行 dolt sql-server 的另一个终端中,您将看到以下日志行。

  1. 2022-06-06T13:14:32-07:00 INFO [conn 1] NewConnection {DisableClientMultiStatements=false}

您已连接成功!

在这里,我们也可以获取 MySQL 的副本,以便我们可以使用该客户端连接。转到 MySQL 入门文档,按照说明在您的计算机上安装 MySQL。我在我的 Mac 上使用 Homebrew 安装了 MySQL。

MySQL 附带了一个名为 mysqld 的 MySQL 服务器和一个名为 mysql 的 MySQL 客户端。您只关心客户端。按照 MySQL 文档的说明操作后,请确保在路径上有 mysql 客户端的副本:

  1. % mysql --version
  2. mysql Ver 8.0.29 for macos12.2 on x86_64 (Homebrew)

现在,要将 mysql 客户端连接到 Dolt,您将通过传递主机和端口来强制 MySQL 客户端通过 TCP 接口。默认情况下是套接字接口,Dolt 支持但仅在 localhost 上可用。因此,最好展示 TCP 接口。MySQL 客户端还要求您指定一个用户,此处为 root。

  1. % mysql --host 127.0.0.1 --port 3306 -uroot
  2. Welcome to the MySQL monitor. Commands end with ; or \g.
  3. Your MySQL connection id is 2
  4. Server version: 5.7.9-Vitess
  5. Copyright (c) 2000, 2022, Oracle and/or its affiliates.
  6. Oracle is a registered trademark of Oracle Corporation and/or its
  7. affiliates. Other names may be trademarks of their respective
  8. owners.
  9. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  10. mysql>

同样,为确保客户端实际连接,您应该在 dolt sql-server 终端中看到以下内容

  1. 2022-06-06T13:26:55-07:00 INFO [conn 2] NewConnection {DisableClientMultiStatements=false}

如您所见,Dolt 支持任何与 MySQL 兼容的客户端。Dolt 附带了一个客户端,但您可以使用任何 MySQL 客户端,例如 MySQL 提供的那个。

创建 schema

现在我们实际准备做一些有趣的事情。我将保持在 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> 模式。因此,CLI 上的 dolt add 变成了存储过程 dolt_add。传递选项也遵循命令行模型。例如,要指定要添加的表,请将表名作为选项发送到 dolt_add 存储过程。对于像将消息发送到 dolt_commit 命令这样的命名参数,请使用两个连续的参数,如 (‘-m’, ‘This is a message’)。如果您熟悉 Git,版本控制存储过程和系统表应该感觉很熟悉。

因此,我们像这样添加并提交我们的新模式。

  1. mysql> call dolt_add('teams', 'employees', 'employees_teams');
  2. +--------+
  3. | status |
  4. +--------+
  5. | 0 |
  6. +--------+
  7. 1 row in set (0.03 sec)
  8. mysql> call dolt_commit('-m', 'Created initial schema');
  9. +----------------------------------+
  10. | hash |
  11. +----------------------------------+
  12. | ne182jemgrlm8jnjmoubfqsstlfi1s98 |
  13. +----------------------------------+
  14. 1 row in set (0.02 sec)
  15. mysql> select * from dolt_log;
  16. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  17. | commit_hash | committer | email | date | message |
  18. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  19. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema |
  20. | vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | Initialize data repository |
  21. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  22. 2 rows in set (0.01 sec)

这样就完成了。您的模式已创建,并且在 dolt_log 系统表中可以看到 Dolt 提交跟踪了创建的记录。

请注意,Dolt 提交与标准的 SQL 事务 COMMIT 不同。在这种情况下,我正在运行启用了 AUTOCOMMIT 的数据库,因此每个 SQL 语句都会自动生成一个事务 COMMIT。如果您希望系统为每个事务生成 Dolt 提交,请使用系统变量 @@dolt_transaction_commit。

插入一些数据

现在,我将在 DoltHub 中的数据库中填充一些员工。然后,我将这些员工分配到两个团队:工程和销售。首席执行官在初创公司中担任多重角色,因此他将被分配到多个团队。

  1. mysql> insert into employees values
  2. (0, 'Sehn', 'Tim'),
  3. (1, 'Hendriks', 'Brian'),
  4. (2, 'Son','Aaron'),
  5. (3, 'Fitzgerald', 'Brian');
  6. Query OK, 4 rows affected (0.01 sec)
  7. mysql> select * from employees where first_name='Brian';
  8. +------+------------+------------+
  9. | id | last_name | first_name |
  10. +------+------------+------------+
  11. | 1 | Hendriks | Brian |
  12. | 3 | Fitzgerald | Brian |
  13. +------+------------+------------+
  14. 2 rows in set (0.00 sec)
  15. mysql> insert into teams values
  16. (0, 'Engineering'),
  17. (1, 'Sales');
  18. Query OK, 2 rows affected (0.00 sec)
  19. mysql> insert into employees_teams values
  20. (0,0),
  21. (1,0),
  22. (2,0),
  23. (0,1),
  24. (3,1);
  25. ERROR 1452 (HY000): cannot add or update a child row - Foreign key violation on fk: `rv9ek7ft`, table: `employees_teams`, referenced table: `teams`, key: `[2]`
  26. Oops,我违反了一个约束。看起来我在创建表 teams 之前创建了表 employees。您应该始终在插入时指定列,而不是依赖自然顺序。我的错!Dolt 具有现代 SQL 关系数据库的全部功能,以确保数据完整性。
  27. mysql> insert into employees_teams(employee_id, team_id) values
  28. (0,0),
  29. (1,0),
  30. (2,0),
  31. (0,1),
  32. (3,1);
  33. Query OK, 5 rows affected (0.01 sec)
  34. mysql> select first_name, last_name, team_name from employees
  35. join employees_teams on (employees.id=employees_teams.employee_id)
  36. join teams on (teams.id=employees_teams.team_id)
  37. where team_name='Engineering';
  38. +------------+-----------+-------------+
  39. | first_name | last_name | team_name |
  40. +------------+-----------+-------------+
  41. | Tim | Sehn | Engineering |
  42. | Brian | Hendriks | Engineering |
  43. | Aaron | Son | Engineering |
  44. +------------+-----------+-------------+
  45. 3 rows in set (0.00 sec)

看起来一切都插入并且正确。我能够使用那个三表 JOIN 列出工程团队的成员。Dolt 支持高达十二个表 JOIN。再次说明,Dolt 是一种现代 SQL 关系数据库,配备了 Git 风格的版本控制。

查看差异

现在,如果您想在提交之前查看工作集中发生了什么变化,您可以使用 doltstatus 和 dolt_diff 系统表。

  1. mysql>
  2. select * from dolt_status;
  3. +-----------------+--------+----------+
  4. | table_name | staged | status |
  5. +-----------------+--------+----------+
  6. | teams | 0 | modified |
  7. | employees | 0 | modified |
  8. | employees_teams | 0 | modified |
  9. +-----------------+--------+----------+
  10. 3 rows in set (0.01 sec)
  11. mysql> select * from dolt_diff_employees;
  12. +--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
  13. | 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 |
  14. +--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
  15. | Sehn | Tim | 0 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
  16. | Hendriks | Brian | 1 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
  17. | Son | Aaron | 2 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
  18. | Fitzgerald | Brian | 3 | WORKING | NULL | NULL | NULL | NULL | ne182jemgrlm8jnjmoubfqsstlfi1s98 | 2022-06-07 16:35:49.277 | added |
  19. +--------------+---------------+-------+-----------+----------------+----------------+-----------------+---------+----------------------------------+-------------------------+-----------+
  20. 4 rows in set (0.00 sec)

如您所见,从差异中我已将正确的值添加到了 employees 表中。这些值先前为 NULL,现在已经填充。

让我们以使用 -am 添加所有受影响的表的另一个 Dolt 提交结束。

  1. mysql> call dolt_commit('-am', 'Populated tables with data');
  2. +----------------------------------+
  3. | hash |
  4. +----------------------------------+
  5. | 13qfqa5rojq18j84d1n2htjkm6fletg4 |
  6. +----------------------------------+
  7. 1 row in set (0.02 sec)

您可以使用 dolt_log 检查日志,并使用未加范围的 dolt_diff 查看每个提交中哪些表发生了变化。未加范围的 dolt_diff 告诉您特定提交中该表的模式、数据或两者是否发生了变化。

  1. mysql> select * from dolt_log;
  2. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  3. | commit_hash | committer | email | date | message |
  4. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  5. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data |
  6. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema |
  7. | vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | Initialize data repository |
  8. +----------------------------------+-----------+-----------------+-------------------------+----------------------------+
  9. 3 rows in set (0.00 sec)
  10. mysql> select * from dolt_diff;
  11. +----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
  12. | commit_hash | table_name | committer | email | date | message | data_change | schema_change |
  13. +----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
  14. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data | 1 | 0 |
  15. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data | 1 | 0 |
  16. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data | 1 | 0 |
  17. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
  18. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
  19. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
  20. +----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
  21. 6 rows in set (0.00 sec)

哦,不!我犯了个错误。

Dolt 支持通过调用 dolt_reset() 撤销更改。让我们假设我意外地删除了一个表。

  1. mysql> drop table employees_teams;
  2. Query OK, 0 rows affected (0.01 sec)
  3. mysql> show tables;
  4. +---------------------------+
  5. | Tables_in_getting_started |
  6. +---------------------------+
  7. | employees |
  8. | teams |
  9. +---------------------------+
  10. 2 rows in set (0.00 sec)

在传统的数据库中,这可能是灾难性的。但在 Dolt 中,您距离恢复表只有一个命令之遥。

  1. mysql> call dolt_reset('--hard');
  2. +--------+
  3. | status |
  4. +--------+
  5. | 0 |
  6. +--------+
  7. 1 row in set (0.01 sec)
  8. mysql> show tables;
  9. +---------------------------+
  10. | Tables_in_getting_started |
  11. +---------------------------+
  12. | employees |
  13. | employees_teams |
  14. | teams |
  15. +---------------------------+
  16. 3 rows in set (0.01 sec)

Dolt 使操作数据库变得不太容易出错。您始终可以撤消您正在进行的更改或回退到已知的良好状态。您还可以使用 dolt_revert() 撤消特定的提交。即使您意外地在错误的数据库上运行了 drop database 命令,Dolt 也允许您通过调用 dolt_undrop() 存储过程进行撤销。

简介 - 图1

单击连接,您将看到一个熟悉的数据库工作台图形用户界面(GUI)。

简介 - 图2

在分支上进行更改,我使用 dolt_checkout() 存储过程。使用 -b 选项创建一个分支,就像在 Git 中一样。

Tableplus 提供了在 SQL 选项卡上输入多行 SQL 脚本的能力。我输入了以下 SQL 以检出一个分支,进行更新、插入、删除,并最终提交我的更改。

  1. call dolt_checkout('-b','modifications');
  2. update employees SET first_name='Timothy' where first_name='Tim';
  3. insert INTO employees (id, first_name, last_name) values (4,'Daylon', 'Wilkins');
  4. insert into employees_teams(team_id, employee_id) values (0,4);
  5. delete from employees_teams where employee_id=0 and team_id=1;
  6. call dolt_commit('-am', 'Modifications on a branch');

以下是在 Tableplus 中的结果。

简介 - 图3

在我的终端中,我无法看到在Tableplus中进行的修改,因为它们发生在与我当前会话中检出的不同分支上。

  1. mysql> select * from dolt_branches;
  2. +---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
  3. | name | hash | latest_committer | latest_committer_email | latest_commit_date | latest_commit_message |
  4. +---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
  5. | main | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data |
  6. | modifications | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | Modifications on a branch |
  7. +---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
  8. 2 rows in set (0.00 sec)
  9. mysql> select active_branch();
  10. +-----------------+
  11. | active_branch() |
  12. +-----------------+
  13. | main |
  14. +-----------------+
  15. 1 row in set (0.00 sec)
  16. mysql> select * from employees;
  17. +------+------------+------------+
  18. | id | last_name | first_name |
  19. +------+------------+------------+
  20. | 0 | Sehn | Tim |
  21. | 1 | Hendriks | Brian |
  22. | 2 | Son | Aaron |
  23. | 3 | Fitzgerald | Brian |
  24. +------+------------+------------+
  25. 4 rows in set (0.00 sec)

我可以使用 SQL 的 as of 语法查询任何我已检出的分支。

  1. mysql> select * from employees as of 'modifications';
  2. +------+------------+------------+
  3. | id | last_name | first_name |
  4. +------+------------+------------+
  5. | 0 | Sehn | Timothy |
  6. | 1 | Hendriks | Brian |
  7. | 2 | Son | Aaron |
  8. | 3 | Fitzgerald | Brian |
  9. | 4 | Wilkins | Daylon |
  10. +------+------------+------------+
  11. 5 rows in set (0.01 sec)

如果我想查看两个分支之间的差异,我可以使用 dolt_diff() 表函数。它接受两个分支和表名作为参数。

  1. mysql> select * from dolt_diff('main', 'modifications', 'employees');
  2. +--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
  3. | 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 |
  4. +--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
  5. | Sehn | Timothy | 0 | modifications | 2022-06-07 16:41:49.847 | Sehn | Tim | 0 | main | 2022-06-07 16:39:32.066 | modified |
  6. | Wilkins | Daylon | 4 | modifications | 2022-06-07 16:41:49.847 | NULL | NULL | NULL | main | 2022-06-07 16:39:32.066 | added |
  7. +--------------+---------------+-------+---------------+-------------------------+----------------+-----------------+---------+-------------+-------------------------+-----------+
  8. 2 rows in set (0.00 sec)

正如你所看到的,使用 Dolt,你可以在 SQL 数据库中获得 Git 风格的分支和差异的全部功能。

现在,让我们继续在另一个分支上进行模式更改。

  1. mysql> call dolt_checkout('-b', 'schema_changes');
  2. +--------+
  3. | status |
  4. +--------+
  5. | 0 |
  6. +--------+
  7. 1 row in set (0.01 sec)
  8. mysql> alter table employees add column start_date date;
  9. Query OK, 0 rows affected (0.02 sec)
  10. mysql> update employees set start_date='2018-09-08';
  11. Query OK, 4 rows affected (0.01 sec)
  12. Rows matched: 4 Changed: 4 Warnings: 0
  13. mysql> update employees set start_date='2021-04-19' where last_name='Fitzgerald';
  14. Query OK, 1 row affected (0.01 sec)
  15. Rows matched: 1 Changed: 1 Warnings: 0
  16. mysql> select * from employees;
  17. +------+------------+------------+------------+
  18. | id | last_name | first_name | start_date |
  19. +------+------------+------------+------------+
  20. | 0 | Sehn | Tim | 2018-09-08 |
  21. | 1 | Hendriks | Brian | 2018-09-08 |
  22. | 2 | Son | Aaron | 2018-09-08 |
  23. | 3 | Fitzgerald | Brian | 2021-04-19 |
  24. +------+------------+------------+------------+
  25. 4 rows in set (0.00 sec)
  26. mysql> call dolt_commit('-am', 'Added start_date column to employees');
  27. +----------------------------------+
  28. | hash |
  29. +----------------------------------+
  30. | pg3nfi0j1dpc5pf1rfgckpmlteaufdrt |
  31. +----------------------------------+
  32. 1 row in set (0.01 sec)

在分支上进行模式更改为你提供了一种进行新模式独立集成测试的新方法。

现在,让我们假设在 schema_changes 分支上进行的新模式测试和在 modifications 分支上进行的数据测试都已经顺利完成。是时候将所有的修改合并到 main 分支上了,这可以使用 dolt_merge 存储过程完成。

  1. mysql> call dolt_checkout('main');
  2. +--------+
  3. | status |
  4. +--------+
  5. | 0 |
  6. +--------+
  7. 1 row in set (0.01 sec)
  8. mysql> select * from dolt_status;
  9. Empty set (0.00 sec)
  10. mysql> call dolt_merge('schema_changes');
  11. +--------------+
  12. | no_conflicts |
  13. +--------------+
  14. | 1 |
  15. +--------------+
  16. 1 row in set (0.01 sec)
  17. mysql> select * from employees;
  18. +------+------------+------------+------------+
  19. | id | last_name | first_name | start_date |
  20. +------+------------+------------+------------+
  21. | 0 | Sehn | Tim |
  22. 2018-09-08 |
  23. | 1 | Hendriks | Brian | 2018-09-08 |
  24. | 2 | Son | Aaron | 2018-09-08 |
  25. | 3 | Fitzgerald | Brian | 2021-04-19 |
  26. +------+------------+------------+------------+
  27. 4 rows in set (0.00 sec)

模式更改成功。现在我们有了起始日期。接下来是数据更改。

  1. mysql> call dolt_merge('modifications');
  2. +--------------+
  3. | no_conflicts |
  4. +--------------+
  5. | 1 |
  6. +--------------+
  7. 1 row in set (0.02 sec)
  8. mysql> select * from employees;
  9. +------+------------+------------+------------+
  10. | id | last_name | first_name | start_date |
  11. +------+------------+------------+------------+
  12. | 0 | Sehn | Timothy | 2018-09-08 |
  13. | 1 | Hendriks | Brian | 2018-09-08 |
  14. | 2 | Son | Aaron | 2018-09-08 |
  15. | 3 | Fitzgerald | Brian | 2021-04-19 |
  16. | 4 | Wilkins | Daylon | NULL |
  17. +------+------------+------------+------------+
  18. 5 rows in set (0.00 sec)

数据更改也成功了。正如你所看到的,现在我的名字是 “Timothy” 而不是 “Tim”,Daylon 被添加了,我们都有了起始日期,除了 Daylon,他是在不同的分支上添加的。

  1. mysql> select first_name, last_name, team_name from employees
  2. join employees_teams on (employees.id=employees_teams.employee_id)
  3. join teams on (teams.id=employees_teams.team_id)
  4. where team_name='Sales';
  5. +------------+------------+-----------+
  6. | first_name | last_name | team_name |
  7. +------------+------------+-----------+
  8. | Brian | Fitzgerald | Sales |
  9. +------------+------------+-----------+
  10. 1 row in set (0.01 sec)

我也从销售团队中消失了。工程是生活。

我必须提交所有的更改,因为最后一次合并不是快进合并。

  1. mysql> call dolt_commit('-m', 'Merged all branches');
  2. +----------------------------------+
  3. | hash |
  4. +----------------------------------+
  5. | vn9b0qcematsj2f6ka0hfoflhr5s6p0b |
  6. +----------------------------------+
  7. 1 row in set (0.01 sec)
  8. mysql> select * from dolt_log;
  9. +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+
  10. | commit_hash | committer | email | date | message |
  11. +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+
  12. | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim Sehn | tim@dolthub.com | 2022-06-07 17:10:02.07 | Merged all branches |
  13. | pg3nfi0j1dpc5pf1rfgckpmlteaufdrt | Tim Sehn | tim@dolthub.com | 2022-06-07 16:44:37.513 | Added start_date column to employees |
  14. | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | Modifications on a branch |
  15. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data |
  16. | ne182jemgrlm8jnjmoubfqsstlfi1s98 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema |
  17. | vluuhvd0bn59598utedt77ed9q5okbcb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:33:59.531 | Initialize data repository |
  18. +----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+
  19. 6 rows in set (0.00 sec)

现在,我们有一个合并了所有模式和数据更改的数据库,可以随时使用。

审计单元系谱

哪个提交更改了我的名字?使用Dolt,您可以追溯数据库中每个单元的系谱。让我们使用dolt_history_<tablename>dolt_diff_<tablename>来探索Dolt中的系谱功能。

dolt_history_<tablename>显示了每个提交时行的状态。

  1. select * from dolt_history_employees where id=0 order by commit_date;
  2. +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+
  3. | id | last_name | first_name | start_date | commit_hash | committer | commit_date |
  4. +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+
  5. | 0 | Sehn | Tim | NULL | 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | 2022-06-07 16:39:32.066 |
  6. | 0 | Sehn | Timothy | NULL | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | 2022-06-07 16:41:49.847 |
  7. | 0 | Sehn | Tim | 2018-09-08 | pg3nfi0j1dpc5pf1rfgckpmlteaufdrt | Tim Sehn | 2022-06-07 16:44:37.513 |
  8. | 0 | Sehn | Timothy | 2018-09-08 | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim Sehn | 2022-06-07 17:10:02.07 |
  9. +------+-----------+------------+------------+----------------------------------+-----------+-------------------------+
  10. 4 rows in set (0.00 sec)

dolt_diff_<tablename>允许您将历史记录筛选为仅包括涉及到特定单元更改的提交。在这种情况下,我对更改我的名字很感兴趣。请注意,有两个更改我的名字的提交,因为一个是最初的更改,另一个是合并提交。

  1. select to_commit, from_first_name, to_first_name from dolt_diff_employees
  2. where (from_id=0 or to_id=0) and (from_first_name <> to_first_name or from_first_name is NULL)
  3. order by to_commit_date;
  4. +----------------------------------+-----------------+---------------+
  5. | to_commit | from_first_name | to_first_name |
  6. +----------------------------------+-----------------+---------------+
  7. | 13qfqa5rojq18j84d1n2htjkm6fletg4 | NULL | Tim |
  8. | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim | Timothy |
  9. | vn9b0qcematsj2f6ka0hfoflhr5s6p0b | Tim | Timothy |
  10. +----------------------------------+-----------------+---------------+
  11. 3 rows in set (0.01 sec)

Dolt 提供了强大的数据审计功能,可追溯到单个单元。每个数据库单元在何时、如何以及为何发生更改?

额外阅读

在您对 Dolt 有了一定了解后,请前往我们的文档。您还可以阅读我们在博客上的工作。