2

我最近不得不向我们的数据库团队提出一组新的 Postgres 表,这些表将被我正在编写的应用程序使用。他们失败了设计,因为我的表有这样列出的字段:

my_table
    my_table_id : PRIMARY KEY, AUTO INCREMENT INT
    some_other_table_id, FOREIGN KEY INT
    some_text : CHARACTER VARYING(100)
    some_flag : BOOLEAN

他们说该表不会是最优的,因为some_text出现在 之前some_flag,并且由于CHARACTER VARYING字段搜索比BOOLEANs 慢,因此在进行表扫描时,具有列从最高精度到最低精度排序的表结构会更快;所以,像这样:

my_table
    my_table_id : PRIMARY KEY, AUTO INCREMENT INT
    some_other_table_id, FOREIGN KEY INT
    some_flag : BOOLEAN
    some_text : CHARACTER VARYING(100)

这些 DBA 具有 Sybase 背景,最近才转为我们的 Postgres DBA。我在想这可能是一个不适用于 Postgres 的 Sybase 优化(我认为 Postgres 足够聪明以至于不关心列序列)。

无论哪种方式,我都找不到任何确认或否认的 Postgres 文档。寻找任何久经沙场的 Postgres DBA 来权衡这是否是有效的或虚假的(或有条件的有效!)声明。

4

3 回答 3

3

根据我在 Oracle 处理类似问题的经验,如果内存服务(由于在一行中查找列数据时的 CPU 开销),版本 9 和 10(或 8 和 9)之间的行为会发生很大变化,我不相信当实际实验相当简单和结论性时,您应该依靠记录在案的行为来解决此类问题。

所以我建议你为此创建一个测试用例。创建两个具有完全相同数据和不同顺序的列的表,并运行重复和不同的测试。尝试将整个测试实现为可以在开发或测试系统上运行并告诉您答案的单个脚本。也许 DBA 是对的,您可以说:“嘿,证实了您对此的想法,非常感谢”,或者您可能找不到可衡量的显着差异。在后一种情况下,您可以将整个测试交给 DBA,并解释如何无法重现问题。让他们进行测试。

无论哪种方式,有人都会学到一些东西,并且您有一个可以应用于未来(或过去)版本的测试用例。

最后,在此处发布您发现的内容;)

于 2012-10-26T12:56:38.180 回答
1

数据库设计的角度来看,您的设计与 DBA 的建议没有区别——您的应用程序不应该关心。在关系数据库中(逻辑上)没有列顺序之类的东西。实际上,如果列的顺序很重要(逻辑上)它失败了 1NF。

因此,只需将所有创建表脚本传递给您的 DBA,并让他们以他们认为在物理级别上最佳的任何方式来实现(重新排序列)。您只需继续应用程序。

数据库设计不能在列的顺序上失败——它根本不是设计过程的一部分。


必须保护大型数据库的未来用户不必知道数据在机器中的组织方式......

...处理的问题是数据独立性问题——应用程序和终端活动独立于数据类型的增长和变化...

英孚科德 ~ 1979

物理级别的更改...不得要求更改应用程序...

规则 8:物理数据独立性 EF Codd ~ 1985


所以我们在这里 - 33年后......

于 2012-10-26T13:21:52.867 回答
1

您的 DBA 可能指的是“获取”给定元组 (/row) 中的布尔值的访问策略。

在他们提出的设计中,系统可以通过查看字节 9 “获取”该值。

在您提出的设计中,系统必须首先检查所有可变长度列的 LENGTH 字段[在您的布尔列之前],然后才能知道可以找到布尔值的字节偏移量。那总是比“他们”的方式慢。

他们的考虑是物理设计之一(这是正确的)。Damir 的回答也是正确的,但是是从 LOGICAL 设计的角度来回答的。

如果你的 DBA 的评论真的是“批评‘坏’设计”,那么他们应该指出逻辑设计是你的工作(在那个级别上,列顺序无关紧要),而物理设计是他们的工作。如果他们希望也做物理设计(他们的工作),那么老板就没有任何理由让他们继续工作了。

于 2012-10-26T22:17:14.517 回答