2_1、mysql基础--DML

一、DML

DML(Data Manipulation Language)指数据操作语言,用来对数据表中的数据记录进行增/删/改操作,不包括数据查询

//插入数据语法
insert into 表 (列名1,列名2,列名3...) values (值1,值2,值3...); //向表中插入某些
insert into 表 values (值1,值2,值3...);     //向表中插入所有列

//删除数据语法
delete from 表名 [where 条件];

//修改数据语法
update 表名 set 字段名=值,字段名=值...;
update 表名 set 字段名=值,字段名=值... where 条件;

//清空数据语法
truncate table  表名 或者 truncate 表名

二、批量插入数据

2.1 批量插入数据示例

CREATE TABLE `book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

//批量插入
INSERT INTO book(name,price)
VALUES
('a',1),
('b',2),
('c',3);

2.2 批量插入的数据量大小限制

1、mysql中每次批量插入或更新的数据量(查询、删除不受影响),会受max_allowed_packet 参数限制,默认是4M(4194304字节)。

//mysql中查看max_allowed_packet 值的语句
show variables like '%max_allowed_packet%'; 

2、当需要批量插入大量数据时,如何解决呢?

常见的方法是:将待插入的数据list,分成多个list,分批插入。

//
    /**
     * mybatis-plus中批量插入(分批插入)的源码
     *
     * @param entityList 待插入数据列表
     * @param batchSize 每次分批的list大小
     * @return ignore
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
        try (SqlSession batchSqlSession = sqlSessionBatch()) {
            int i = 0;
            for (T anEntityList : entityList) {
                batchSqlSession.insert(sqlStatement, anEntityList);
                //此处将批量数据,分成多个批次
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
                i++;
            }
            //将小批次的批量数据插入
            batchSqlSession.flushStatements();
        }
        return true;
    }

2.3 批量插入时数据重复处理

在 mysql 中,当存在主键冲突任意一个唯一键冲突的情况下,根据插入策略不同,一般有以下三种方法避免插入失败:

  • insert ignore into:若没有则插入,若存在则忽略
  • insert into … on duplicate key update:若没有则正常插入,若存在则更新
  • replace into:若没有则正常插入,若存在则先删除后插入

注意:

1、replace into 遇到已存在的记录,会先删除掉表中原有的记录后,再插入新的记录,如果该表的和其它表有关联,那么可能会导致关联数据丢失,所以一般不用replace into 方式

2、三种方法在数据重复未插入时,未插入数据也会造成AUTO_INCREMENT自增(AUTO_INCREMENT不连续问题),且这种不连续不会同步更新到 slave 的 AUTO_INCREMENT,当 master 被 kill,且 slave 升级为 master 时,就会出现主键冲突问题。【所以一般不用自增约束,采用分布式id来生成各表主键】

3、mybatis-plus目前没支持如上3中处理方式封装,可通过xml文件手写对应的sql或者扩展框架

2.3.1 批量插入示例

(1)新建数据表与初始化数据

CREATE TABLE `user_card` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `uid` int(10) DEFAULT '0' COMMENT '用户ID',
  `dep_id` int(10) DEFAULT '0' COMMENT '部门ID',
  `name` varchar(255) DEFAULT '' COMMENT '姓名',
  `money` decimal(10,2) DEFAULT '0.00' COMMENT '余额',
	`company_id` int(10) DEFAULT '0' COMMENT '公司ID',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid_did` (`uid`,`dep_id`),   
  UNIQUE KEY `uid_cid` (`uid`,`company_id`)
);


INSERT INTO user_card(uid,dep_id,name,money,company_id)
VALUES
(10000,10,'a',11,100),
(20000,20,'b',22,200),
(30000,30,'c',33,300);

(2)批量插入示例

//insert ignore into用法
INSERT IGNORE INTO user_card(uid,dep_id,name,money,company_id)
VALUES
(10000,10,'a',11,100),
(40000,40,'d',44,400);



//insert into ... on duplicate key update用法
//update money=values(money)只会修改money字段的值,其他字段的值不变
INSERT  INTO user_card(uid,dep_id,money,company_id)
VALUES
(10000,10,11.11,111),
(40000,40,44,400)
on duplicate key update money=values(money);



//insert into ... on duplicate key update用法
//update 中使用values关键字的才会更新,不使用values关键字会不出现在update中的字段值不会更新
INSERT  INTO user_card(uid,dep_id,money,company_id)
VALUES
(10000,10,11.11,111),
(40000,40,44,400)
on duplicate key update dep_id=dep_id,money=values(money);     //dep_id与其他字段值不会更新

2.3.2 AUTO_INCREMENT不连续原因–自增锁模式

insert语句常常涉及自增列的加锁过程,会涉及到AUTO-INC Locks加锁过程。因此我们了解下自增锁及模式。

AUTO-INC锁是一种特殊的表级锁,innodb_autoinc_lock_mode有3种配置模式:0、1、2,分别对应”传统模式”, “连续模式”(默认值), “交错模式”:

mysql> show variables like  'innodb_autoinc_lock_mode';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_autoinc_lock_mode | 1     |
+--------------------------+-------+
  • 传统模式:涉及auto-increment列的插入语句加的表级AUTO-INC锁,只有插入执行结束后才会释放锁。
  • 连续模式:事先确定插入行数(包括单行和多行插入),分配连续的确定的auto-increment值。这种模式下,事务回滚,auto-increment值不会回滚,换句话说,自增列内容会不连续。(当行数不能确定时仍加表锁)
  • 交错模式:同一时刻多条SQL语句产生交错的auto-increment值。

1、从开发者视角学习MYSQl系列文章:https://blog.csdn.net/maoxuemin/article/details/123523457
2、快速问答入口:https://gitee.com/wendakuai/introducton/wikis/question

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值