mysql实现存在则保存,不存在则更新
方式1 ON DUPLICATE KEY UPDATE
使用前提:表必须配置唯一键或者主键,且保存的字段中包含该键【重点】
原理:
ON DUPLICATE KEY UPDATE
如果配合主键,存在数据a,新插入b,如果主键不冲突,会保存b。如果b主键和a冲突会删除b,然后更新a。ON DUPLICATE KEY UPDATE
如果配合唯一键,mysql先插入一条数据,然后根据唯一键判断唯一键是否冲突,如果已经存在该键,就会删除后面插入的数据,对前面的那条数据执行更新操作。比如已经存在A,此时插入一条B,B和A冲突就会删除B,对A执行后面的更新操作。所以造成主键id+1。
基本语法
插入的字段必须包含master_id
, award_name
,这两个字段,否则唯一索引无效,mysql无法发现索引冲突,会一直执行保存动作,不会执行更新。
单条插入或者更新
INSERT INTO reward_center_award (master_id, award_name) VALUES('432564','京东e卡')
ON DUPLICATE KEY UPDATE
award_name='杜卡迪一辆'
批量插入或者更新
INSERT INTO reward_center_award (master_id, award_name,award_type) VALUES('432564','京东e卡',4), ('432564','杜卡迪',1),('432564','春风450',2)
ON DUPLICATE KEY UPDATE
award_name='杜卡迪一辆'
初始化表
主键id,唯一索引由master_id
,award_name
组成,意思同一个品牌商的奖品名称是唯一的。
DROP TABLE IF EXISTS reward_center_award;
CREATE TABLE `reward_center_award` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否删除(0:删除,1可用)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`reward_guid` varchar(50) DEFAULT NULL COMMENT '奖励标识guid',
`master_id` varchar(50) DEFAULT NULL COMMENT '品牌主Id',
`master_name` varchar(50) DEFAULT NULL COMMENT '品牌主名称',
`award_name` varchar(50) DEFAULT NULL COMMENT '奖品名称',
`award_type` tinyint(4) DEFAULT NULL COMMENT '奖励类型 1:店铺商品,2:线下商品,3:积分,4:优惠券',
`goods_name` varchar(100) DEFAULT NULL COMMENT '商品名称',
`goods_price` decimal(13,2) DEFAULT NULL COMMENT '商品价格',
`number` bigint(11) DEFAULT '0' COMMENT '奖品总数',
PRIMARY KEY (`id`),
UNIQUE KEY `master_id_award_name` (`master_id`,`award_name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='奖品中心奖品表';
1. 表一开始为空,所以这里是保存一条数据。
INSERT INTO reward_center_award (master_id, award_name) VALUES('432564','京东e卡')
ON DUPLICATE KEY UPDATE
award_name='杜卡迪一辆'
执行结果
2. 同样的语句再执行一次
因为前面插入了一条数据a,这次又插入一条一样的数据b,这次会唯一索引冲突,会删除b,然后对a执行更新操作,主键id+1
INSERT INTO reward_center_award (master_id, award_name) VALUES('432564','京东e卡')
ON DUPLICATE KEY UPDATE
award_name='杜卡迪一辆'
3. 再插入一条不同的数据
因为前面主键+1,所以这里id从3开始了
INSERT INTO reward_center_award (master_id, award_name) VALUES('432564','春风450')
ON DUPLICATE KEY UPDATE
award_name='杜卡迪一辆'
方式二:REPLACE INTO
也需要存在主键或者唯一键
先删除原来数据,再插入。比如表里有A,插入一条和A一样的B时,会把A删除再插入B。
基本语法
插入的字段必须包含master_id
, award_name
,这两个字段,否则唯一索引无效,mysql无法发现索引冲突,会一直执行保存动作,不会执行更新。
单条插入或者更新
REPLACE INTO 表名(字段1,字段2)
VALUES(值A,值B);
批量插入或者更新
REPLACE INTO 表名(字段1,字段2)
VALUES(值A,值B),(值A,值B),(值A,值B),(值A,值B);
和上面同样的表
DROP TABLE IF EXISTS reward_center_award;
CREATE TABLE `reward_center_award` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否删除(0:删除,1可用)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`reward_guid` varchar(50) DEFAULT NULL COMMENT '奖励标识guid',
`master_id` varchar(50) DEFAULT NULL COMMENT '品牌主Id',
`master_name` varchar(50) DEFAULT NULL COMMENT '品牌主名称',
`award_name` varchar(50) DEFAULT NULL COMMENT '奖品名称',
`award_type` tinyint(4) DEFAULT NULL COMMENT '奖励类型 1:店铺商品,2:线下商品,3:积分,4:优惠券',
`goods_name` varchar(100) DEFAULT NULL COMMENT '商品名称',
`goods_price` decimal(13,2) DEFAULT NULL COMMENT '商品价格',
`number` bigint(11) DEFAULT '0' COMMENT '奖品总数',
PRIMARY KEY (`id`),
UNIQUE KEY `master_id_award_name` (`master_id`,`award_name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='奖品中心奖品表';
插入两条数据
INSERT INTO reward_center_award (master_id, award_name,award_type) VALUES('432564','杜卡迪','1'),('432564','春风450','2');
REPLACE INTO reward_center_award (master_id, award_name,award_type) VALUES('432564','杜卡迪',3);
id=1的被删除了,插入了一条新数据
完结!!!