仅当第二列是特定值时,MySQL才有两列唯一约束

时间:2017-10-27 00:10:45

标签: mysql triggers constraints unique

您好我有一个MysQL表,我在其中保存客户端

在一栏中,我保存了IP地址,

在其他列中,我设置客户端是否为活动状态 我也保存姓名,邮件等......

如果有一个客户离开,我们只需将活动列设置为0,(保持付款历史记录等),当新客户端到达时我们可以重新分配相同的IP

有没有办法创建一个UNIQUE约束来只允许一个活动的IP?

例如

IP    |   ACTIVE  |   DATE
---------------------------------
102   |      1    |    2017-10-12
103   |      1    |    2017-10-12
103   |      0    |    2017-10-13
103   |      0    |    2017-10-09

所以它可以是带有IP和0的行的倍数,但只有一个带有IP和1

我正在考虑INSERT,UPDATE之前执行SELECT的触发器,并验证是否没有其他行具有该IP和1在ACTIVE中

建议?

2 个答案:

答案 0 :(得分:1)

备选方案1

不是使用0表示不活跃,为什么不使用负数?这样,你可以保持IP / Active列对的唯一性,只有Active = 1的记录才会被认为是活动的。我不确定你的逻辑在激活方面是什么,但实质上,你只会选择一个小于现有的第一个负数(或-1,如果它是第一个)来更新记录。

备选方案2

完全取消Active列,并创建另一个表来保存IP历史记录。所以...在主表中,唯一性约束在IP地址上。在历史记录表中,您可以对IP地址及其成为历史记录的日期具有唯一性约束。

修改

根据@MichelFeldheim的评论,我建议您将用户电子邮件地址作为唯一性约束的一部分。基本上意味着每个唯一用户将被允许一个活动IP地址。它还允许每个IP地址(或组织,例如)有多个活动用户。

答案 1 :(得分:0)

使用值1NULL代替10

然后,您可以向表中添加UNIQUE KEY (ip, active),并且每个IP组合只允许一行值为1,但NULL的无限行不会违反唯一约束。

请注意,NULL = NULL 为真,因为NULL 不是一个值。它是表示缺少价值的标记。两个不存在的值不能说是相同的,因此NULL的{​​{1}}的多行不会被视为重复,因此它们不会违反唯一约束。

除此之外:注意到ip不正确,如上所述,同样重要的是要注意,它也不是假的。同样地,NULL = NULL既不是真也不是假,因为 - 根据定义 - 缺乏价值不能与任何事物进行比较,包括另一个缺乏价值。