我该怎么用作此表的主键?

时间:2012-09-03 22:07:57

标签: database database-design

我正在为一个网站建立一个小型论坛组件,其中子论坛有不同的管理员和mod负责他们,用户可以被禁止从单个子论坛。禁令表我看起来像这样:

_Bantable_ 
user_id 
group_id
start_date 
end_date 
banned_by 
comment 

起初我打算使用前四列作为主键,但现在我想知道如果我根本使用一列是否重要,因为没有人会在同一时间被禁止同一个论坛,无论我还是要检查它们是否已经被禁止以及在什么时间间隔内。我不应该在这里使用密钥,只需在user_id和group_id上创建一个索引,并在需要时搜索这些索引吗?

3 个答案:

答案 0 :(得分:1)

这不是100%明确,但听起来您希望特定groupId的每个用户使用临时禁止功能。如果是这种情况,则应创建复合主键:

user_id,
group_id,
end_date

这将让你做到

SELECT * FROM bantable WHERE user_id=$currentUserToCheck AND group_id=$currentGroupToCheck AND end_date < $currentDate

或类似的东西

注意:如果您希望主键在您所遵循的任何数据库设计原则方面保持一致,那么您可以将主键设为user_id(因为它确实是一个唯一的标识符),然后在我上面指定的三列上创建一个复合索引。

绝对确保您针对此表运行的任何需要单个索引的查询都正确生成了这些索引。

答案 1 :(得分:0)

为什么不把user_id作为主键?我的意思是你甚至不必使用auto_increment(这显然在这里没有任何意义)。

猜测你在登录时请求user_id这可能会提供最好的表现,看看是否有禁止事项的条目。

答案 2 :(得分:0)

您是否需要过去禁令的历史记录?

  • 如果没有,只需在{user_id, group_id}上创建一个复合PK。无论_Bantable_当前的数据是什么,都会确定当前被禁止的人。禁令到期后,只需删除相应的行(并考虑是否需要end_date 1 )。

  • 如果您确实需要历史记录,请像以前一样对原始表格进行有效禁止,但禁令到期时,不要只删除它 - 而是将其移到单独的“历史记录”表中,将具有独立于{user_id, group_id}的代理PK 2 (因此相同的用户/组对可以在多行中)以及防止时间重叠的触发器(类似this


1 如果这是禁令即将结束的日期,那么你确实需要它。如果这是禁令结束的日期,那么你就不会 - 那时行将消失。

2 或者{user_id, group_id, start_date}上的PK。