性能命中建模多态性在postgresql上的一对多联接表中有许多关系?

性能命中建模多态性在postgresql上的一对多联接表中有许多关系?,sql,postgresql,Sql,Postgresql,TL;DR-我正在寻找关于多态关系表的最佳实践反馈。有一个没有外键约束的表更好(为关系的每一侧生成一个_id和_type列,为关系类型生成一个整体类型列),还是有多个表更好,每种可能的父类型-关系类型-子类型关系一个表 我的(postgres 9.3)数据库中有几个表具有多态关系。特别是,文档可以同时向用户和社区类型对象授予访问权限(其中社区有许多用户作为成员,因此这将授予社区的所有成员该权限),其中权限包括编辑、查看和评论 现在,我将其建模为单个访问权限表: CREATE TABLE edge

TL;DR-我正在寻找关于多态关系表的最佳实践反馈。有一个没有外键约束的表更好(为关系的每一侧生成一个_id和_type列,为关系类型生成一个整体类型列),还是有多个表更好,每种可能的父类型-关系类型-子类型关系一个表

我的(postgres 9.3)数据库中有几个表具有多态关系。特别是,
文档
可以同时向
用户
社区
类型对象授予访问权限(其中
社区
有许多
用户
作为成员,因此这将授予社区的所有成员该权限),其中权限包括编辑、查看和评论

现在,我将其建模为单个访问权限表:

CREATE TABLE edges (
    id integer NOT NULL,
    parent_id integer NOT NULL,
    parent_type character varying(255) NOT NULL,
    child_id integer NOT NULL,
    child_type character varying(255) NOT NULL,
    type character varying(255) NOT NULL,
    created_at timestamp with time zone NOT NULL default CURRENT_TIMESTAMP
);
我在这个表的五个主要列上有一个复合索引(parent_type、parent_id、child_id、child_type、type)。但是,很自然,我的许多不同类型的查询通常不会命中主索引-有时我会查找哪些社区对该文档具有查看权限,更多时候我会查找该社区对哪些文档具有查看权限,而且我必须经常说,“此用户或此用户所属的任何社区是否具有此文档的查看权限”

我也不能真正利用任何外键约束,我希望能够。目前,我必须编写一系列触发器,以改善我在删除级联中免费获得的行为。我还希望有更强大的保护,防止(比如)删除非空社区或孤立文档(在没有人对文档拥有任何权限的情况下创建文档),这在一次性使用的表上更容易实施,我可以对引用完整性提出更有力的主张

在这一点上,我真的在过早地进行优化。我的总体数据库很小,我的用户群预计在未来五年内不会超过500个。但是,我想从最佳实践的角度来处理这个问题

我可以将单个表分解成一大堆更小的表(用户视图文档、用户注释文档、社区视图文档等,每个关系类型一个表)。这在我第一次开始这个项目时是不可行的,因为我不知道系统中会有多少对象类型(这就是为什么会有父类型列)或者有多少种权限类型

我在表格中也有其他边缘(用户可以同意/不同意文档,这也是一个边缘),但这些查询很少,因此我不介意将它们都放在一个表格中(因为它使计算一个文档有多少反应变得更容易,而无需引用喜欢、同意和同情,而且它还使以后构建新类型的用户->文档反应和其他边缘变得更容易),但我正在认真考虑将权限关系拉到它们自己的表中,主要是因为我的数据库目前所做的大部分工作是计算使用此表的文档的访问权限

我也可以不考虑这一点,而是考虑更好地在内存中缓存计算值(我已经使用redis来存储每个用户的社区成员资格列表,因为我最终需要在每个api查找中使用它,因为我必须在计算访问权时使用它)


那么:这里有公认的最佳实践吗?有没有好书/博客/问题可以阅读,可以帮助我更好地优化查询和索引?

所以
parent\u id
child\u id
基本上都是外键,指向多形实体?是的,但我不能在结构上称它们为外键,因为它们可能请转到几个不同的表中的一个。