826 lines
39 KiB
Markdown
826 lines
39 KiB
Markdown
<!-- WEHUB_ZH_README -->
|
||
> [!NOTE]
|
||
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
|
||
> [English](./README.en.md) · [原始项目](https://github.com/dolthub/dolt) · [上游 README](https://github.com/dolthub/dolt/blob/HEAD/README.md)
|
||
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
|
||
|
||
<img height="100" src="./images/Dolt-Logo@3x.svg"/>
|
||
|
||
# Dolt 是数据的 Git!
|
||
|
||
Dolt 是一款 SQL 数据库,你可以像操作 Git 仓库一样对它进行 fork、clone、branch、merge、push 和 pull。
|
||
|
||
像连接任何 MySQL 数据库一样连接 Dolt,即可读取或修改 schema 和数据。版本控制功能通过 SQL 中的系统表、函数和存储过程暴露出来。
|
||
|
||
或者,使用类似 Git 的命令行界面导入 CSV 文件、提交更改、推送到远程,或合并队友的更改。你熟悉的所有 Git 命令在 Dolt 中用法完全相同。
|
||
|
||
Git 对文件进行版本控制。Dolt 对表进行版本控制。它就像 Git 和 MySQL 的结合体。
|
||
|
||
我们还构建了 [DoltHub](https://www.dolthub.com),,一个分享 Dolt 数据库的平台。我们免费托管公开数据。如果你想自行托管 DoltHub,我们有 [DoltLab](https://www.doltlab.com).。如果你想让我们为你运行 Dolt 服务器,我们有 [Hosted Dolt](https://hosted.doltdb.com).。
|
||
|
||
更喜欢 Postgres 而不是 MySQL?试试 [Doltgres](https://github.com/dolthub/doltgresql),,目前已进入 Beta 版本。
|
||
|
||
[加入我们的 Discord](https://discord.com/invite/RFwfYpu)打个招呼、提问,或[查看我们的路线图](https://dolthub.com/docs/other/roadmap),了解我们接下来要构建什么。
|
||
|
||
# 视频介绍
|
||
|
||
[](https://www.youtube.com/watch?v=H2iZy0Cme10)
|
||
|
||
# 它有什么用?
|
||
|
||
用途很多!Dolt 是一款通用工具,应用场景数不胜数。但如果你想找些灵感,[可以看看人们目前是如何使用它的](https://dolthub.com/blog/2024-10-15-dolt-use-cases/).。
|
||
|
||
Dolt 为 [Beads](https://github.com/gastownhall/beads) 和 [Gas Town](https://github.com/steveyegge/gastown). 提供支持。它是智能体记忆(agent memory)的最佳数据库,尤其是在你迈向多智能体、多机器工作流时。
|
||
|
||
# Dolt CLI
|
||
|
||
`dolt` CLI 拥有与 `git` 相同的命令,并附带一些额外功能。
|
||
|
||
```
|
||
$ dolt
|
||
Valid commands for dolt are
|
||
init - Create an empty Dolt data repository.
|
||
status - Show the working tree status.
|
||
add - Add table changes to the list of staged table changes.
|
||
diff - Diff a table.
|
||
reset - Remove table changes from the list of staged table changes.
|
||
clean - Remove untracked tables from working set.
|
||
commit - Record changes to the repository.
|
||
sql - Run a SQL query against tables in repository.
|
||
sql-server - Start a MySQL-compatible server.
|
||
log - Show commit logs.
|
||
branch - Create, list, edit, delete branches.
|
||
checkout - Checkout a branch or overwrite a table from HEAD.
|
||
merge - Merge a branch.
|
||
conflicts - Commands for viewing and resolving merge conflicts.
|
||
cherry-pick - Apply the changes introduced by an existing commit.
|
||
revert - Undo the changes introduced in a commit.
|
||
clone - Clone from a remote data repository.
|
||
fetch - Update the database from a remote data repository.
|
||
pull - Fetch from a dolt remote data repository and merge.
|
||
push - Push to a dolt remote.
|
||
config - Dolt configuration.
|
||
remote - Manage set of tracked repositories.
|
||
backup - Manage a set of server backups.
|
||
login - Login to a dolt remote host.
|
||
creds - Commands for managing credentials.
|
||
ls - List tables in the working set.
|
||
schema - Commands for showing and importing table schemas.
|
||
table - Commands for copying, renaming, deleting, and exporting tables.
|
||
tag - Create, list, delete tags.
|
||
blame - Show what revision and author last modified each row of a table.
|
||
constraints - Commands for handling constraints.
|
||
migrate - Executes a database migration to use the latest Dolt data format.
|
||
read-tables - Fetch table(s) at a specific commit into a new dolt repo
|
||
gc - Cleans up unreferenced data from the repository.
|
||
filter-branch - Edits the commit history using the provided query.
|
||
merge-base - Find the common ancestor of two commits.
|
||
version - Displays the current Dolt cli version.
|
||
dump - Export all tables in the working set into a file.
|
||
```
|
||
|
||
# 安装
|
||
|
||
Dolt 是一个约 103 MB 的单一程序。
|
||
|
||
```bash
|
||
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 权限运行脚本,可以从[最新版本](https://github.com/dolthub/dolt/releases),)下载适用于你平台的 dolt 二进制文件,解压后,将二进制文件放到 `$PATH` 上的某个位置。
|
||
|
||
### Linux
|
||
|
||
#### Arch Linux
|
||
|
||
Dolt 已收录在 Arch Linux 的官方软件仓库中。
|
||
|
||
```
|
||
pacman -S dolt
|
||
```
|
||
|
||
### Mac
|
||
|
||
#### Homebrew
|
||
|
||
Dolt 已上架 Homebrew,每个版本发布时都会更新。
|
||
|
||
```
|
||
brew install dolt
|
||
```
|
||
#### MacPorts
|
||
|
||
在 macOS 上,也可以通过 [MacPorts](https://www.macports.org):) 的[社区维护 port](https://ports.macports.org/port/dolt/)) 安装 Dolt。
|
||
|
||
```sh
|
||
sudo port install dolt
|
||
```
|
||
|
||
### Windows
|
||
|
||
在 [releases](https://github.com/dolthub/dolt/releases)) 中下载最新的 Microsoft Installer(`.msi` 文件)并运行。
|
||
|
||
有关在 Windows 上运行的信息,请参见[此处](https://dolthub.com/docs/introduction/installation/windows).。
|
||
|
||
#### Chocolatey
|
||
|
||
你可以使用 [Chocolatey](https://chocolatey.org/):) 安装 `dolt`。
|
||
|
||
```sh
|
||
choco install dolt
|
||
```
|
||
|
||
#### Docker
|
||
|
||
Dolt 提供以下官方 Docker 镜像:
|
||
|
||
* [`dolthub/dolt`](https://hub.docker.com/r/dolthub/dolt)):将 Dolt 作为 CLI 工具运行。
|
||
* [`dolthub/dolt-sql-server`](https://hub.docker.com/r/dolthub/dolt-sql-server)):以服务器模式运行 Dolt。
|
||
|
||
## 从源码构建
|
||
|
||
请确保已安装 Go,且 `go` 在你的 path 中。Dolt 依赖 [cgo](https://pkg.go.dev/cmd/cgo),),因此你还需要可用的 C 编译器和工具链。
|
||
|
||
克隆此仓库并进入 `go` 目录。然后运行:
|
||
|
||
```
|
||
go install ./cmd/dolt
|
||
```
|
||
|
||
输出将位于 `$GOPATH/bin`,默认值为 `~/go/bin`。要测试你的构建,请尝试:
|
||
|
||
```
|
||
~/go/bin/dolt version
|
||
```
|
||
|
||
# 配置
|
||
|
||
在终端中运行 `dolt`,验证安装是否成功。
|
||
|
||
```
|
||
$ dolt
|
||
Valid commands for dolt are
|
||
[...]
|
||
```
|
||
|
||
使用你的用户名和邮箱配置 `dolt`,创建提交时需要这些信息。命令用法与 git 完全相同。
|
||
|
||
```
|
||
$ dolt config --global --add user.email YOU@DOMAIN.COM
|
||
$ dolt config --global --add user.name "YOUR NAME"
|
||
```
|
||
|
||
# 入门
|
||
|
||
## 导航到你想存放数据的目录
|
||
|
||
Dolt 需要一个位置来存储你的数据库。我将把数据库放在 `~/dolt`。
|
||
|
||
```bash
|
||
% cd ~
|
||
% mkdir dolt
|
||
% cd dolt
|
||
```
|
||
|
||
你创建的任何数据库都会存储在此目录中。因此,在本示例中,运行 `create database getting_started` 后,将在此处创建一个名为 `getting_started` 的目录。进入 `~/dolt/getting_started` 后,即可使用 Dolt 命令行访问该数据库。
|
||
|
||
注意:在本示例中,`getting_started` 目录将在你在 [Create a schema section](#create-a-schema) 的 SQL shell 中运行 `create database getting_started;` 后创建。目前只需创建目录并进入即可,不要执行其他操作。
|
||
|
||
## 启动兼容 MySQL 的数据库服务器
|
||
|
||
Dolt 内置了一个与 MySQL 兼容的数据库服务器。要启动它,请使用命令 `dolt sql-server`。运行该命令后,服务器会在 3306 端口启动。
|
||
|
||
```bash
|
||
dolt sql-server
|
||
Starting server with Config HP="localhost:3306"|T="28800000"|R="false"|L="info"
|
||
```
|
||
|
||
此时终端会停在那里不动。这表示服务器正在运行。任何错误都会打印在这个终端中。让它保持运行,并打开一个新的终端。
|
||
|
||
## 使用 MySQL 客户端连接(最高支持 8.4 版本)
|
||
|
||
在新的终端中,我们将使用客户端连接到正在运行的数据库服务器。Dolt 也自带了一个与 MySQL 兼容的客户端。
|
||
|
||
```bash
|
||
% dolt -u root -p "" sql
|
||
# Welcome to the Dolt MySQL client.
|
||
# Statements must be terminated with ';'.
|
||
# "exit" or "quit" (or Ctrl-D) to exit.
|
||
mysql>
|
||
```
|
||
|
||
在运行 `dolt sql-server` 的另一个终端中,你会看到以下日志行。
|
||
|
||
```
|
||
2022-06-06T13:14:32-07:00 INFO [conn 1] NewConnection {DisableClientMultiStatements=false}
|
||
```
|
||
|
||
你已经连接成功!
|
||
|
||
趁这个机会,我们先安装一份 MySQL,以便使用该客户端进行连接。请前往 [MySQL Getting Started](https://dev.mysql.com/doc/mysql-getting-started/en/) 文档,在你的机器上安装 MySQL。我在 Mac 上使用 [Homebrew](https://brew.sh/) 安装 MySQL:`brew install mysql@8.4`。或者,你也可以通过运行 `brew install mysql-client@8.4` 仅安装客户端组件。
|
||
|
||
注意:请确保安装的是 MySQL 8.4 版本。MySQL 8.4 是当前长期支持(Long Term Support,LTS)版本,也就是说它是 MySQL 稳定且受支持的版本。MySQL 9.0 也可获得,但属于“创新”(innovation)版本,意味着它包含更多最新变更和功能,但可能不如 LTS 版本稳定。9.0 版本更改了认证支持,默认情况下无法连接到 Dolt SQL 服务器。你可以通过运行 `brew install mysql@8.4` 用 Homebrew 安装 MySQL 8.4。如果你确实想使用 MySQL 9.0,请阅读[我们关于如何为 `caching_sha2_password` 认证配置 Dolt 的文章](https://www.dolthub.com/blog/2024-12-11-mysql9-and-caching-sha2-auth-support/).
|
||
|
||
MySQL 附带一个名为 `mysqld` 的 MySQL 服务器和一个名为 `mysql` 的 MySQL 客户端。你只需关注客户端。按照 MySQL 文档中的说明操作后,请确保你的路径上有 `mysql` 客户端:
|
||
|
||
```bash
|
||
% mysql --version
|
||
mysql Ver 8.0.29 for macos12.2 on x86_64 (Homebrew)
|
||
```
|
||
|
||
现在,要将 `mysql` 客户端连接到 Dolt,你需要通过传入主机和端口,强制 MySQL 客户端走 TCP 接口。默认使用的是 socket 接口,Dolt 也支持该接口,但仅在 `localhost` 上可用。因此,更好的做法是演示 TCP 接口。MySQL 客户端还要求你指定用户,此处为 `root`。
|
||
|
||
```bash
|
||
% 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 自带的那个。
|
||
|
||
## 创建 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 commit
|
||
|
||
是时候使用你的第一个 Dolt 功能了。我们将创建一个 Dolt [commit](https://dolthub.com/docs/concepts/dolt/commits). Dolt commit 允许你进行时间旅行并查看血缘关系。每当你想恢复到这一时间点或与之进行比较时,就创建一个 Dolt commit。
|
||
|
||
Dolt 通过类似 Git 的界面暴露版本控制功能。在命令行中,Dolt 命令与对应的 Git 命令一一映射,只是目标对象从文件变成了表。在 SQL 中,Dolt 将版本控制的读操作暴露为[系统表](https://dolthub.com/docs/sql-reference/version-control/dolt-system-tables),将版本控制的写操作暴露为[存储过程](https://dolthub.com/docs/sql-reference/version-control/dolt-sql-procedures).
|
||
|
||
系统表和存储过程的命名遵循 `dolt_<command>` 模式。因此,CLI 中的 `dolt add` 会变成存储过程 `dolt_add`。传递选项也遵循命令行模型。例如,要指定要添加的表,请将表名作为选项传给 `dolt_add` 存储过程。对于命名参数,例如向 `dolt_commit` 命令发送消息,请按顺序使用两个参数,如 `('-m', 'This is a message')`。如果你熟悉 Git,这些版本控制存储过程和系统表应该会感觉很熟悉。
|
||
|
||
那么,我们像这样添加并提交新 schema。
|
||
|
||
```
|
||
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)
|
||
```
|
||
|
||
就是这样。你的 schema 已创建,并且有一个 Dolt commit 在跟踪这次创建,可以在 `dolt_log` 系统表中看到。
|
||
|
||
请注意,Dolt commit 不同于标准 SQL 事务 `COMMIT`。在本例中,我启用了 [`AUTOCOMMIT`](https://dev.mysql.com/doc/refman/5.6/en/innodb-autocommit-commit-rollback.html) 运行数据库,因此每条 SQL 语句都会自动生成事务 `COMMIT`。如果你希望系统为每个事务生成 Dolt commit,请使用系统变量 [`@@dolt_transaction_commit`](https://dolthub.com/docs/sql-reference/version-control/dolt-sysvars#dolt_transaction_commit).
|
||
|
||
## 插入一些数据
|
||
|
||
现在,我要向数据库中填入 DoltHub 的几位员工。然后,我会把这些员工分配到两个团队:工程(engineering)和销售(sales)。在初创公司里,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]`
|
||
```
|
||
|
||
哎呀,我违反了约束。看来我创建表时把 teams 放在 employees 前面了。插入时应该始终明确指定列,而不要依赖自然顺序。活该!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`s。再说一次,Dolt 是现代 SQL 关系型数据库,并配有 Git 风格的版本控制。
|
||
|
||
## 查看 diff
|
||
|
||
现在,如果你想在提交之前查看工作区里有哪些变更,可以使用 `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)
|
||
```
|
||
|
||
从 diff 可以看出,我已向 `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` 会告诉你该次提交中该表的 schema、data 或二者是否发生了变化。
|
||
|
||
```
|
||
mysql> select * from dolt_log;
|
||
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
|
||
| commit_hash | committer | email | date | message |
|
||
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
|
||
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data |
|
||
| 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 |
|
||
+----------------------------------+-----------+-----------------+-------------------------+----------------------------+
|
||
3 rows in set (0.00 sec)
|
||
|
||
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 | Populated tables with data | 1 | 0 |
|
||
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data | 1 | 0 |
|
||
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data | 1 | 0 |
|
||
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
|
||
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | employees_teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
|
||
| ne182jemgrlm8jnjmoubfqsstlfi1s98 | teams | Tim Sehn | tim@dolthub.com | 2022-06-07 16:35:49.277 | Created initial schema | 0 | 1 |
|
||
+----------------------------------+-----------------+-----------+-----------------+-------------------------+----------------------------+-------------+---------------+
|
||
6 rows in set (0.00 sec)
|
||
```
|
||
|
||
## 糟了!我犯了个错误。
|
||
|
||
Dolt 支持通过 `call dolt_reset()` 撤销变更。假设我不小心删了一张表。
|
||
|
||
```
|
||
mysql> drop table employees_teams;
|
||
Query OK, 0 rows affected (0.01 sec)
|
||
|
||
mysql> show tables;
|
||
+---------------------------+
|
||
| Tables_in_getting_started |
|
||
+---------------------------+
|
||
| employees |
|
||
| teams |
|
||
+---------------------------+
|
||
2 rows in set (0.00 sec)
|
||
```
|
||
|
||
在传统数据库中,这可能会带来灾难性后果。在 Dolt 中,你只需一条命令就能恢复表。
|
||
|
||
```
|
||
mysql> call dolt_reset('--hard');
|
||
+--------+
|
||
| status |
|
||
+--------+
|
||
| 0 |
|
||
+--------+
|
||
1 row in set (0.01 sec)
|
||
|
||
mysql> show tables;
|
||
+---------------------------+
|
||
| Tables_in_getting_started |
|
||
+---------------------------+
|
||
| employees |
|
||
| employees_teams |
|
||
| teams |
|
||
+---------------------------+
|
||
3 rows in set (0.01 sec)
|
||
```
|
||
|
||
Dolt 让数据库运维更少出错。你随时可以回滚进行中的更改,或回溯到已知的良好状态。你还可以使用 [`dolt_revert()`](https://dolthub.com/docs/sql-reference/version-control/dolt-sql-procedures#dolt_revert). 撤销特定提交。即使你意外在错误的数据库上运行了 `drop database`,Dolt 也允许你通过调用 [`dolt_undrop()` stored procedure](https://dolthub.com/docs/sql-reference/version-control/dolt-sql-procedures#dolt_undrop). 来撤销该操作。
|
||
|
||
|
||
## 在 SQL Workbench 中查看数据
|
||
|
||
讨厌命令行?让我们使用 [Tableplus](https://tableplus.com/) 进行一些修改。Tableplus 是一款免费的 SQL Workbench。请按照其官网的安装说明进行操作。
|
||
|
||
现在,要连接数据库,你必须选择 MySQL 作为连接类型。然后为连接输入一个名称,将 `getting_started` 作为数据库,将 `root` 作为用户。
|
||
|
||

|
||
|
||
点击连接后,你将看到一个熟悉的数据库 workbench GUI。
|
||
|
||

|
||
|
||
## 在分支上进行更改
|
||
|
||
要在分支上进行更改,我使用 `dolt_checkout()` 存储过程。使用 `-b` 选项会创建分支,就像在 Git 中一样。
|
||
|
||
Tableplus 让我可以在 SQL 选项卡中输入多行 SQL 脚本。我输入了以下 SQL,用于检出分支、更新、插入、删除,最后 Dolt commit 我的更改。
|
||
|
||
```SQL
|
||
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', 'Modifications on a branch');
|
||
```
|
||
|
||
以下是 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 | Populated tables with data |
|
||
| modifications | uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | Modifications on a branch |
|
||
+---------------+----------------------------------+------------------+------------------------+-------------------------+----------------------------+
|
||
2 rows in set (0.00 sec)
|
||
|
||
mysql> select active_branch();
|
||
+-----------------+
|
||
| active_branch() |
|
||
+-----------------+
|
||
| main |
|
||
+-----------------+
|
||
1 row in set (0.00 sec)
|
||
|
||
mysql> select * from employees;
|
||
+------+------------+------------+
|
||
| id | last_name | first_name |
|
||
+------+------------+------------+
|
||
| 0 | Sehn | Tim |
|
||
| 1 | Hendriks | Brian |
|
||
| 2 | Son | Aaron |
|
||
| 3 | Fitzgerald | Brian |
|
||
+------+------------+------------+
|
||
4 rows in set (0.00 sec)
|
||
```
|
||
|
||
无论当前检出的是哪个分支,我都可以使用 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 rows in set (0.01 sec)
|
||
```
|
||
|
||
如果我想查看两个分支之间的 diff,可以使用 `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 rows in set (0.00 sec)
|
||
```
|
||
|
||
如你所见,借助 Dolt,你可以在 SQL 数据库中获得 Git 风格分支和 diff 的全部能力。
|
||
|
||
## 在另一个分支上进行 schema 更改
|
||
|
||
我也可以在分支上进行 schema 更改,以便对新 schema 进行隔离测试。我将在新分支上添加 `start_date` 列并填充数据。
|
||
|
||
```
|
||
mysql> call dolt_checkout('-b', 'schema_changes');
|
||
+--------+
|
||
| status |
|
||
+--------+
|
||
| 0 |
|
||
+--------+
|
||
1 row in set (0.01 sec)
|
||
|
||
mysql> alter table employees add column start_date date;
|
||
Query OK, 0 rows affected (0.02 sec)
|
||
|
||
mysql> update employees set start_date='2018-09-08';
|
||
Query OK, 4 rows affected (0.01 sec)
|
||
Rows matched: 4 Changed: 4 Warnings: 0
|
||
|
||
mysql> update employees set start_date='2021-04-19' where last_name='Fitzgerald';
|
||
Query OK, 1 row affected (0.01 sec)
|
||
Rows matched: 1 Changed: 1 Warnings: 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', 'Added start_date column to employees');
|
||
+----------------------------------+
|
||
| hash |
|
||
+----------------------------------+
|
||
| pg3nfi0j1dpc5pf1rfgckpmlteaufdrt |
|
||
+----------------------------------+
|
||
1 row in set (0.01 sec)
|
||
```
|
||
|
||
在分支上更改 schema 为你提供了一种对新 schema 更改进行隔离集成测试的新方法。
|
||
|
||
## 全部合并
|
||
|
||
假设在 `schema_changes` 分支上对新 schema 的测试,以及在 `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)
|
||
```
|
||
|
||
Schema 变更成功。我们现在有了开始日期(start dates)。接下来进行数据变更。
|
||
|
||
```
|
||
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)
|
||
```
|
||
|
||
我也离开了 Sales Team。Engineering 才是王道。
|
||
|
||
我必须提交所有更改,因为上次合并不是快进(fast-forward)合并。
|
||
|
||
```
|
||
mysql> call dolt_commit('-m', 'Merged all branches');
|
||
+----------------------------------+
|
||
| 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 | Merged all branches |
|
||
| pg3nfi0j1dpc5pf1rfgckpmlteaufdrt | Tim Sehn | tim@dolthub.com | 2022-06-07 16:44:37.513 | Added start_date column to employees |
|
||
| uhkv57j4bp2v16vcnmev9lshgkqq8ppb | Tim Sehn | tim@dolthub.com | 2022-06-07 16:41:49.847 | Modifications on a branch |
|
||
| 13qfqa5rojq18j84d1n2htjkm6fletg4 | Tim Sehn | tim@dolthub.com | 2022-06-07 16:39:32.066 | Populated tables with data |
|
||
| 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 |
|
||
+----------------------------------+-----------+-----------------+-------------------------+--------------------------------------+
|
||
6 rows in set (0.00 sec)
|
||
```
|
||
|
||
现在,我们有了一个数据库,其中所有 schema 和数据变更都已合并,可以投入使用。
|
||
|
||
## 审计单元格血缘(Cell Lineage)
|
||
|
||
是哪个 commit 更改了我的名字?使用 Dolt,你可以追踪数据库中每个单元格的血缘。让我们使用 `dolt_history_<tablename>` 和 `dolt_diff_<tablename>` 来探索 Dolt 中的血缘功能。
|
||
|
||
`dolt_history_<tablename>` 会显示该行在每一个 commit 时的状态。
|
||
|
||
```
|
||
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_<tablename>` 允许你将历史记录筛选为仅显示目标单元格发生变更的 commit。在这种情况下,我关心的是更改我名字的 commit。注意,有两个 commit 更改了我的名字,其中一个是原始变更,另一个是 merge commit。
|
||
|
||
```
|
||
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://dolthub.com/docs/introduction/what-is-dolt)。你也可以在 [我们的博客](https://www.dolthub.com/blog/). 中了解我们一直在做什么。
|
||
|
||
# 安全策略
|
||
|
||
[Dolt 当前的安全策略](https://github.com/dolthub/dolt/blob/main/SECURITY.md) 维护在本仓库中。请按照其中的披露说明操作。请勿在本仓库的公开 GitHub Issues 中初次报告安全问题。
|
||
|
||
# 致谢与许可
|
||
|
||
Dolt 大量依赖来自
|
||
[Noms](https://github.com/attic-labs/noms) 项目的开源代码和理念。我们非常感谢 Noms 团队免费提供这些代码,
|
||
没有它们,我们无法如此快速地构建 Dolt。
|
||
|
||
Dolt 采用 Apache License, Version 2.0 许可。详见
|
||
[LICENSE](https://github.com/dolthub/dolt/blob/master/LICENSE)。
|