mysql数据库,如何理解replace into智能插入或更新语句?
发布于 作者:苏南大叔 来源:程序如此灵动~在日常编程中,经常会出现判断id
是否存在,进而调用insert
还是update
的场景。这里一般情况下,都是要走个流程分支的。如果从mysql
数据库角度上来解决这个需求的话,倒是有个简单的方法,那就是replace into
语句,一句话就可以搞定这个需要走分支的需求。
大家好,这里是苏南大叔的程序如此灵动博客,记录苏南大叔的代码经验感悟。本文测试环境:win10
,mysql@5.6.27
。
replace into
测试一(主键id
)
经常会有数据更新的场景,表单完全一致,是不过一个是新建数据,使用insert into
语句。而另外一个是数据更新,使用update xxx set
语句。两者的区别仅仅在于主键id
不同。
测试用数据表表结构如下:
DROP TABLE IF EXISTS `users3`;
CREATE TABLE `users3` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`department` varchar(50) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `users3` VALUES (1,'技术部','苏南大叔','11111'),(2,'国际部','苏南大叔','22222'),(3,'后勤部','sunan大叔','33333');
值得说明的是:对于本文来说,要关注主键是谁,本例中的主键是最常见的自增id
。replace into
就是根据这个id
值去决定是更新还是插入的。
目前数据表中,有三条数据。那么再次执行下面的replace into
语句,表面上并不给数据带来任何变化。
replace INTO `users3` VALUES (1,'技术部','苏南大叔','11111'),(2,'国际部','苏南大叔','22222'),(3,'后勤部','sunan大叔','33333');
如果数据中的非主键id
列,是变化的,那么执行的效果是数据更新。
replace INTO `users3` VALUES (1,'技术部1','苏南大叔1','11111'),(2,'国际部','苏南大叔','22222'),(3,'后勤部','sunan大叔','33333');
如果数据中的主键id
变化,非id
列不变。那么执行效果是数据插入。
replace INTO `users3` VALUES (1,'技术部','苏南大叔','11111'),(2,'国际部','苏南大叔','22222'),(5,'后勤部','sunan大叔','33333');
replace into
测试二(组合主键)
replace into
的标准就是主键,那么,如果主键不是id
的话,执行效果就会出现偏差,并不符合预期。那么,本例中,如果主键不是id
,而是department
和name
的组合呢?
数据表语句如下:
DROP TABLE IF EXISTS `users3`;
CREATE TABLE `users3` (
`uuid` varchar(36) NOT NULL,
`department` varchar(50) NOT NULL,
`name` varchar(50) NOT NULL,
`password` varchar(50) DEFAULT NULL,
PRIMARY KEY (`department`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `users3` VALUES (uuid(),'后勤部','sunan大叔','33333'),(uuid(),'国际部','苏南大叔','22222'),(uuid(),'技术部','苏南大叔','11111');
注意这里没有自增id
,而是使用了uuid()
。因为自增id
只要存在就必须设置为主键primary key
。这和本测试用例的主旨冲突。并且组合主键里面的字段默认不能为空,所以代码里面是not null
。
相关文章:
replace into
语句执行如下:
replace INTO `users3` VALUES (uuid(),'后勤部','sunan大叔','33333'),(uuid(),'国际部','苏南大叔','22222'),(uuid(),'技术部','苏南大叔','11111');
可见,在主键是一个多字段联合主键的情况下,只有当deparment
和name
都一致的情况下,才会执行更新。同时,更新uuid()
的运行结果为新的uuid()
数据。
现在的主键不是uuid
字段,所以更新uuid
的字段内容,并没有什么法理上的不妥。只是看上去有些奇怪罢了。
相关链接
- https://newsn.net/say/mysql-replace.html
- https://newsn.net/say/mysql-index.html
- https://newsn.net/say/mysql-uuid.html
总结
数据表的主索引设置是谁,将控制replace into
的执行结果走向。换句话说的话,即使同样的replace into
语句,也会根据表的主键变化,而产生不同的效果。再换句话来说,replace into
语句存在有隐含条件:表的主键。
更多mysql
相关文章,请点击下面的链接:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。