博客 / 工程

使用 Atlas 管理您的 ClickHouse Schema-as-Code

author avatar
Rotem Tamir
2024 年 3 月 12 日 - 8 分钟阅读

今天,我们欢迎来自 ariga 的 Rotem Tamir,他维护着用于管理数据库模式即代码的开源工具 atlas。Rotem 深入探讨了细节,并展示了最近对 ClickHouse 支持的价值。

无模式技术的兴起与衰落

在 2010 年代初期,Python 和 Javascript 等动态类型语言以及 MongoDB 和 Elasticsearch 等 NoSQL 数据库标志着偏离严格的、预先模式规划的趋势。所有这些技术都具有不太冗长的语法和更大的灵活性,承诺更快的开发周期和更简单的原型设计,使它们成为旨在快速进入市场的新兴公司和新项目的首选语言。

然而,随着项目和组织规模和复杂性的增长,这些技术的最初优势开始暴露出重大的权衡。模式强制执行的缺失导致数据不一致,使得随着应用程序的发展,更难确保数据质量和完整性。缺乏严格的类型系统以及无模式数据库的灵活性使得调试和维护大型代码库变得越来越困难。

人们对 ClickHouse 等关系型存储技术日益增长的兴趣,标志着我们行业数据管理方法的一种细微转变。虽然现代数据系统需要处理有时需要非结构化方法的多样化数据集,但人们越来越欣赏强类型、结构化数据处理方法带来的效率和组织性。

管理模式仍然很痛苦

NoSQL 运动的驱动因素之一是许多开发人员希望不惜一切代价避免管理数据库模式的痛苦。模式更改(也称为迁移)需要技术专业知识才能安全有效地完成。现代数据库提供了一种有限的命令式方式来更改模式,称为 DDL 语句。

如果我们不完全放弃模式及其好处,而是使管理模式成为一个无缝的过程,而无需任何特殊努力,会怎么样?管理数据库模式无疑需要技术专业知识,但这并非一个无限复杂的问题。因此,可以创建自动化工具来简化非专家的任务。

数据库模式即代码

atlas_declarative_vs_imperative.png

近年来,随着云计算资源管理方法 基础设施即代码 取得巨大进步,一种新的数据库模式管理方法正在兴起。这种方法被称为 “数据库模式即代码”,并由 AtlasSkeema 等项目体现,旨在通过为工程师配备一个提供声明式 API 以与数据库交互的工具,极大地简化模式管理。

声明式 API 的工作原理是向工具提供系统的期望状态,并让工具找出使其与当前状态协调所需的操作。在数据库模式管理上下文中,用户向工具提供他们希望数据库拥有的模式,让工具检查当前的数据库信息模式,并自动为他们生成迁移计划。

当然,自动迁移计划并不是一个新概念。应用程序开发框架和 ORM(如 Django)多年来一直提供类似的功能。在 ORM 级别自动化迁移计划的问题在于,它们只能在其特定上下文中使用,并且不能通用地应用于每个堆栈。此外,ORM 倾向于关注数据库功能的一小部分,例如表、列、外键和索引,并且不提供管理更高级对象(如视图、物化视图、存储过程等)的方法。

工作原理

让我们看看数据库模式即代码和声明式迁移在实践中是如何工作的。为了演示这一点,我们将使用 Atlas,一个开源数据库模式即代码工具(F.D:我是创建者之一)。有关入门和安装说明,请访问 Atlas 文档

作为本演示的先决条件,让我们使用 Docker 运行一个本地的空 ClickHouse 实例

docker run --rm -d --name atlas-demo -e CLICKHOUSE_DB=demo -p 9000:9000 clickhouse/clickhouse-server:latest

与更传统的方法相反,使用声明式迁移,我们始终从数据库的期望状态开始。让我们创建一个名为 schema.sql 的文件,内容如下

CREATE TABLE `users` (
   `id` UInt64,
   `name` String)
ENGINE = MergeTree
PRIMARY KEY (`id`)
ORDER BY `id`;

现在,我们可以使用 atlas schema apply 命令将此模式应用于目标数据库

atlas schema apply \
-u "clickhouse://127.0.0.1:9000/demo" \
--to file://schema.sql \
--dev-url "docker://clickhouse/23.11/demo"

这将告诉 Atlas 我们要将名为 schema.sql 的文件中定义的模式应用于 localhost:9000/demo 的 ClickHouse 数据库(我们刚刚使用 Docker 在本地启动)。

Atlas 连接到目标数据库,检查其信息模式,计算当前状态和期望状态之间的差异,并提示我们批准迁移计划

-- Planned Changes:
-- Create "users" table
CREATE TABLE `users` (
  `id` UInt64,
  `name` String
) ENGINE = MergeTree
 PRIMARY KEY (`id`) SETTINGS index_granularity = 8192;
? Are you sure?:
  ▸ Apply
    Lint and edit
    Abort

计划看起来不错,因此我们点击“应用”以将更改应用于数据库。

在成功运行 Atlas 为我们计划的迁移后,我们可以重新运行 schema apply 命令,以确保数据库处于其期望状态

atlas schema apply \
-u "clickhouse://127.0.0.1:9000/demo" \
--to file://schema.sql \
--dev-url "docker://clickhouse/23.11/demo"

Atlas 再次连接到我们的 ClickHouse 实例,检查它,并计算差异,这次告诉我们

Schema is synced, no changes to be made

接下来,让我们对期望状态进行一个小更改,以表明声明式迁移在具有现有模式的实时数据库上有效。让我们向我们的 users 表添加一个新列 email_address。编辑 schema.sql 添加以下列

CREATE TABLE `users` (
    `id` UInt64,
    `name` String,
+    `email_address` String
)
 ENGINE = MergeTree
 PRIMARY KEY (`id`)
ORDER BY `id`;

接下来,让我们重新运行 schema apply 命令,看看 Atlas 如何为我们计划迁移

-- Planned Changes:
ALTER TABLE `users` ADD COLUMN `email_address` String;
? Are you sure?:
  ▸ Apply
    Lint and edit
    Abort

太棒了!Atlas 检测到现有表,并计划迁移以将缺少的列添加到目标数据库。让我们点击 Apply 以将我们的数据库置于期望状态。

总结

2010 年代,由于开发人员试图避免模式管理的复杂性,无模式数据库成为趋势,但随着系统规模的扩大,这种转变导致了数据一致性和维护方面的挑战。从过去的挑战中吸取教训,科技行业现在对关系型技术表现出新的兴趣。

然而,开发人员仍然面临着与过去相同的模式管理挑战。数据库模式即代码工具(如 Atlas)应运而生,提供简化和精简模式操作,弥合开发效率需求与结构化数据完整性需求之间的差距。

在本文中,我们展示了 Atlas 功能的一瞥,但这绝不是一个全面的指南。有关 ClickHouse 用户的更完整的“Atlas 入门”指南,请访问 Atlas 文档网站

分享这篇文章

订阅我们的新闻通讯

随时了解功能发布、产品路线图、支持和云产品!
正在加载表单...
关注我们
X imageSlack imageGitHub image
Telegram imageMeetup imageRss image
©2025ClickHouse, Inc. 总部位于加利福尼亚州湾区和荷兰阿姆斯特丹。