具有复合键的外键与自动增量

时间:2012-11-19 21:27:40

标签: mysql sql

我有一个数据库,我将在其中存储两个用户之间的对话。我将保持一个对话表和一个消息表。对话表将存储两个用户之间的对话,而消息表将消息存储在特定对话中。两个用户之间只有一个对话,如MSN messenger或Facebook消息,新消息将添加到此对话中。我有两个想法可以做到这一点。

第一种方法:

conversations(c_id, user1, user2) 

c_id是主键auto_incremented

messages(m_id, c_id, user_from, user_to, content) 

m_id是主键auto_incremented,c_id是外键引用对话(c_id)

在第二种方法中,

conversations(user1, user2) 

(user1,user2)是复合主键

messages(m_id, user_from, user_to, content) 

m_id是主键,(user_from,user_to)是外键引用对话(user1,user2)

我的问题是哪一个更好? 1号,2号还是没有?我还没有在我的任何设计中使用复合外键,老实说我不知道​​结果会是什么。

除了所有这些字段外,还有读取日期,输入日期等字段。为了简洁起见,我正在跳过这些。

2 个答案:

答案 0 :(得分:0)

键/索引决策很大程度上受您查询数据的方式的影响。我将忽略插入性能,假设您的查询性能更重要(这可能是错误的假设,只有您知道)。此外,根据您的列名称,我假设消息方向很重要,就像在同一个对话中一样,有时用户X在消息user_from列中,有时在user_to列中。在您对Laurence的评论中,您说您将首先显示用户参与的对话列表,然后当他们点击一个对话时,您将显示消息列表。所以我们可能不会查看联接,而是查看一对查询,因为您一次只能获得一个对话的消息。

查询1将是用户X的会话选择,例如: 从user1 = X或user2 = X

的会话中选择*

此时,两个选项都是等效的。现在,第二个查询获取给定对话的消息。

选项1: select * from message where c_id =? (在第一个查询中获取c_id,并将其与列表框中的每一行相关联)

选项2: 从列表框中单击,您现在知道您想要用户X和Y之间的对话消息:

从消息中选择*(user_from = X和user_to = Y)或(user_from = Y和user_to = X)

如果我在这里的所有假设都是正确的,那么显然选项1是优越的,因为它是一个非常快速的单值主键查找。否则,对如何查询数据进行类似的分析,这应该指向更好的解决方案。

(顺便说一句,在你的消息表中,不是重复两个用户,只是有一个0/1位列指示会话的方向,因为会话表已经有一个订单。例如,如果会话表有cid 1,用户X,用户Y,然后当用户x是来自用户时,用于cid 1的消息表可以将位设置为零,当用户y是来自用户时,将位设置为1)

答案 1 :(得分:0)

我个人的偏好是永远不会有复合FK - 如果具有复合PK的表与另一个表之间存在一对多的关系,根据经验,我创建一个单列主键(自动 - 递增,连接现有列或任何唯一键生成方法为您剪切它,然后键入它。我认为复合FK在设想两个表之间的关系时可能过于混乱。

YMMV