【问题标题】:Make Unique key work with NULL values?使唯一键与 NULL 值一起使用?
【发布时间】:2017-03-19 17:35:03
【问题描述】:

我已经创建了聊天应用程序,它的聊天看到的 sql 如下所示

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

它的工作原理如下:当 group_id 为 NULL 时,表示这是一对一聊天,如果 group_id 不为 null from_user 是写消息的最终用户,to_id 是组成员的用户。我在 group_id 上有外键和它引用组表,我有 3 列的唯一键(from_user,to_id,group_id),当 group_id 为空时它应该工作,因为 from_user 和 to_id 在一对一聊天中应该是唯一的,但在群聊中它应该是每个 group_id 唯一,如果唯一键与 NULL VALUES 一起使用,这将起作用,因为如果它起作用,它将 group_id NULL 值计为 group_id 并且每个 NULL 组 from_user 和 to_id 将是唯一的。我无法将 group_id 更改为任何内容,因为它具有外键。

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

带有示例的更新版本

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

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

【问题讨论】:

  • 那行不通(有充分的理由)。从技术上讲,您可以添加一个带有group_memberid 的新列,并留下to_id``null 用于群聊,然后为两种组合(群聊和1-1-聊天)创建一个唯一键。另一方面,您的设计中可能存在一些问题(虽然我不知道您的数据库,所以这只是一个猜测):a)组成员身份可以更改,因此组表的外键可能不起作用(例如,如果你离开并重新加入,你错过了一些消息)和 b)在群聊中,from 通常与seen 无关,所以可能group_id 代替from
  • 一般性评论:仅从您的文字描述中遵循您的设计和要求有点困难。如果您添加一些示例数据(以及您的其他表,尤其是 group-member-table 会很好),这将更容易遵循。而且因为我没有提到它:sql 标准定义了唯一键的行为,它们在 mysql 中的工作方式:如果您在键列中有 null,它们不是非唯一的。
  • 为 NULL 分配一些意义,超出缺失值,因此未知值,通常充满陷阱。这是其中之一。您试图使 NULL 的含义不同于 SQL 想要的含义。
  • @Solarflare to_id 不会为空,它将是 user_id 应该收到通知。我使用这个系统在新消息到来时通知用户,因为如果新消息到来,用户 unseen_count 应该增加(见更新我突然放之前有消息,但我已修复它是 unseen_count)并且用户应该获得通知计数。
  • @Bucky 我的意思是这样的:to, from, group, from_grp,以及两个唯一键 (to, from)(to, group, from_grp)(或 (from, to)(from, group, to_grp))。根据消息类型,留下fromgroup, from_grp null,然后只有一个唯一键是相关的(因为另一个将包含带有null 的键列,这不会使唯一键失败约束)。至少在技术上。正如我所说,我认为您的数据库设计并不适合这里。

标签: php mysql sql database-design chat


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢你的回答,我认为这句话可以解决我的问题“为组分配Id字段,为来自同一个自动序列生成器的用户分配Id字段。”,但有点不清楚,你能告诉我有关它的详细信息吗? “相同的自动序列生成器”是什么意思。我应该给外键,但我不能给一列提供 2 个外键
  • 我知道如何在某些数据库系统中做到这一点,但不知道 mysql。我会把它留给 mysql 用户来帮助你完成这部分。
  • 真正的交易是用户和组都是收件人,但他们进入不同的表格。通过使用相同的自动序列,我真的回避了完整的建模答案。它是定义一个收件人表,然后使用共享主键将收件人ID复制为用户ID或组ID。在你的情况下,这太过分了。
  • 感谢您的回答,如果我复制它们,我将如何检测它是 user_id 还是 group_id?我已经在 stackoverflow.com/questions/40447156/make-unique-key-work-with-null-values/40449056?noredirect=1#40451013 解决了我的问题
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 2018-10-10
      • 2017-12-07
      • 1970-01-01
      • 2021-10-07
      • 2018-10-02
      相关资源
      最近更新 更多