何时使用复合类型和数组以及何时规范化数据库?

ve

是否有关于何时规范化数据库或仅使用复合类型和数组的准则?

当使用数组和复合类型时,我只能使用一个表。我还可以规范化数据库并使用几个表和联接。

您如何确定最佳选择?

克雷格·林格(Craig Ringer)

大多数时候,坚持规范化。除其他事项外,使您的数据库标准化得相当好有助于锁定粒度。例如,如果您有一个带有两个数组的“父”对象,则不能有同时添加/更新/修改数组成员的事务。如果它们是常规的边桌,则可以。不过,SELECT ... FOR UPDATE如果序列化的行为,您仍然可以在更新子对象之前保留父行)。

更新数组以添加/替换/删除值非常昂贵,因为PostgreSQL必须重写该数组所在整个元组作为MVCC更新。(它有一些TOAST技巧可以起到帮助作用,但无济于事)。嵌入在行中的同上复合类型。

装满数组和组合的宽大行意味着较慢的表扫描,这意味着较慢的常用值提取。

IIRC您无法在复合类型的字段中定义外键,因此您会发现自己正在解决该问题,或者放弃了具有完整性的引用完整性。同上数组(有一些工作可以使数组的外键起作用,但我认为它从来没有使用过)。

许多客户端驱动程序(PgJDBC,psqlODBC,psycopg2等等等)对数组和组合的支持都不完整,甚至根本不存在,因此无论如何您通常都会将它们扩展为元组以与客户端驱动程序进行交互。有些东西,例如复合类型的数组,确实很难处理。

大多数ORM,包括像Hibernate这样的通用ORM,都完全会使用超出最简单化的最低公分母SQL功能之外的任何东西。迟早会有人想要在您的数据模型中指出其中之一,这时会产生很多哭泣和咬牙切齿的感觉。OTOH,请勿将垃圾ORM容纳到避免使用会大大改善数据模型并解决现实世界问题的功能的程度,例如,如果您选择存储本机hstore字段或使用EAV模式,请考虑只使用jstore(或者更好,在9.4中,带有hstore功能的json)。

(相反,这意味着拥有“面向对象”程序最多的人通常拥有最纯粹的关系数据库,因为他们的工具很烂)。

诸如报表生成工具之类的东西也将类似地与组合和数组纠缠,因此您经常会创建视图以为数据库提供标准化外观。然后ON INSERT OR UPDATE OR DELETE ... DO INSTEAD在视图上触发以启用写入。在这一点上,它变得丑陋。

就个人而言,我建议您在逻辑上将某事建模为“类型”时,保留合成。例如,考虑一下,如果您的数据模型要求您跟踪原始时区中的时间戳。对此没有内置类型(不,尽管有SQL委员会的名称,“带时区的时间戳”不是这样做的),所以您可以创建一个(timestamp without time zone, tzname)在数据模型中一致地存储和使用该类型的复合类型

同样,我倾向于在查询中大量使用数组,但在数据模型中却很少使用数组。当您要有意地对某些内容进行规范化以提高性能时,它们很有用,但这通常是在物化视图或类似视图中完成的。即使是对主数据模型的更改,这也是您应该基于适当的性能评估而要做的事情,而不仅仅是“优化”您还不知道很慢的事情。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章