MySQl替换为自动增量主键和MUL辅助键

时间:2018-01-26 15:15:11

标签: mysql primary-key auto-increment

我有一个现有的表,我通过一个脚本在一夜之间填充,该脚本读取二进制格式文件并将其转换为replace语句的序列,这些语句通过管道导入mysql。该脚本有一个错误,并在每个二进制文件上循环两次,因此每次发出replace个语句两次。

现在该表具有自动递增的主键,并且替换语句未指定它。我期待得到两个条目(具有不同的整数主键值)。我实际上没有重复。

更多细节:

来自describe a.b

 Field | Type    | Null | Key | Default | Extra
 ------|---------|------|-----|---------|---------------
 id    | int(11) | NO   | PRI | NULL    | auto_increment
 name  | char(8) | YES  | MUL | NULL    |
 date  | date    | YES  |     | NULL    |
 size  | int(11) | YES  |     | NULL    |

示例replace声明

replace into a.b (name,date,size) values ('Joe',20180105,32100);

脚本运行后,我查看表中的条目,并且给定日期的Joe只有一个具有给定大小的条目。 select * from a.b where name='Joe' and date=20180105的结果是:

id     | name | date       | size
-------|------|------------|------
20423  | Joe  | 2018-01-05 | 32100

(而我希望看到另一行有不同的id并且其余列中的值相同。)

我似乎有了我想要的答案,如果脚本运行正常,每个replace语句只会出现一次,但我不明白为什么(因此不要&# 39;完全信任它。)

修改

在回复评论时,这是show index from a.b的结果(当我把它结束时我将基数数字四舍五入):

Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment
------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+--------
b     | 0          | PRIMARY  | 1            | id          | A         | 1000000     | Null     | Null   | YES  | BTREE      |
b     | 0          | n_d      | 1            | name        | A         | 100         | Null     | Null   | YES  | BTREE      |
b     | 0          | n_d      | 2            | date        | A         | 10000       | Null     | Null   | YES  | BTREE      |

所以,我想也许我误解了描述结果中MUL的含义?来自文档:

  

如果Key为MUL,则该列是非唯一索引的第一列,其中允许在列中多次出现给定值。

这是"非独特"在那里让我觉得这并不会导致第二次替换线被杀。是不是只标记name本身没有唯一索引(即使总共n_d索引是唯一的)?

2 个答案:

答案 0 :(得分:1)

我无法重现你的观察结果(无论如何都是在mariadb中)。

MariaDB [sandbox]> drop table if exists t;
Query OK, 0 rows affected (0.07 sec)

MariaDB [sandbox]> create table t
    -> (id    int auto_increment primary key,
    -> name   char(8) null default null,
    -> date   date  null  default null,
    -> size   int  null default null
    -> );
Query OK, 0 rows affected (0.12 sec)

MariaDB [sandbox]> alter table t
    -> add key tk1(name);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> describe t;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
| name  | char(8) | YES  | MUL | NULL    |                |
| date  | date    | YES  |     | NULL    |                |
| size  | int(11) | YES  |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+
4 rows in set (0.02 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> replace t (name,date,size) values ('aaa','2018-01-30',1);
Query OK, 1 row affected (0.00 sec)

MariaDB [sandbox]> replace t (name,date,size) values ('aaa','2018-01-31',2);
Query OK, 1 row affected (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+------+------------+------+
| id | name | date       | size |
+----+------+------------+------+
|  1 | aaa  | 2018-01-30 |    1 |
|  2 | aaa  | 2018-01-31 |    2 |
+----+------+------------+------+
2 rows in set (0.00 sec)

答案 1 :(得分:0)

使用replace时,如果找到重复的行(相同的主键和/或唯一键),则删除现有行并插入新行。所以你不应该看到具有相同值的另一行。如果其他列(主键除外)上有任何唯一键,则会看到找到的结果。由于您没有显示表的键,这只是猜测。

从SQL手册:

  

REPLACE的工作原理与INSERT完全相同,只是如果在一个旧行中   table与PRIMARY KEY或UNIQUE的新行具有相同的值   index,在插入新行之前删除旧行。