今天在修复MySQL数据的时候,发现一个看起来“奇怪”的问题。

有一个表里存在一个唯一性索引,这个索引包含3个列,这个唯一性索引的意义就是通过这3个列能够定位到具体1行的数据,但是在实际中却发现这个唯一性索引还是有一个地方可能被大家忽略了。

我们先来看看数据的情况。

CREATE TABLE `test_base_data` (

`servertime` datetime DEFAULT NULL COMMENT '时间',

`appkey` varchar(64) DEFAULT NULL,

...

`timezone` varchar(50) DEFAULT NULL COMMENT '时区',

UNIQUE KEY `servertime_appkey_timezone` (`servertime`,`appkey`,`timezone`),

KEY `idx_ccb_r_b_d_ak_time` (`servertime`,`appkey`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

表里的数据量在300万左右

> select count(*)from test_base_data;

+----------+

| count(*) |

+----------+

|  3818630 |

+----------+

我在分析一个问题的时候,发现按照目前的情况,似乎主键和唯一性索引有一点差别(当然回过头来看这个问题本身就很明确了)。

于是我尝试删除这个唯一性索引,转而创建一个主键,但是这个操作竟然抛出了数据冲突的的错误。

> alter table test_base_data add primary key `servertime_appkey_timezone` (`servertime`,`appkey`,`timezone`);

ERROR 1062 (23000): Duplicate entry '2017-05-09 13:15:00-1461048746259-' for key 'PRIMARY'

数据按照appkey 1461048746259来过滤,得到的一个基本情况如下:

> select servertime,appkey,timezone from ccb_realtime_base_data limit 5;

+---------------------+---------------+----------+

| servertime          | appkey        | timezone |

+---------------------+---------------+----------+

| 2017-05-09 20:25:00 | 1461048746259 | NULL     |

| 2017-05-09 13:15:00 | 1461048746259 | NULL     |

| 2017-05-09 19:00:00 | 1461048746259 | NULL     |

| 2017-05-09 17:00:00 | 1461048746259 | NULL     |

| 2017-05-09 20:30:00 | 1461048746259 | NULL     |

+---------------------+---------------+----------+

单纯这样看,看不出什么问题来,但是当我有count来得到重复数据的时候,着实让我惊呆了。

> select count(1) from ccb_realtime_base_data where servertime ='2017-05-09 13:15:00' and appkey='1461048746259';

+----------+

| count(1) |

+----------+

|      709 |

+----------+

这一行记录,在这个表里竟然有重复的数据达到700多个。

按照这个情况,表里的数据缺失有大的问题,但是为什么唯一性索引就查不出来呢。

这一点上,Oracle和MySQL的立场是一致的,那就是主键和唯一性索引的差别,出了主键的根红苗正,主键是唯一性索引的一种之外,还有一点很重要,我们掰开了揉碎了来说。

为了方便演示,我就创建一个简单的表unique_test\create table unique_test(id int,name varchar(30))

添加唯一性约束

alter table unique_test add unique key(id);

插入1行数据

insert into unique_test values(1,'aa');

再插入1行,毫无疑问会抛出错误。

insert into unique_test values(1,'aa');

ERROR 1062 (23000): Duplicate entry '1' for key 'id'

我们删除原来的索引,创建一个新的索引,基于列(id,name)

alter table unique_test drop index id;

alter table unique_test add unique key (id,name);

创建新的索引

> insert into unique_test values(1,'aa');

ERROR 1062 (23000): Duplicate entry '1-aa' for key 'id'

可见唯一性约束是生效了,插入不冲突的数据没有任何问题。

insert into unique_test values(1,'bb');

所以这样来看,多个键值列也都能校验出来嘛,我们再建一个列,创建一个复合索引,含有3个列。

> alter table unique_test drop index id

创建一个列created,换个数据类型。

> alter table unique_test add column created datetime;

创建唯一性索引,基于3个列。

> alter table unique_test add unique key(id,name,created);

这个时候模拟一下数据

> insert into unique_test values(1,'aa',null);

这个时候问题就很明显了,竟然校验不出来了。

> select *from unique_test;

+------+------+---------+

| id   | name | created |

+------+------+---------+

|    1 | aa   | NULL    |

|    1 | aa   | NULL    |

|    1 | bb   | NULL    |

+------+------+---------+

3 rows in set (0.00 sec)

这问题在哪儿呢。

我们来看看create table的语句。

> show create table unique_test;

+-------------+-------------------------------------

| Table       | Create Table                                                                                        |

+-------------+--------------------------------------

| unique_test | CREATE TABLE `unique_test` (

`created` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

+-------------+---------------------------------------我就把问题点透,就在哪个null的地方上,这个是这个问题的根本,进一步来说,这个是唯一性索引和主键的一个差别,那就是主键约束相比唯一性约束来说,还有一个默认的属性,那就是not null

但是同样都是null的差别,MySQL和Oracle的结果是否相同呢。我们来测试一下。顺便熟悉一下两种数据库的语法风格。

在Oracle里面,代表的含义是不同的,大大不同,可以看看下面的结果来对比一下。

SQL> create table unique_test(id number,name varchar2(30));

Table created.

SQL> alter table unique_test add constraint uq_test unique(id);

Table altered.

SQL> insert into unique_test values(1,'a');

1 row created.

SQL> /

insert into unique_test values(1,'a')

*

ERROR at line 1:

ORA-00001: unique constraint (PDB_MGR.UQ_TEST) violated

SQL> alter table unique_test drop constraint uq_test;

Table altered.

SQL> alter table unique_test add constraint uq_test unique(id,name);

Table altered.

SQL> insert into unique_test values(2,'bb');

1 row created.

SQL> commit;

SQL> alter table unique_test drop constraint uq_test;

SQL> alter table unique_test add created date;

SQL> alter table unique_test add constraint uq_test unique(id,name,created);

Table altered.

SQL>  insert into unique_test values(1,'a',null);

insert into unique_test values(1,'a',null)

*

ERROR at line 1:

ORA-00001: unique constraint (PDB_MGR.UQ_TEST) violated

SQL>  insert into unique_test values(2,'bb',null);

insert into unique_test values(2,'bb',null)

*

ERROR at line 1:

ORA-00001: unique constraint (PDB_MGR.UQ_TEST) violated

oracle索引与mysql区别_MySQL和Oracle中的唯一性索引从差别(r12笔记第83天)相关推荐

  1. oracle索引与mysql区别_Mysql和ORACLE索引的实现方式

    B-Tree和B+Tree 目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构. 首先,对单个节点来说,是一个key value结构,key是作引的列,value有两种, ...

  2. SQLplus 和mysql区别_mysql和oracle的区别有哪些

    MySQL和Oracle都是流行的关系数据库管理系统(RDBMS),在世界各地广泛使用:大多数数据库以类似的方式工作,但MySQL和Oracle的这里和那里总是存在一些差异的.本篇文章就给大家比较Or ...

  3. mysql $区别_mysql 与oracle区别

    http://blog.csdn.net/huanghm88/article/details/8009048 本章来源 http://www.jb51.net/article/34414.htm 其他 ...

  4. 索引视图是否物理存储在数据库中以及使用索引视图的一些见解

    索引视图是否物理存储在数据库中以及使用索引视图的一些见解 前言 这个话题我本来是写在文章里没有写在随笔里的,不过赶脚不写在随笔里其他人就看不到了,因为小弟对视图的认识不深 希望写在随笔里让大家也讨论一 ...

  5. oracle 和mysql有什么区别_mysql和oracle的区别有哪些

    原标题:mysql和oracle的区别有哪些 MySQL和Oracle都是流行的关系数据库管理系统(RDBMS),在世界各地广泛使用:大多数数据库以类似的方式工作,但MySQL和Oracle的这里和那 ...

  6. oracle可以迁徙mysql吗_项目oracle迁徙到mysql的小总结

    项目oracle迁移到mysql的小总结 1.更新表的不同 oracle update IP_GN_BAXX_GBXX_LS SJXT_ID = #provinceSystemId# JLID = # ...

  7. 影响索引的mysql函数_mysql索引对排序的影响实例分析

    本文实例讲述了mysql索引对排序的影响.分享给大家供大家参考,具体如下: 索引不仅能提高查询速度,还可以添加排序速度,如果order by 后面的语句用到了索引,那么将会提高排序的速度. 测试 1. ...

  8. mysql索引缓存的内容_mysql服务器变量、缓存及索引

    服务器变量 注意:其中有些参数支持运行时修改,会立即生效:有些参数不支持,且只能通过修改配置文件,并重启服务器程序生效:有些参数作用域是全局的,且不可改变:有些可以为每个用户提供单独(会话)的设置. ...

  9. oracle中句柄,释放句柄 – 提供7*24专业数据库(Oracle,SQL Server,MySQL等)恢复和Oracle技术服务@Tel:+86 13429648788 - 惜分飞...

    在很多时候,检查系统时候发现,由于某个Oracle的trace文件导致磁盘空间告警,因为业务需要不能让数据库down下来.这个时候你想到的方法可能是直接删除掉这个trace文件,如果是win系统,那恭 ...

最新文章

  1. Python_note2 基本图形绘制+turtle库使用
  2. Python中列表的介绍以及常见操作
  3. 堆和栈的联系与区别(转贴)
  4. P2710-数列【Splay】
  5. mysql与mssql中datetime类型字段问题_excel数据存入sqlserver过程中,遇到Datetime的格式问题。...
  6. 计算机选配 注意事项,选择鼠标注意事项有哪些
  7. 2月第三周各国家.NET域名排名Top10:中国第三
  8. Scientific Linux 6.4安装详程
  9. Android的Service组件
  10. 在php中使用for、while、do-while循环实现从1加到100
  11. Excel如何快速根据身份证号码计算周岁?
  12. gif透明背景动画_如何利用premiere制作GIF动态图片
  13. 如何用友远程到服务器,怎么安装用友T3远程通
  14. ZUI框架加上Flex布局构建登录后的主页
  15. 二级路由器的设置上网
  16. 搜狗输入法皮肤编辑器(“用户账户不存在: 解压缩失败 皮肤解压失败:skin.ini不存在……”)
  17. 清除IE浏览器SSL缓存
  18. Chrome 灵魂插件!
  19. LeetCode 刷题记录 77. Combinations
  20. 闲话设计模式之建造者模式

热门文章

  1. PCA、碎石图、PCA+正确的维度个数、增量PCA(IncrementalPCA)、随机PCA(Randomized PCA)、KernelPCA
  2. Bowtie下载安装
  3. linux系统/etc目录内容简介
  4. 免安装的mysql删除_MySQL5.7 免安装版配置及删除图文教程
  5. java迭代器创建后mutx锁,多线程编程(10) - 多线程同步之 Mutex (互斥对象)
  6. flask_sqlalchemy 教程
  7. 【英文文本分类实战】之三——数据清洗
  8. OverFeat:Integrated Recognition, Localization and Detection using Convolutional Networks
  9. LeetCode 53. Maximum Subarray--动态规划--C++,Python解法
  10. 解决一个坑爹的mininet的pingall失败的问题(自己编译安装openvswitch后)