使用NULL值的唯一键工作?

使用NULL值的唯一键工作?

问题描述:

我创建聊天应用程序和其聊天看到SQL看起来像下面使用NULL值的唯一键工作?

chat_seen --table name 
--Columns--- 
from_user | to_id | group_id | unseen_count 

它的工作原理是这样的:当GROUP_ID是NULL则表示,这是一对一的聊天,如果GROUP_ID不为空FROM_USER是最终用户其中写的消息和to_id是用户谁是组成员。我有group_id上的外键,它引用组表,并且我有唯一键为3列(from_user,to_id,group_id),当group_id为null时,它应该工作,因为from_user并且to_id在一对一聊天中应该是唯一的,但在群组聊天中,它应该是每个group_id唯一的,如果Unique键与NULL VALUES一起工作,这将工作,因为如果它工作,它会将group_id NULL值计数为group_id和每个NULL组from_user和to_id将是唯一的。我不能改变group_身份证到任何事物,因为它有外键。

我也想实现,如果group_id不为null to_id应该有外键,它应该引用组成员,group_id不是NULL它应该引用user_id在用户表中。

更新版本与实例

当有人在每个消息我插入或更新(如果存在),以chat_seen表为每个用户组写消息时,它意味着,如果组包含每每个消息20人我将更新或插入20列以稍后通知他们,如果他们没有看到聊天。并且我更新每个用户的unseen_count。

我该怎么办?有什么建议吗?

+0

这是行不通的(原因很好)。从技术上讲,你可以添加一个新的列'group_memberid',并留下'to_id''null'为组聊天,然后创建一个唯一的密钥(组聊天和1-1聊天)。另一方面,在你的设计中你可能会遇到一些问题(虽然我不知道你的数据库,所以这只是一个猜测):a)组成员关系可以改变,所以组表的外键可能不起作用例如,如果你离开并重新加入,你错过了一些消息)和b)在群聊中,'from'通常与'seen'无关,所以'group_id'可以代替'from'。 – Solarflare

+0

而且还有一般性评论:从您的文字描述中去追踪您的设计和您的要求是有点困难的。如果添加一些示例数据(并且您的其他表,特别是组成员表会更好),将会更容易遵循。因为我没有提到它:sql标准定义了它们在mysql中工作的唯一键的行为:如果你在键列中有一个'null',它们并不是唯一的。 – Solarflare

+1

为NULL指定一些重要性,超出缺失值,因此未知值,通常充满了陷阱。这是其中之一。你试图让NULL意味着不同于SQL的意思。 –

我已经用一点点黑客解决了这个问题。当一对一聊天插入chat_seen表时,我首先检查from_user是否为null,因为我允许from_user可以为null(稍后我会解释它)。然后,我有创建from_user和to_id唯一键。现在我有2个唯一键1)from_user和to_id,另一个是2)to_id和group_id(我已从此唯一键删除from_user)。当用户插入chat_seen表与group_chat mod时,我插入null to_user,因为我想忽略1)Uniuqe组的密钥,如果组为null,则表示一对一聊天2)唯一密钥将被忽略。

为来自同一个自动序列发生器的用户分配组的Id字段和Id字段。这保证了给定的Id可以是用户或组,但不能同时为两个。

现在消除到表中的Group_Id。相反,只需将groupId存储在To_Id字段中以获取组消息,并使From_Id和To_Id具有唯一性。

如果您只想查看发送到组的消息,只需加入组表。个人的消息将退出加入。

同样,如果您只想查看给个人的消息,只需加入users表。组的消息将退出加入。

+0

感谢您的回答,我认为这句话可以解决我的问题“为来自同一自动序列发生器的用户分配组的Id字段和用户的Id字段。 ,但有点不清楚,你能否提供一些有关它的细节?这是什么意思“相同的自动序列发生器”。我应该给外钥匙,但我不能给2列外键 – Bucky

+0

我知道如何做到这一点在一些数据库系统,但不是MySQL。我将把它留给mysql用户来帮助你。 –

+0

真正的交易是用户和组都是收件人,但他们在不同的表中。通过使用相同的自动序列,我完全避开了完整的建模答案。它是定义一个收件人表,然后使用共享主键来复制recipientId作为用户标识或组标识。这对你的情况有点矫枉过正。 –