MySQL 小心使用 replace into【转】

  • 来源:本站
  • 发布时间:2019-08-13
  • 8已阅读
您现在的位置:首页 >> 现代文学 >> 文章
简介 MySQLreplaceinto错误案例背景**ROW模式*表结构CREATETABLE`test`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`col

	MySQL 小心使用 replace into【转】

MySQLreplaceinto错误案例背景**ROW模式*表结构CREATETABLE`test`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`col_1`varcMySQLreplaceinto错误案例背景*MySQL5.*ROW模式*表结构CREATETABLE(()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBDEFAULTCHARSET=utf8错误场景一其他字段value莫名其妙的没了lcREPLACEINTOtest(col_1,col_2,col_3)values(,,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录lcREPLACEINTOtest(col_1,col_2,col_3)values(,,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录lcREPLACEINTOtest(col_1,col_2,col_3)values(,,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录mastershowcreatetabletestCREATETABLE(int()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBAUTO_INCREMENT=DEFAULTCHARSET=utf8idcol_2+----+-------+-------+-------+aabccset()lcreplaceintotest(col_1,col_2)values(,);QueryOK,rowsaffected(.sec)lcselect*fromtest;+----+-------+-------+-------+col_1col_3abbcc+----+-------+-------+-------+rowsset(.sec)col_3的值,从原来的c,变成了NULL,天呐,数据不见了。 id也变了。 用户原本的需求,应该是如果col_1=c存在,那么就改变col_2=cc,其余的记录保持不变,结果id,col_3都变化了解决方案就是:将replaceinto改成INSERTINTOONDUPLICATEKEYUPDATE但是你以为这样就完美的解决了吗?马上就会带来另外一场灾难,请看下面的错误场景错误场景二ERROR1062(23000):DuplicateentryxforkeyPRIMARYmater:REPLACEINTOtest(col_1,col_2)(,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录master:REPLACEINTOtest(col_1,col_2)(,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录master:REPLACEINTOtest(col_1,col_2)(,);QueryOK,rowaffected(.sec)--注意,这里是影响了条记录mastershowcreatetabletest|test|CREATETABLE(()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBAUTO_INCREMENT=DEFAULTCHARSET=utf8|slaveshowcreatetabletest|test|CREATETABLE(()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBAUTO_INCREMENT=DEFAULTCHARSET=utf8|*masterlcREPLACEINTOtest(col_1,col_2)values(,);QueryOK,rowsaffected(.sec)--注意,这里是影响了两条记录lcshowcreatetabletestCREATETABLE(int()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBAUTO_INCREMENT=DEFAULTCHARSET=utf8idcol_2abccset()*slaveslave:lcshowcreatetabletest|testlcselect*fromtest+----+-------+-------+col_1+----+-------+-------+abc+----+-------+-------+rowsset(.sec)*假设有一天,master挂了,由slave提升为newmater原slave:showcreatetabletest|test|CREATETABLE(()unsignedNOTNULLAUTO_INCREMENT,varchar()DEFAULTNULL,varchar()DEFAULTNULL,PRIMARYKEY(),UNIQUEKEY())ENGINE=InnoDBAUTO_INCREMENT=DEFAULTCHARSET=utf8|原slave:*fromtest+----+-------+-------+|id|col_1|col_2|+----+-------+-------+||a|a|||b|b|||c|cc|+----+-------+-------+rowsinset(.sec)===注意==root:REPLACEINTOtest(col_1,col_2)(,);ERROR():DuplicateentrykeyRow模式,主从情况下,replaceinto和INSERTINTOONDUPLICATEKEYUPDATE都会导致以上问题的发生解决方案:最后可以通过altertableauto_increment值解决,但是这样已经造成mater的表很长时间没有写入了。

。 。

最后总结1.禁止(错误一,错误二都会发生)禁止(错误二会发生)1.禁止(会发生错误场景一的案例,丢失部分字段数据)可以使用代替postedon2018-12-2519:19阅读(71)所属分类:。