【发布时间】:2020-07-02 18:53:20
【问题描述】:
目标:我正在寻找一种将 SQL 表架构“应用”到数据库的声明性和可重复的方式
我尝试过的
下面是一个 SQL 脚本,它可以执行我想要的操作(根据我对 MySQL 的肤浅知识和一些手动测试,尽我所能判断):
- 如果表不存在,则创建它
- 如果表确实存在,它会确保它具有所需的架构
-- create table
create table if not exists `EntryType` (
`EntryCode` varchar(2) primary key,
`Name` varchar(256) not null
) engine = InnoDB default charset = utf8mb4;
-- modify table
alter table `EntryType`
engine = InnoDB,
character set utf8mb4;
alter table `EntryType`
modify `EntryCode` varchar(2),
drop primary key,
add primary key (`EntryCode`);
alter table `EntryType`
modify `Name` varchar(256) not null;
这种方法的问题
- 重复:重复列定义、引擎和字符集两次
- 费力:每次添加或修改表时,都需要花费大量时间来制作这些查询并手动测试它们
- 命令式:从根本上说,这是对应该声明性的事物的命令式方法
问题:是否有一些安全的方式以声明方式“应用”表架构?
- 幂等:可以以完全相同的最终状态应用任意次数
- 无论表是否已存在都有效
- 无论表是否已包含数据都有效
- 无论是否存在对其他表的约束和外键引用都有效
偏好:
- 纯 SQL 解决方案是理想的
- 可靠且易于使用的 CLI 解决方案会起作用
- 也可以接受相对简单的手工编码 SQL 或 Node.js 解决方案
【问题讨论】:
-
你想要Skeema。它不是纯 SQL 解决方案,但没有纯 SQL 解决方案。 Skeema 符合您的描述。
-
您正在描述通常称为“迁移”的内容,并且有许多工具可以帮助您做到这一点。如果你喜欢 Node,那么Sequelize 有一个你可以使用的迁移系统。
-
Skeema 看起来确实符合我的要求。 ???试试看。
-
@tadman,迁移使用仍然使用命令式方法,但我正在寻找一个声明性解决方案。
-
SQL 本身无法解决这个问题,因为 SQL 的功能不够完整,无法做到这一点。您将需要其他东西来与服务器交互并执行此操作。任何纯粹的“声明性”迁移系统实际上都是垃圾,因为它会在短时间内把事情弄得一团糟。你想要控制它正在做什么。
标签: mysql sql database-schema