我有一个现有的表,我通过一个脚本在一夜之间填充,该脚本读取二进制格式文件并将其转换为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
索引是唯一的)?
答案 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,在插入新行之前删除旧行。