使用唯一键时重复数据

发布于 2024-12-02 21:31:41 字数 6239 浏览 4 评论 0原文

对于我的表,我在 activity_id-actor_id-end_date 上定义了唯一索引;

mysql> show keys from sg_activity_property;
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table                | Non_unique | Key_name    | Seq_in_index | Column_name          | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
| sg_activity_property |          0 | PRIMARY     |            1 | activity_property_id | A         |         506 |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            1 | activity_id          | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            2 | actor_id             | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            3 | end_date             | A         |        NULL |     NULL | NULL   | YES  | BTREE      |         |
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.00 sec)

那么,这些数据怎么可能存在呢?

mysql> SELECT activity_property_id, activity_id, actor_id, start_date, end_date FROM  `sg_activity_property` WHERE  `activity_id` =250;
+----------------------+-------------+----------+---------------------+----------+
| activity_property_id | activity_id | actor_id | start_date          | end_date |
+----------------------+-------------+----------+---------------------+----------+
|                  509 |         250 |        8 | 2011-09-02 11:10:50 | NULL     |
|                  510 |         250 |        8 | 2011-09-02 11:10:50 | NULL     |
+----------------------+-------------+----------+---------------------+----------+
2 rows in set (0.00 sec)

编辑:这是SHOW CREATE TABLE sg_activity_property的输出:

mysql> SHOW CREATE TABLE sg_activity_property;
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| sg_activity_property | CREATE TABLE `sg_activity_property` (
  `activity_property_id` int(10) unsigned NOT NULL auto_increment,
  `activity_id` int(10) unsigned NOT NULL,
  `actor_id` int(10) unsigned NOT NULL,
  `importance` enum('very low','low','normal','high','very high') NOT NULL default 'normal',
  `urgency` enum('!','!!') default NULL,
  `completed` tinyint(1) NOT NULL,
  `start_date` datetime NOT NULL,
  `end_date` datetime default NULL,
  `review_frequency` int(11) NOT NULL default '1',
  `review_frequency_unit` enum('day','week','month','quarter','year') NOT NULL default 'week',
  PRIMARY KEY  (`activity_property_id`),
  UNIQUE KEY `activity_id` (`activity_id`,`actor_id`,`end_date`)
) ENGINE=MyISAM AUTO_INCREMENT=511 DEFAULT CHARSET=latin1 |
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.19 sec)

For my table I've defined a unique index on activity_id-actor_id-end_date;

mysql> show keys from sg_activity_property;
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table                | Non_unique | Key_name    | Seq_in_index | Column_name          | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
| sg_activity_property |          0 | PRIMARY     |            1 | activity_property_id | A         |         506 |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            1 | activity_id          | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            2 | actor_id             | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
| sg_activity_property |          0 | activity_id |            3 | end_date             | A         |        NULL |     NULL | NULL   | YES  | BTREE      |         |
+----------------------+------------+-------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.00 sec)

So, how can this data exist??

mysql> SELECT activity_property_id, activity_id, actor_id, start_date, end_date FROM  `sg_activity_property` WHERE  `activity_id` =250;
+----------------------+-------------+----------+---------------------+----------+
| activity_property_id | activity_id | actor_id | start_date          | end_date |
+----------------------+-------------+----------+---------------------+----------+
|                  509 |         250 |        8 | 2011-09-02 11:10:50 | NULL     |
|                  510 |         250 |        8 | 2011-09-02 11:10:50 | NULL     |
+----------------------+-------------+----------+---------------------+----------+
2 rows in set (0.00 sec)

Edit: here's the output of SHOW CREATE TABLE sg_activity_property:

mysql> SHOW CREATE TABLE sg_activity_property;
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table                | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| sg_activity_property | CREATE TABLE `sg_activity_property` (
  `activity_property_id` int(10) unsigned NOT NULL auto_increment,
  `activity_id` int(10) unsigned NOT NULL,
  `actor_id` int(10) unsigned NOT NULL,
  `importance` enum('very low','low','normal','high','very high') NOT NULL default 'normal',
  `urgency` enum('!','!!') default NULL,
  `completed` tinyint(1) NOT NULL,
  `start_date` datetime NOT NULL,
  `end_date` datetime default NULL,
  `review_frequency` int(11) NOT NULL default '1',
  `review_frequency_unit` enum('day','week','month','quarter','year') NOT NULL default 'week',
  PRIMARY KEY  (`activity_property_id`),
  UNIQUE KEY `activity_id` (`activity_id`,`actor_id`,`end_date`)
) ENGINE=MyISAM AUTO_INCREMENT=511 DEFAULT CHARSET=latin1 |
+----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.19 sec)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无远思近则忧 2024-12-09 21:31:41

这是预期的行为。查看MySQL文档:
http://dev.mysql.com/doc/refman/5.0 /en/create-table.html

UNIQUE 索引创建一个约束,使得索引中的所有值
必须是独特的。如果您尝试添加带有以下内容的新行,则会发生错误
与现有行匹配的键值。此限制不适用
为 NULL 值(BDB 存储引擎除外)。对于其他发动机,
UNIQUE 索引允许列有多个 NULL 值,这些值可以包含
空。

This is the expected behavior. Check the MySQL documentation:
http://dev.mysql.com/doc/refman/5.0/en/create-table.html

A UNIQUE index creates a constraint such that all values in the index
must be distinct. An error occurs if you try to add a new row with a
key value that matches an existing row. This constraint does not apply
to NULL values except for the BDB storage engine. For other engines, a
UNIQUE index permits multiple NULL values for columns that can contain
NULL.

灼疼热情 2024-12-09 21:31:41

由于 end_date 上的 NULL
从技术上讲,NULL <> EMPTY 或任何值只是一个缺少值的占位符,

因此,将其更改为 NOT NULL 应该修复

PS: 当您执行更改时

alter table sg_activity_property 
modify column end_date datetime not null
default '0000-00-00 00:00:00';

,此操作将失败,因为 mysql 会尝试将 NULL 转换为 <代码>0000-00-00 00:00:00,
为了解决这个问题,您可以先为其分配一些随机值,
或者只是简单地删除重复项之一

because of the NULL on end_date,
technically NULL <> EMPTY, or any value, is just a placeholder where value is missing

so, change it to NOT NULL should fix

PS: when you doing alter

alter table sg_activity_property 
modify column end_date datetime not null
default '0000-00-00 00:00:00';

this will fail, because mysql will attempt to convert the NULL to 0000-00-00 00:00:00,
in order to fix this, you can either assign some random value to it first,
or just simply remove one of the duplicate

廻憶裏菂餘溫 2024-12-09 21:31:41

end_date 中有 NULL 值。

NULL 值是未定义的值,因此有两个
NULL 值并不相同。

You have NULL values in end_date.

A NULL value is an undefined value, therefore two
NULL values are not the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文