dolthub/dolt

GitHub: dolthub/dolt

Dolt 是一个兼容 MySQL 协议的 SQL 数据库,将 Git 的版本控制理念引入数据管理,支持对表结构和数据进行分支、合并、回滚等操作。

Stars: 20346 | Forks: 646

# 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://docs.dolthub.com/other/roadmap) 看看我们接下来在构建什么。 # 视频介绍 [![Dolt 解释视频](https://img.youtube.com/vi/H2iZy0Cme10/maxresdefault.jpg)](https://www.youtube.com/watch?v=H2iZy0Cme10) # 它是用来做什么的? 很多事情!Dolt 是一个具有无数 用途的通用工具。但如果你想要一些想法,[这里是人们目前如何使用 它的](https://dolthub.com/blog/2024-10-15-dolt-use-cases/)。 Dolt 可以使用标准的 MySQL binlog replication [设置为 你现有 MySQL 的副本](https://www.dolthub.com/blog/2023-02-17-binlog-replication-preview/)。 每次写入都会成为一个 Dolt commit。这是获得 Dolt 版本控制 好处并保留现有 MySQL 数据库的好方法。 # 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 兆字节的单个程序。 ``` 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 上,Dolt 也可以通过 [MacPorts](https://www.macports.org) 的[社区管理端口](https://ports.macports.org/port/dolt/)安装: ``` sudo port install dolt ``` ### Windows 下载 [releases](https://github.com/dolthub/dolt/releases) 中最新的 Microsoft 安装程序(`.msi` 文件)并运行 它。 有关在 Windows 上运行的信息,请参阅[此处](https://docs.dolthub.com/introduction/installation/windows)。 #### Chocolatey 你可以使用 [Chocolatey](https://chocolatey.org/) 安装 `dolt`: ``` 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` 位于你的路径中。Dolt 依赖于 [cgo](https://pkg.go.dev/cmd/cgo),因此你还需要一个可用的 C 编译器和工具链。 克隆此仓库并 cd 进入 `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` 中。 ``` % 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 上启动服务器。 ``` dolt sql-server Starting server with Config HP="localhost:3306"|T="28800000"|R="false"|L="info" ``` 你的终端会停在那里。这意味着服务器正在运行。任何错误都将打印在此终端中。只需将其留在那里并打开一个新终端。 ## 使用 MySQL 客户端连接(最高版本 8.4) 在新终端中,我们现在将使用客户端连接到正在运行的数据库服务器。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 Getting Started](https://dev.mysql.com/doc/mysql-getting-started/en/) 文档并在你的机器上安装 MySQL。我使用 [Homebrew](https://brew.sh/) 在我的 Mac 上安装 MySQL:`brew install mysql@8.4`。或者,你可以通过运行 `brew install mysql-client@8.4` 仅安装客户端组件。 注意:确保你安装的是 MySQL 8.4 版本。MySQL 8.4 是当前的长期支持 (LTS) 版本,这意味着这是 MySQL 的稳定且受支持的版本。MySQL 9.0 也可用,但是一个“创新”版本,这意味着它具有更多最新的更改和功能,但可能不如 LTS 版本稳定。9.0 版本更改了身份验证支持,默认情况下无法连接到 Dolt SQL server。你可以通过运行 `brew install mysql@8.4` 使用 Homebrew 安装 MySQL 8.4。如果你确实想使用 MySQL-9.0,请阅读[我们关于如何配置 Dolt 进行 `caching_sha2_password` 身份验证的文章](https://www.dolthub.com/blog/2024-12-11-mysql9-and-caching-sha2-auth-support/)。 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 接口。默认是 socket 接口,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 附带的客户端。 ## 创建 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 支持 foreign keys、secondary indexes、triggers、check constraints 和 stored procedures。它是一个现代的、功能丰富的 SQL 数据库。 ## 进行 Dolt commit 是时候使用你的第一个 Dolt 功能了。我们将进行一次 Dolt [commit](https://docs.dolthub.com/concepts/dolt/commits)。Dolt commit 允许你进行时间旅行并查看沿袭。每当你想要恢复或与此时此点进行比较时,都进行一次 Dolt commit。 Dolt 通过 Git 风格的接口暴露版本控制功能。在命令行上,Dolt 命令与其 Git 等效命令完全映射,只是目标是表而不是文件。在 SQL 中,Dolt 将版本控制读取操作作为 [system tables](https://docs.dolthub.com/sql-reference/version-control/dolt-system-tables) 暴露,将版本控制写入操作作为 [stored procedures](https://docs.dolthub.com/sql-reference/version-control/dolt-sql-procedures) 暴露。 系统表和存储过程的命名遵循 `dolt_` 模式。因此,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://docs.dolthub.com/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]` ``` 哎呀,我违反了约束。看起来我是在 employees 之前创建了 teams 表。插入时你应该始终指定列,而不是依赖自然排序。我真是活该!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` 列出 engineering 团队的成员。Dolt 支持最多十二个表的 `JOIN`。同样,Dolt 是一个现代 SQL 关系数据库,结合了 Git 风格的版本控制。 ## 检查 diff 现在,如果你想在提交之前查看工作集中发生了什么更改怎么办?你使用 `dolt_status` 和 `dolt_diff_` 系统表。 ``` 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 commit 结束,这次使用 `-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、数据还是两者。 ``` 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://docs.dolthub.com/sql-reference/version-control/dolt-sql-procedures#dolt_revert) 撤消特定的提交。即使你不小心在错误的数据库上运行 `drop database`,Dolt 也允许你通过调用 [`dolt_undrop()` 存储过程](https://docs.dolthub.com/sql-reference/version-control/dolt-sql-procedures#dolt_undrop) 来撤消该操作。 ## 在 SQL Workbench 中查看数据 讨厌命令行?让我们使用 [Tableplus](https://tableplus.com/) 进行一些修改。Tableplus 是一个免费的 SQL Workbench。按照其网站上的安装说明进行操作。 现在,要连接,你必须选择 MySQL 作为连接类型。然后输入你的连接名称,`getting_started` 作为你的数据库,以及 `root` 作为你的用户。 ![Tableplus Connection./images/getting-started-tp-connect.png) 点击 connect,你将看到一个熟悉的数据库 workbench GUI。 ![Tableplus](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/4982302c25152458.png) ## 在分支上进行更改 要在分支上进行更改,我使用 `dolt_checkout()` 存储过程。使用 `-b` 选项创建一个分支,就像在 Git 中一样。 Tableplus 使我能够在 SQL 选项卡上输入多行 SQL 脚本。我输入了以下 SQL 以 checkout 一个分支、更新、插入、删除,最后 Dolt commit 我的更改。 ``` 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 中的结果。 ![New Updates](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/2a89a6ce89152459.png) 回到我的终端中,我看不到在 Tableplus 中进行的表修改,因为它们发生在我会话中 checkout 的分支以外的分支上。 ``` 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) ``` 无论我 checkout 了什么,我都可以使用 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 更改成功。我们现在有了开始日期。接下来是数据更改。 ``` 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 才是生活。 我必须提交所有更改,因为最后一次合并不是快进合并。 ``` 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 哪个提交更改了我的名字?使用 Dolt,你可以获得数据库中每个 cell 的 lineage。让我们使用 `dolt_history_` 和 `dolt_diff_` 来探索 Dolt 中的 lineage 功能。 `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_` 允许你将历史记录筛选为仅限所讨论的 cell 发生更改时的提交。在这种情况下,我对更改我的名字的提交感兴趣。注意,有两个提交更改了我的名字,因为一个是原始更改,第二个是合并提交。 ``` 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 提供了强大的数据审计功能,精确到单个 cell。你的数据库中每个 cell 随着时间的推移是在何时、如何以及为何发生更改的? # 延伸阅读 既然你对 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 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)。
标签:BinlogReplication, Dolt, DoltHub, EVTX分析, EVTX分析, Git, RelationalDatabase, SchemaMigration, SQL数据库, 多线程, 安全可观测性, 开源, 数据 lineage, 数据协作, 数据工程, 数据库版本控制, 数据管理, 日志审计, 版本控制, 网络安全研究, 请求拦截