MySQL在自动递增的行中进行REPLACE

时间:2013-03-05 06:16:41

标签: mysql replace innodb

假设我有一个包含三列的MySQL表:idab,名为id的列是AUTO INCREMENT字段。如果我将如下所示的查询传递给MySQL,它将正常工作:

REPLACE INTO `table` (`id`, `a`, `b`) VALUES (1, 'A', 'B')

但如果我跳过字段id,它将不再有效,这是预期的。

我想知道ignore查询中是否有REPLACE某些字段的方法。所以上面的查询可能是这样的:

REPLACE INTO `table` (`a`, `b`) VALUES ('A', 'B')

为什么我需要这样的东西?

有时我需要使用SELECT查询来检查数据库,以查看是否存在行。如果它存在,那么我需要UPDATE现有行,否则我需要INSERT一个新行。我想知道我是否可以使用单个REPLACE查询获得类似的结果(但不相同)。

为什么它不能是相同的结果?只是因为REPLACEDELETE现有行并且会INSERT一个新行,这将丢失当前primary key并且会增加自动递增的值。相反,在UPDATE查询中,primary keyAI字段将不受影响。

MySQL REPLACE

2 个答案:

答案 0 :(得分:5)

  • 这不是你应该如何使用替换。
  • 仅在您知道primary key值时才使用替换。

手册:

  

请注意,除非表具有PRIMARY KEY或UNIQUE索引,否则使用   REPLACE语句毫无意义。它等同于INSERT,   因为没有索引可用于确定是否有新行   复制另一个。

答案 1 :(得分:0)

如果您有多个与字段匹配的行,该怎么办?

考虑添加您可以匹配的密钥并使用INSERT IGNORE.. ON DUPLICATE KEY UPDATE。 INSERT IGNORE的工作方式与REPLACE略有不同。

INSERT IGNORE非常快,但可能会产生一些看不见的副作用。

INSERT... ON DUPLICATE KEY UPDATE

副作用较少,但可能要慢得多,特别是对于MyISAM,重写入量或重度索引表。

有关副作用的更多详细信息,请参阅: https://stackoverflow.com/a/548570/1301627

使用INSERT IGNORE似乎适用于具有少量列的快速查找MyISAM表(可能只是一个VARCHAR字段)。

例如,

create table cities (
    city_id int not null auto_increment,
    city varchar(200) not null,
    primary key (city_id),
    unique key city (city))
    engine=myisam default charset=utf8;

insert ignore into cities (city) values ("Los Angeles");

在这种情况下,反复重新插入“Los Angeles”将不会导致对表的任何实际更改,并且将阻止生成新的auto_increment ID,这有助于防止ID字段耗尽(耗尽所有重度搅拌表上的auto_increment范围可用。)

为了获得更高的速度,请在插入之前使用像spooky hash这样的小哈希,并将其用于单独的唯一键列,然后varchar将不会被索引。