必承其重 | 欲带皇冠 2009-09-01 08:56 采纳率: 0%
浏览 444
已采纳

如何'插入如果不存在'在 MySQL?

I started by googling, and found this article which talks about mutex tables.

I have a table with ~14 million records. If I want to add more data in the same format, is there a way to ensure the record I want to insert does not already exist without using a pair of queries (ie, one query to check and one to insert is the result set is empty)?

Does a unique constraint on a field guarantee the insert will fail if it's already there?

It seems that with merely a constraint, when I issue the insert via php, the script croaks.

转载于:https://stackoverflow.com/questions/1361340/how-to-insert-if-not-exists-in-mysql

  • 写回答

9条回答 默认 最新

  • ~Onlooker 2009-09-01 09:02
    关注

    use INSERT IGNORE INTO table

    see http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html

    there's also INSERT … ON DUPLICATE KEY UPDATE syntax, you can find explanations on dev.mysql.com


    Post from bogdan.org.ua according to Google's webcache:

    18th October 2007

    To start: as of the latest MySQL, syntax presented in the title is not possible. But there are several very easy ways to accomplish what is expected using existing functionality.

    There are 3 possible solutions: using INSERT IGNORE, REPLACE, or INSERT … ON DUPLICATE KEY UPDATE.

    Imagine we have a table:

    CREATE TABLE `transcripts` (
    `ensembl_transcript_id` varchar(20) NOT NULL,
    `transcript_chrom_start` int(10) unsigned NOT NULL,
    `transcript_chrom_end` int(10) unsigned NOT NULL,
    PRIMARY KEY (`ensembl_transcript_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    Now imagine that we have an automatic pipeline importing transcripts meta-data from Ensembl, and that due to various reasons the pipeline might be broken at any step of execution. Thus, we need to ensure two things: 1) repeated executions of the pipeline will not destroy our database, and 2) repeated executions will not die due to ‘duplicate primary key’ errors.

    Method 1: using REPLACE

    It’s very simple:

    REPLACE INTO `transcripts`
    SET `ensembl_transcript_id` = ‘ENSORGT00000000001′,
    `transcript_chrom_start` = 12345,
    `transcript_chrom_end` = 12678;
    

    If the record exists, it will be overwritten; if it does not yet exist, it will be created. However, using this method isn’t efficient for our case: we do not need to overwrite existing records, it’s fine just to skip them.

    Method 2: using INSERT IGNORE Also very simple:

    INSERT IGNORE INTO `transcripts`
    SET `ensembl_transcript_id` = ‘ENSORGT00000000001′,
    `transcript_chrom_start` = 12345,
    `transcript_chrom_end` = 12678;
    

    Here, if the ‘ensembl_transcript_id’ is already present in the database, it will be silently skipped (ignored). (To be more precise, here’s a quote from MySQL reference manual: “If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead. For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted.”.) If the record doesn’t yet exist, it will be created.

    This second method has several potential weaknesses, including non-abortion of the query in case any other problem occurs (see the manual). Thus it should be used if previously tested without the IGNORE keyword.

    There is one more option: to use INSERT … ON DUPLICATE KEY UPDATE syntax, and in the UPDATE part just do nothing do some meaningless (empty) operation, like calculating 0+0 (Geoffray suggests doing the id=id assignment for the MySQL optimization engine to ignore this operation). Advantage of this method is that it only ignores duplicate key events, and still aborts on other errors.

    As a final notice: this post was inspired by Xaprb. I’d also advise to consult his other post on writing flexible SQL queries.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(8条)

报告相同问题?

悬赏问题

  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥200 关于#c++#的问题,请各位专家解答!网站的邀请码
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号