我知道很多次都会问过这个问题,但请在这个例子中解释一下。
所以...我有2个表:用户和组
Users(ID, Name...)
Groups(ID, UserID[FK], GroupName)
每个用户都可以在“组”表中拥有多个记录(组)。
好的,为什么我真的需要Groups表中的ID字段?
我做的每一个SQL都是这样的:
SELECT * FROM Groups WHERE UserID = ...
此外,用户不能拥有重复的组,因此表中永远不会有2个确切的行。
那么,ID字段用于什么?
答案 0 :(得分:4)
您不需要使用单个整数列作为主键 - 您只需将主键定义为UserID
和GroupName
。
为什么要使用主键?
根据您的DBMS,表中的记录将由主键组织,从而使该键的查找速度最快。定义主键非常容易。对于所涉及的微小投资,您可以大幅提升性能和可扩展性。
几乎所有DBMS都强制实施主键的唯一性。你说用户不能两次拥有同一个组。要将主键定义为UserID
和GroupName
,您可以在数据库级别(无需任何其他代码)保证该假设始终为真。
答案 1 :(得分:2)
在数据库表中使用主键不是必需的,但通常这是一个好主意。想象一下,你有一百万条记录,想要找到UserID 532,395。如果没有索引,数据库将必须搜索整个文件,直到找到记录。使用索引,它只需要搜索一些记录。
在您的情况下,我将按UserID索引/键入Groups表,以便您可以快速查找给定用户所在的所有组。您可以拥有(UserID,GroupName)主键或自动递增行号。
答案 2 :(得分:1)
做一些事情要花费的时间少于做两次。
当您设计数据库时,您不仅需要满足当前的需求,还应该预测未来的需求。例如,您声明了当前要求“此外,用户不得拥有重复的组”。那没关系,但如果改变了怎么办?
我自己会带3张桌子。组将GroupID作为PK,GroupName作为字段,以及我认为合适的任何其他字段。用户将具有类似的结构。
我的第三个表是UserGroups。它将有一个复合主键,由UserID,GroupID和其他一些字段组成,具体取决于我设想的当前和未来需求。
另外,我发现在所有表格中放置CreatedWhen,CreatedBy,LastUpdatedWhen,LastUpdatedBy通常都值得花时间和精力。
最后,当你这样做时:
SELECT * FROM Groups WHERE UserID = ...
我会这样做:
select JustTheFieldsINeed
from Users join UserGroups using (UserId)
join Groups using (GroupId)
where UserId = something
and other conditions are met.
虽然你的方法起初需要的工作量较少,但如果我从现在开始被告知用户现在可以属于更多的那一组,我可以简单地说,“是先生,3袋满包邮”,然后拿走小睡。
答案 3 :(得分:0)
主键通常不是强制性的,但通常建议使用。如果表上的数据量非常小,则主键不会提高性能,因为每次访问时都会读取整个表。但是,对于大多数小尺寸表,主键会使读取性能更快。
对于没有主键或唯一键的表,您可能会遇到一些问题:
在users
表中,使用ID
作为主键