MySql
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象,如:数据库、表、字段等等 |
DML |
Data Manipulation Language |
数据操作语言,用来对数据表中的数据进行增、删、改 |
DQL | Data Query Language | 数据查询语言,用来查询 数据库中表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
DML
DML:就三个字,增(insert)、删(delete)、改(update)
添加(INSERT)
指定指定添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
study> insert into tb_user (id, username, age) values (1,'milo',33) [2023-09-18 15:24:15] 1 row affected in 9 ms
全部字段添加数据
INSERT INTO 表名 VALUES (值1, 值2, ...);
study> insert into tb_user values (2,'milo',20) [2023-09-18 15:27:23] 1 row affected in 5 ms
批量添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
实际用的
我们在工作中,大部分都会采用框架,如传入User的结构体,然后直接save即可。或者要涉及到sql语句,一般也是采用占位符 %s 把字段名和值的名称先来表示,如 :
insert into tb_user (%s) values (%s);
再在代码中增对%s去赋值,这样可以在循环中去批量插入。
注意事项
字符串和日期类型数据应该包含在引号中
插入的数据大小应该在字段的规定范围内
修改(UPDATE)
根据条件,修改数据
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ... [ WHERE 条件 ];
study> update tb_user set username = 'miloyang',age = 30 where id = 1 [2023-09-18 15:38:28] 1 row affected in 8 ms
注意:不带where则会更新全表数据,切记切记
删除(DELETE)
根据条件进行删除
DELETE FROM 表名 [ WHERE 条件 ];
study> delete from tb_user where id = 1 [2023-09-18 15:47:15] 1 row affected in 7 ms
注意:不带where则会删除全表数据,切记切记,否则提桶吧
事务
事务,可以理解为要么全部成功,要么全部失败.
准备数据:
create table account(
id int auto_increment primary key,
name varchar(10),
money decimal(10,2)
) comment '账户表';
insert into account(name,money)values ('zhangsan',1000),('lisi',1000);
例如:张三和李四的账户都有1000块钱,张三向李四转500块钱。步骤一般都是:
1:查询张三的账户,大于500,执行下一步。
2:张三账户余额扣500.
3:李四账户余额加500.
如果执行完第二步,程序异常了,那第三步还没执行,就gg了。或者执行完第一步,还不到第二步,此时张三把1000块钱全部取出,那也gg了。则需要事务了
事务操作
- 查看、设置事务提交方式
mysql是自动提交事务的。我们可以改为手动,也就是执行commit之后才提交事务。
-- 查看事务提交方式
SELECT @@AUTOCOMMIT;
-- 设置事务提交方式,1为自动提交,0为手动提交,该设置只对当前会话有效
SET @@AUTOCOMMIT = 0;
提交事务
COMMIT;
回滚事务
ROLLBACK;
上述的转账案例,则为:
set @@AUTOCOMMIT = 0;
select * from account where name = 'zhangsan';
update account set money = money - 500 where name = 'zhangsan';
update account set money = money + 500 where name = 'lisi';
commit;
但是在实际工作中,不会采取修改事务提交方式来做事务操作,都是采用 开启事务
的方式。
start transaction;
select * from account where name = 'zhangsan';
update account set money = money - 500 where name = 'zhangsan';
update account set money = money + 500 where name = 'lisi';
commit;
事务四大特性
- 原子性(Atomicity):事务是不可分割的最小操作但愿,要么全部成功,要么全部失败
- 一致性(Consistency):事务完成时,必须使所有数据都保持一致状态
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
并发事务问题
我们在处理并发的时候,通常会有一下的问题出现:
脏读:一个事物读到另外一个事务还没提交的数据。
如事务A中更新zhagnsan的money为2000元,但是事务A还未提交。此时事务B读取到A的
更新但未提交
的money为2000,这时候就叫脏读。不可重复读:一个事物先后读取同一条记录,但两次读取的数据不同,为不可重复读。
如事务A中第一次查询zhangsan的money为1000元,A事务还未提交。此时事务B把zhangsan的money改为了2000元,事务A中再次查询zhangsan的money为2000元。这就是不可重复读。
幻读:一个事物按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了幻影一样。
如邮箱字段唯一,A事务开启的时候,还没有zhangsan@qq.com这条数据,在A事务中插入zhangsan@qq.com之前,B事务已经插入zhangsan@qq.com这条数据了。由于邮箱冲突,则A事务插入zhangsan数据失败。
事务的隔离级别
综合并发事务问题,事务的隔离级别,就是解决这些问题。
隔离级别有以下:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | 会 | 会 | 会 |
Read committed(oracle默认) | 不会 | 会 | 会 |
Repeatable Read(mysql默认) |
不会 | 不会 | 会 |
Serializable | 不会 | 不会 | 不会 |
事务的隔离级别越高,数据越安全,但性能越低,具体得看业务容忍度。
- 查看事务隔离级别
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)
- 设置事务隔离级别
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-UNCOMMITTED |
+-------------------------+
1 row in set (0.00 sec)