我的网站有问题。该网站有多个实体:文章,帖子,评论。。。或6种类型。现在我介绍了用户对项目进行评级的可能性(它可以是这些实体中的任何一个)
我创建了一个表Votes(int Id主键,int ItemId,nvarchar(30)Ip,datetime Timestamp,int VoteValue)。在这里,我将存储所有的选票和他们的ips。
我的问题是我必须具有唯一的ItemID。。。但我的数据库已经有不同类型的具有相同id的项。所有表都从0开始id。为了能够将所有选票存储在一个表中,您认为我的设计有哪些选项?
您的方法试图为字段"ItemId"分配多个含义,这将导致您遇到的问题。如果我在那个领域看到"9500",我怎么知道这意味着什么?
我建议删除ItemId字段,并在Votes和其他实体之间创建"人行横道"表。
例如,您的实体:
+-----------+
| Articles |
+-----------+
| ArticleId | PK
| ~ snip ~ |
+-----------+
+-----------+
| Posts |
+-----------+
| PostId | PK
| ~ snip ~ |
+-----------+
等
您的投票表:
+-----------+
| Votes |
+-----------+
| VoteId | PK
| ~ snip ~ |
+-----------+
你的"人行横道"表:
+--------------+
| ArticleVotes |
+--------------+
| ArticleId | PK, FK to Articles
| VoteId | PK, FK to Votes
+--------------+
+--------------+
| PostVotes |
+--------------+
| PostId | PK, FK to Posts
| VoteId | PK, FK to Votes
+--------------+
请注意,在您的crosswalk表中,您将创建一个复合主键,该主键由对适当实体的两个FK引用组成,从而确保唯一性。
根据我的经验,这是对您所描述的领域的一种适当的规范化方法。
在查询中,要获得文章的投票(例如),只需通过文章投票来获得INNER JOIN文章。要获取所有投票,只需查询投票即可。
此外,我建议创建一个IPAddresses表,并在您的Votes表中使用FKing来减少冗余。
一个没有提到的选项是GUID。如果您在文章/文章/评论等中使用GUID。而不是int主键,您可以依赖它们来实现唯一性。我并不是说这是你应该使用的路线,因为它会增加存储/搜索GUID而不是int的额外开销。
我建议将类型字段添加到投票表中,并将其作为密钥的一部分。听起来你已经考虑过这个想法,但担心性能。如果您担心性能问题,请在将更改投入生产之前进行一些测试,以确保表查询满足您的需求。
一种可能性是将一组不同的表转换为类型/子类型集。关于这一点的讨论可以在这里找到。(可能相当大的)缺点是,你必须重构所有的表……但然后你会有一个Id(可能是"ItemId")来唯一地识别所有的项目类型。