我正在使用Postgres 9.5进行投票表设计(但问题本身可能适用于一般的sql)。我的投票表应该是:
-------------------------
object | user | timestamp
-------------------------
其中object
和user
是与其自己的表对应的ID的外键。我有一个问题,确定实际应该是什么主键。
我一开始认为是primary_key(object, user)
但是因为我使用django作为服务器,它只是不支持多列主键,我不确定性能,因为我可能只使用访问行这两个列中的一个(即object
或user
),但这个想法的优势在于自动作为唯一键,因为同一个用户不应该为同一个对象投票两次。我不需要任何额外的索引。
另一个想法是引入auto
或serial
id字段,我真的不认为使用这种方法有任何好处,特别是当表变大时。我还需要引入至少一个unique_key(object, user)
,这会增加计算复杂性和数据存储。当我选择使用2列中的一列时,我甚至不确定性能,可能还需要object
和user
的2个额外索引来加速选择操作,因为我需要这么多。
我在这里缺少什么吗?还是有更好的主意?
答案 0 :(得分:1)
正确的解决方案是在PRIMARY KEY (object, user)
上设置user
和附加索引。主键索引也可用于单独搜索object
。
从数据库的角度来看,问题是如果不支持复合主键,则使用不充分的中间件。
您可能不得不引入人工主键约束,此外还有(object, user)
上的唯一约束和user
上的索引,但您的直觉感觉不是最好的从数据库角度来看解决方案绝对正确。
答案 1 :(得分:1)
django自己认识到不支持这种情况下的“自然主键”。所以你的直觉是正确的,但是django不支持它。
https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys
关系数据库设计使用一组列作为主键 一张桌子。当该集合包括多个列时,它是已知的 作为“复合”或“复合”主键。 (有关更多内容 术语,这是一篇讨论数据库密钥的文章。)
目前Django模型仅支持此集合中的单个列, 否认许多设计,其中表的自然主键是 多列。 Django目前无法使用这些模式;他们 必须改为引入冗余的单列密钥(“代理” 键),迫使应用程序任意和其他不必要的 选择在任何给定实例中用于表的键。
我个人django的失败少了。 一个选项可能是通过连接对象和用户来形成一个额外的列作为主键。
请记住,主键没有什么特别之处。您始终可以在这对列上添加UNIQUE KEY
,并将它们同时NOT NULL
。
您可能会发现此示例很有用。