【问题标题】:Duplicate data while using a unique key使用唯一键时重复数据
【发布时间】:2011-09-02 09:22:53
【问题描述】:

对于我的表,我在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)

【问题讨论】:

  • 我们可以得到SHOW CREATE TABLE sg_activity_property的输出吗?
  • 将输出添加到帖子中!

标签: mysql database unique-key


【解决方案1】:

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

一个 UNIQUE 索引创建一个约束,使得索引中的所有值 必须是不同的。如果您尝试添加一个带有 与现有行匹配的键值。此约束不适用 除 BDB 存储引擎外,为 NULL 值。对于其他发动机,一个 UNIQUE 索引允许包含多个 NULL 值的列 空。

【讨论】:

  • 感谢您的有用评论。我从没想过 NULL 会在 MySQL 索引中被“跳过”!
【解决方案2】:

因为 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
为了解决这个问题,您可以先为其分配一些随机值,
或者只是简单地删除其中一个重复项

【讨论】:

  • 不幸的是,我在这里需要NULL,因为我用它来查找“当前”条目(WHERE end_date IS NULL
  • 您可以随时将其转换为WHERE end_date=0
  • 表现是否同样出色?
  • 真的吗?那我马上改。可惜我必须编辑我的所有查询......(:
【解决方案3】:

end_date 中有 NULL 值。

NULL 值是一个未定义的值,因此有两个 NULL 值不一样。

【讨论】:

  • 两个NULL值不一样??这完全让我感到困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2014-01-12
  • 2023-02-16
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
相关资源
最近更新 更多