ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

20220 단어 errordup106223000
1. 버전
1) 운영 체제
cat/etc/issue CentOS release 6.6 (Final) Kernel\r on an\m
 cat/proc/version Linux version 2.6.32-504.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) #1 SMP Wed Oct 15 04: 27:16 UTC 2014 2) mysql 데이터베이스 버전
R&D 테스트 환경 5.1.73
비즈니스 환경 5.6.26
2. 질문
연구 개발한 형제가 오늘 와서 나에게 5.1.73의 테스트 환경에서 아래의 문장을 반복해서 집행할 수 있다고 반영하였다
###여기서 meclassid열은 자증열입니다
그러나 상업적 환경(5.6.26)에서 실행할 때 두 번째 실행하면 다음과 같은 오류를 보고한다(솔직히 말하면 나는 이런 쓰기 방법을 처음 본다. 일반적으로 auto increment열을 지정하지 않거나null값으로 지정한다)
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
  t_meclass 테이블은 다음과 같이 정의됩니다.
CREATE TABLE `t_meclass` (
  `meclass_id` bigint(20) not NULL AUTO_INCREMENT COMMENT '    ',
  `meclass_name` varchar(100) DEFAULT NULL COMMENT '    ',
  `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
  `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
  `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
  `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
  `state` bigint(20) NOT NULL DEFAULT '0',
  `type` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`meclass_id`)
) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   '; 

5.6.26에서 다음을 반복합니다.
mysql> insert into t_meclass set meclass_id = default ,meclass_name='XXXX APP(    1100)',meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.01 sec)

mysql> select * from t_meclass;
+------------+----------------------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name               | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+----------------------------+--------------+----------+-------------+------------------+-------+-------+
|          0 | XXXX APP(    1100)     |              | 53453792 |  1446625414 |       1446625414 |     0 | 20000 |
+------------+----------------------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> insert into t_meclass set meclass_id = default ,meclass_name='XXXX APP(    1100)',meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
mysql> 
첫 번째 실행 후 meclassid열에 삽입된 값은 0입니다. 두 번째 실행은 0입니다. 따라서 메인 키가 충돌합니다.
3. 솔루션
mysql(5.6.26) 공식 문서에서 autoincrement 섹션에서 다음 문제와 관련된 부분을 캡처합니다.
 NO_AUTO_VALUE_ON_ZERO

NO_AUTO_VALUE_ON_ZERO affects handling of AUTO_INCREMENT columns. Normally, you generate the next sequence number for the column by inserting either NULL or 0 into it. NO_AUTO_VALUE_ON_ZERO suppresses this behavior for 0 so that only NULL generates the next sequence number.<pre name="code" class="html"><span style="color:#ff6666;">>>NO_AUTO_VALUE_ON_ZERO     AUTO_INCREMENT 。               null   0 ,                  。    sql_mode   NO_AUTO_VALUE_ON_ZERO,       0                 ,      0,     null            。</span>
This mode can be useful if 0 has been stored in a table's AUTO_INCREMENT column. (Storing 0 is not a recommended practice, by the way.) For example, if you dump the table with mysqldump and then reload it, MySQL normally generates new sequence numbers when it encounters the 0 values, resulting in a table with contents different from the one that was dumped. Enabling NO_AUTO_VALUE_ON_ZERO before reloading the dump file solves this problem. mysqldump now automatically includes in its output a statement that enables NO_AUTO_VALUE_ON_ZERO, to avoid this problem.>>만약 0값이 자증열에 저장되어 있다면, 이 sql 을 설정하십시오mode는 유용합니다. (참고로 자증열에 0값을 저장하는 것을 권장하지 않습니다.) 예를 들어 mysqldump를 사용하여 테이블을 내보낸 다음 다른 라이브러리로 가져옵니다. 가져올 때 자증열이 0값일 때 시퀀스 값을 생성합니다. 이로 인해 이 테이블은 원래의 테이블 내용과 일치하지 않습니다.가져오기 전에 NO 사용 가능AUTO_VALUE_ON_ZERO는 이 문제를 피합니다.이제 mysqldump 내보내기 파일에는 NO 활성화가 자동으로 포함됩니다.AUTO_VALUE_ON_제로 씨, 이 문제를 피하세요.
 ##通过上面官方文档描述可以,在sql_mode中去掉NO_AUTO_VALUE_NO_ZERO应该就没有问题了,后来再商用环境上,调整sql_mode后问题解决(其实最根本的解决方法,还是需要研发修改他们的代码) 
 
  

好了看完了官方文档 再来看看我们研发遇到的问题:

1)查看重复执行报错的 5.6.26数据库的sql_mode

mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                |
+---------------+--------------------------------------------------------------------------------------+
| sql_mode      | NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------------------------------------------------+

2) 우리는 sql 을 보았다mode에 NO 이 포함되어 있음AUTO_VALUE_ON_ZERO, 이것은 auto로 간주됨increment 열이 0 값을 만났을 때 자동 증가 시퀀스 값이 생성되지 않고 0 값이 삽입됩니다
3) 그 문제는 우리가default값을 삽입했는데 어떻게 0값이 되었는가?이 문제에 관하여 나는 다음과 같은 실험을 했다.
1.sql_mode='NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 때
mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                |
+---------------+--------------------------------------------------------------------------------------+
| sql_mode      | NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> drop table test3;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE `test3` (
    ->   `meclass_id` bigint(20) not NULL COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`meclass_id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   '; 
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test3 set meclass_id = default ,meclass_name=default ,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
ERROR 1364 (HY000): Field 'meclass_id' doesn't have a default value  <span style="color:#ff0000;">>> sql_mode  STRICT_TRANS_TABLES ,    not null,          default,   </span>
mysql> drop table test3;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `test3` (
    ->   `meclass_id` bigint(20) COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`meclass_id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   ';  
Query OK, 0 rows affected (0.05 sec)

mysql> insert into test3 set meclass_id = default ,meclass_name=default ,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.00 sec)  <span style="color:#ff0000;">>> sql_mode  STRICT_TRANS_TABLES ,       not null  ,         default,       ,meclass_id(  )     0,meclass_name     null</span>

mysql> select * from test3;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|          0 | NULL         |              | 53453792 |  1446630357 |       1446630357 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> drop table test3;
Query OK, 0 rows affected (0.07 sec)

mysql> CREATE TABLE `test3` (
    ->   `meclass_id` bigint(20) COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0'
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   ';
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test3 set meclass_id = default ,meclass_name=default ,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.03 sec) <span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">>> sql_mode  STRICT_TRANS_TABLES ,       not null  ,         default,       ,meclass_id(   )     null,meclass_name     null.(               meclass_id        )</span>


mysql> select * from test3;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|       NULL | NULL         |              | 53453792 |  1446630887 |       1446630887 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> drop table test3;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE `test3` (
    ->   `meclass_id` bigint(20) not NULL AUTO_INCREMENT COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`meclass_id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   ';
Query OK, 0 rows affected (0.02 sec)

mysql> insert into test3 set meclass_id = default ,meclass_name=default ,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.01 sec) <span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">>> sql_mode  STRICT_TRANS_TABLES ,      not null  ,    AUTO_INCREMENT,         default,       ,meclass_id(  )     null,meclass_name     null.(      meclass_id  auto_increment     not null  ,  default       )</span>


mysql> select * from test3;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|          0 | NULL         |              | 53453792 |  1446631037 |       1446631037 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> insert into test3 set meclass_id = default ,meclass_name=default ,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'  <span style="color:#ff0000;">>>                 0,       </span>
mysql> 

sqlmode=이 비어 있을 때 다음 테스트를 수행합니다.
mysql> show variables like 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |   <span style="color:#ff0000;">>>sql_mode  </span>
+---------------+-------+
1 row in set (0.00 sec)

mysql> drop table test5;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE `test5` (
    ->   `meclass_id` bigint(20) not null COMMENT '    ',
    ->   `meclass_name` varchar(100) not NULL COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`meclass_id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   '; 
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test5 set meclass_id = default ,meclass_name=default,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected, 2 warnings (0.00 sec)  <span style="color:#ff0000;">>> sql_mode   ,        not null,        default,          default  warning,  meclass_id     0,meclass_name      </span>

mysql> show warnings;
+---------+------+---------------------------------------------------+
| Level   | Code | Message                                           |
+---------+------+---------------------------------------------------+
| Warning | 1364 | Field 'meclass_id' doesn't have a default value   |
| Warning | 1364 | Field 'meclass_name' doesn't have a default value |
+---------+------+---------------------------------------------------+
2 rows in set (0.00 sec)

mysql> select * from test5;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|          0 |              |              | 53453792 |  1446633043 |       1446633043 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> CREATE TABLE `test5` (
    ->   `meclass_id` bigint(20) COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0'
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   '; 
Query OK, 0 rows affected (0.06 sec)

mysql> insert into test5 set meclass_id = default ,meclass_name=default,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.00 sec)  <span style="color:#ff0000;">>>sql_mode   ,     not null  ,   default ,            default,    ,   meclass_id  null,meclass_name  null(          ,       not null,  meclass_name         )##    not null           null</span>

mysql> 
mysql> select * from test5;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|       NULL | NULL         |              | 53453792 |  1446633290 |       1446633290 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

mysql> drop table test5;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE `test5` (
    ->   `meclass_id` bigint(20) not NULL AUTO_INCREMENT COMMENT '    ',
    ->   `meclass_name` varchar(100) COMMENT '    ',
    ->   `meclass_desc` varchar(255) DEFAULT NULL COMMENT '    ',
    ->   `property` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '    ',
    ->   `last_update_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '      ',
    ->   `state` bigint(20) NOT NULL DEFAULT '0',
    ->   `type` bigint(20) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`meclass_id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=303903 DEFAULT CHARSET=utf8 COMMENT='   ';
Query OK, 0 rows affected (0.05 sec)

mysql> insert into test5 set meclass_id = default ,meclass_name=default,meclass_desc='',property=53453792,type=20000,create_time= unix_timestamp(now()),last_update_time=unix_timestamp(now()),state=0;
Query OK, 1 row affected (0.00 sec) <span style="color:#ff0000;">>>sql_mode 0 ,        not null  auto_increment,        default,    ,meclass_id     auto_increment   ,meclass_name     null</span>

mysql> 
mysql> select * from test5;
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
| meclass_id | meclass_name | meclass_desc | property | create_time | last_update_time | state | type  |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
|     303903 | NULL         |              | 53453792 |  1446633360 |       1446633360 |     0 | 20000 |
+------------+--------------+--------------+----------+-------------+------------------+-------+-------+
1 row in set (0.00 sec)

좋은 웹페이지 즐겨찾기