【问题标题】:MySQL REPLACE in an auto incremented rowMySQL REPLACE 在自动递增的行中
【发布时间】:2013-02-19 10:57:30
【问题描述】:

假设我有一个 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 查询获得类似的结果(但不一样)。

为什么它不能是 same 结果?仅仅因为REPLACEDELETE 现有行并将INSERT 一个新行,这将丢失当前primary key 并将增加自动递增 值.相反,在 UPDATE 查询中,primary keyAI 字段将保持不变。

MySQLREPLACE.

【问题讨论】:

  • 我无法理解你的问题。你到底想做什么?
  • @FathahRehmanP 你熟悉 MySQL REPLACE吗?
  • @Mahdi- 请在 REPLACE 查询之前提供表数据,并在 REPLACE 查询之后提供您的预期输出。我会尽力给你解决方案
  • @FathahRehmanP 我已经更新了我的问题 :)
  • 1) 共享正确的表模式。 2)这不是您应该使用替换的方式。 3) 仅当您知道 primary key 值时才使用替换。

标签: mysql replace innodb


【解决方案1】:
  • 这不是您应该使用替换的方式。
  • 仅当您知道 primary key 值时才使用替换。

手册:

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

【讨论】:

  • 如果我们有一个唯一索引,比如列A,我想做REPLACE INTO table` (a, b) VALUES ('A', 'B' )`?这是一个很好的用例吗?
【解决方案2】:

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

考虑添加一个可以匹配并使用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 似乎非常适合快速查找具有少量列(可能只是一个 VARCHAR 字段)的 MyISAM 表。

例如,

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 范围)。

为了更快的速度,在插入之前使用像幽灵哈希这样的小哈希,并将其用于单独的唯一键列,然后 varchar 根本不会被索引。

【讨论】:

  • 另外,请注意:如果忽略插入,则来自 last_insert_id() 的值未定义。因此,您必须在 insert ignore 之后执行 select city_id from cities where city="Los Angeles" 而不是使用它,以确保您获得良好的 ID 值(如果需要)。即便如此,这仍然比ON DUPLICATE KEY UPDATE 快得多,因为(几乎总是)写入比读取慢。 (在 Innodb 上,如果需要,使用事务。)
  • 如果您要投反对票,请添加评论,解释为什么您认为这是一个无效点。
  • 在 Postgresql 中,这称为 UPSERT。
猜你喜欢
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2013-08-27
相关资源
最近更新 更多