【问题标题】:Identifying primary key for a vote table识别投票表的主键
【发布时间】:2016-09-02 05:52:20
【问题描述】:

我正在使用 Postgres 9.5 进行投票表设计(但也许问题本身通常适用于 sql)。我的投票表应该是这样的:

-------------------------
object | user | timestamp
-------------------------

其中objectuser 是对应于它们自己的表的id 的外键。我在确定什么应该是主键时遇到问题。

我起初想创建一个primary_key(object, user),但由于我使用 django 作为服务器,它只是不支持多列主键,我也不确定性能,因为我可能只使用其中一个来访问一行这 2 列(即objectuser),但这个想法的优点是自动作为唯一键起作用,因为同一个用户不应该为同一个对象投票两次。而且我不需要任何额外的索引。

另一个想法是引入autoserial id 字段,我真的不认为使用这种方法有什么好处,尤其是当表变大时。我还需要至少介绍一个unique_key(object, user),它会增加计算复杂性和数据存储。甚至不确定使用 2 列之一选择时的性能,可能我还需要 2 个额外的索引用于 objectuser 来加速选择操作,因为我非常需要这个。

我在这里缺少什么吗?还是有更好的主意?

【问题讨论】:

    标签: sql django postgresql


    【解决方案1】:

    django 自己认识到在这种情况下不支持“自然主键”。所以你的直觉是对的,但是 django 不支持它。

    https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys

    关系数据库设计使用一组列作为主键 一张桌子。当该集合包含多于一列时,已知 作为“复合”或“复合”主键。 (有关更多信息 术语,这是一篇讨论数据库键的文章。

    目前 Django 模型仅支持该集合中的单个列, 否认许多表的自然主键是 多列。 Django 目前不能使用这些模式;他们 必须改为引入冗余的单列键(“代理” 键),强制应用程序进行任意和其他不必要的操作 选择在任何给定实例中为表使用哪个键。

    我个人对 django 的失败较少。 一种选择可能是通过连接对象和用户来形成一个额外的列作为主键。

    请记住,主键没有什么特别之处。您始终可以在这对列上添加UNIQUE KEY,并将它们都设为NOT NULL

    您可能会发现此示例很有用。

    https://thecuriousfrequency.wordpress.com/2014/11/11/make-primary-key-with-two-or-more-field-in-django/

    【讨论】:

    • 谢谢!是否有一个活跃的 django 应用程序或为复合主键设计模型的简单方法?
    • 成功了!谢谢菲利普!当我将primary_key=True 添加到两者的第一列时,问题就解决了。由于我的models.py 是使用manage.py inspectdb 生成的,因此unique_together 字段已使用包含两列的元组定义。这似乎是一种 hack 而不是一种干净的方式,但至少在 postgres 级别上可以正常工作。
    【解决方案2】:

    正确的解决方案是在PRIMARY KEY (object, user) 上添加一个索引并在user 上添加一个索引。主键索引也可以单独用于搜索object

    从数据库的角度来看,你的问题是如果它不支持复合主键,你使用的中间件不合适。

    您可能必须引入一个人工主键约束,此外还有一个对 (object, user) 的唯一约束和一个在 user 上的索引,但您的直觉认为这不是从数据库角度来看的最佳解决方案绝对正确。

    【讨论】:

    • 感谢这个快速而详细的答案,我现在投了赞成票,如果没有其他针对 django 部分的答案,我会将其作为可接受的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2017-08-04
    • 2011-09-30
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多