我最近不得不向我们的数据库团队提出一组新的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
字段搜索速度比BOOLEAN
慢,所以在进行表扫描时,具有表结构的表格结构更快,其列的排序从最高精度到最低精度;所以,像这样:
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来衡量这是否是有效或伪造(或有条件有效!)的声明。
答案 0 :(得分:3)
根据我在Oracle上遇到类似问题的经验,如果内存服务于版本9和10(或8和9)之间的行为发生了很大变化(由于在一行中查找列数据的CPU开销),我当实际的实验相当简单和确凿时,不要相信你应该依赖记录在案的行为来解决这个问题。
所以我建议你为此创建一个测试用例。创建两个具有完全相同数据的表和不同顺序的列,并运行重复和变化的测试。尝试将整个测试实现为可以在开发或测试系统上运行的单个脚本,并告诉您答案。也许DBA是对的,你可以说,“嘿,确认你对此的想法,非常感谢”,或者你可能找不到可衡量的重大差异。在后一种情况下,您可以将整个测试交给DBA,并解释如何无法重现问题。让他们进行测试。
无论哪种方式,某人都会学习一些东西,而且你有一个可以应用于未来(或过去)版本的测试用例。
最后,在此发布您发现的内容;)
答案 1 :(得分:1)
从数据库设计一点来看,您的设计与DBA建议的内容没有区别 - 您的应用程序应该不关心。在关系数据库(逻辑上)中没有列的顺序;实际上,如果列的顺序很重要(逻辑上),它就失败了1NF。
因此,只需将所有create table脚本传递给DBA,让它们以物理级别上最佳的任何方式实现(重新排序列)。您只需继续使用该应用程序。
数据库设计不能按列顺序失败 - 它根本不属于设计过程。
必须保护大型数据银行的未来用户不必知道 如何在机器中组织数据......
......处理兔子的问题是数据独立的问题 - 应用程序和终端活动的独立性 数据类型和变化的增长......
E.F。 Codd~1979
物理等级的变化......不得要求改变 申请......
Rule 8: Physical data independence( E.F.Codd~1985 )
所以我们在这里 - 33年后......
答案 2 :(得分:1)
您的DBA可能指的是“gettting to”给定元组(/ row)中的布尔值的访问策略。
在他们提出的设计中,系统可以通过查看字节9来“达到”该值。
在您提出的设计中,系统必须首先检查所有变长列[在布尔列之前]的LENGTH字段,然后才能知道可以找到布尔值的字节偏移量。这总是比“他们的”慢。
他们的考虑是物理设计之一(并且它是正确的)。 Damir的答案也是正确的,但从LOGICAL设计的角度来看,这是一个答案。
如果您的DBA的评论真的是“批评'糟糕''设计”,那么他们应该指出LOGICAL设计是您的工作(并且列顺序不是在那个层面上的问题),而物理设计是他们的工作。如果他们希望你做出物理设计(他们的工作),那么老板就没有任何理由让他们继续受雇。