已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新问题,以便editing this post可以使用事实与引用来回答.
21小时前关门了。
Improve this question
Supabase用于版本控制(PostgreSQL)模式的工作流是供开发人员手动运行一个工具,该工具在每次更改后对模式进行差异化,并将生成的迁移保存到文件中。
我发现,使用命令式命令(CREATE TABLE、ENABLE ROW LEVEL SECURITY等)构建数据库模式,然后使用比较工具创建命令式迁移,这让我很惊讶。
看起来更好的方法是使用一些声明性标记语言来描述模式,如JSON、YAML、XML等,然后迁移可以只是模式声明版本之间的Git差异。
我发现很多人都说SQL * 是声明性的,但从我(作为一个新手)的Angular 来看,它似乎是由必须按顺序执行的命令组成的。我发现有几个项目声称在处理声明性数据库模式,而不是迁移(skeema.io,schemahero.io),但没有广泛采用的迹象。
为什么会这样呢?是历史的产物,还是我遗漏了一些声明式模式管理方法的关键挑战?
我在Reddit上找到了this answer:
更新数据库模式的90%的工作是更新数据。这不能用期望的状态来完成。例如,引入一个城市引用表,你不能用模式差异来完成,你需要在迁移数据的同时做出业务逻辑决策。所以使用许多现有的迁移系统中的一个,忘记这个想法。
那么,答案是您需要根据具体情况发出命令式命令来处理数据迁移,而声明式引擎无法做到这一点吗?
2条答案
按热度按时间ou6hu8tu1#
字母SQL的意思是结构化查询语言。这个名字中最重要的词是QUERY,意思是它不是一种过程语言。在过程语言中,你写的是你希望计算机执行的确切命令。在SQL,一种“查询”语言中,你不写程序代码,而只写你想要的答案。则SQL算法/优化器必须计算将由查询处理器执行的程序(称为“查询执行计划”)。这与SELECT、INSERT、UPDATE...查询一样有效(这是语言的DML部分),而且也适用于CREATE、ALTER、DROP(DDL部分)或GRANT / REVOKE(DCL部分)。
要优化任何查询,优化程序需要具有结构的完整视图,并且此结构必须是稳定的。(例如,在涉及表的CREATE VIEW之前不存在的表),SQL命令将失败。另一件事是SQL代码的“编译”是在执行查询的时刻完成的,并且在一些RDBMS中,如果结构不稳定,则在更改或删除SQL对象的任何部分、创建索引或对数据进行重要更改(重新计算优化程序的统计信息)时,将该高速缓存中丢弃所有执行计划。
另外,视图是特殊的表,基于表,但逻辑上是独立的...这意味着视图可以从它使用的表数据结构中取消同步...
由于所有这些原因,您不能将执行语言与查询语言进行比较...
ef1yzkbh2#
我想你得到的反对票是因为 * 声明性 * 和 * 命令性 * 的误解,对什么是 * 迁移 * 的过度简化,加上一个带有错别字的随机reddit引用和一个不清楚的反例--如果有人来这里想被冒犯的话,所有这些都是非常冒犯的。
为了解开这个问题,将问题中的误解作为单独的问题来解决:
1.What vs how是declarative vs imperative的一个更好的简化。SQL * 是 * declarative。你定义你的模式是 what 和 what 你想要从它里面得到什么。RDBMS处理 how 它是如何执行的。你可以观察在你的查询之前添加的
EXPLAIN ANALYZE VERBOSE
的输出,并看到计划者提出achieving that的最佳方式。您还可以检查您的定义的文件系统representation,也是由db计算出来的,而不是您。1.根据定义,迁移是必不可少的,您可以看到它们的声明性处理。迁移是将一个源模式转换为另一个目标模式所需采取的一组步骤。从一个声明的对象到另一个声明的对象的 * 方式 *。Supabase会自动处理它-您只需 * 声明 * 目标。
1.当在git中进行diff时,普通的
.sql
和.json
都没有优势。diff也不是一个迁移--它必须被翻译成create
/alter
/drop
语句才能成为一个。现代的ORM可以为你做这两件事。