数据库

151 阅读25分钟

常见的关系型数据库管理系统

  • Oracle: 收费的大型数据库,Oracle公司产品
  • MySQL: 开源免费的中小型数据库。
  • SQL Server: MicroSoft 公司收费的中型数据库。C#、.net等语言常使用
  • PostgreSQL: 开源免费中小型数据库
  • DB2: IBM公司的大型收费数据库产品 -SQLite: 嵌入式的微型数据库。如:作为Android内置数据库。
  • MariaDB: 开源免费中小型数据库。

数据库相关概念

  • 数据库

    • 存储数据的仓库,数据是有组织的进行存储
    • 英文:DataBase,简称 DB
  • 数据库管理系统

    • 管理数据库的大型软件
    • 英文:DataBase Management System, 简称 DBMS
  • SQL

    • 英文:Structured Query Language, 简称 SQL,结构化查询语言
    • 操作关系型数据库的编程语言
    • 定义操作所有关系型数据库的统一标准
    • 对于同一个需求,每一种数据库的操作方式可能有所不同,这些我们称之为方言
  • 关系型数据库 关系型数据库是建立在关系模型基础上的数据库,简单说,关系型数据库是由多张能相互连接的二维表组成的数据库

    • 优点
      1. 都是使用表结构,格式一致,易于维护
      2. 使用通用的SQL语言操作,使用方便,可用于复杂查询。
      3. 数据存储在磁盘中,安全。

数据库设置

1. 软件的研发步骤

2. 数据库设计概念

  • 数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构造出最优的数据存储模型。
  • 建立数据库中的表结构以及表与表之间的关联关系的过程
  • 有哪些表?表里有哪些字段?表和表之间有什么关系?

3. 数据库设计的步骤

    1. 需求分析(数据是什么?数据具有哪些属性?数据与属性的特点是什么?)
    1. 逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)
    1. 物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)
    1. 维护设计(1.对新的需求进行建表。2.表优化)

表关系

  • 一对一
    • 如:用户和用户详情
    • 一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能。
  • 一对多
    • 如:部门和员工
    • 一个部门对应多个员工,一个员工对应一个部门
  • 多堆多
    • 如:商品和订单
    • 一个商品对应多个订单,一个订单包含多个商品
    • 实现方式:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

安装MYSQL数据库

使用命令行窗口连接MYSQL数据库

mysql -h 主机IP -P 端口 -u 用户名 -p密码
  • 如果没写-h默认就是主机
  • 如果没写-P默认就是3306

数据库三层结构

  • 所谓安装MYSQL数据库,就是在主机安装一个数据库管理系统(DBMS),这个管理程序可以管理多个数据库。DBMS(database message system)
  • 一个数据库中可以创建多个表,以保存数据
  • 数据库管理系统(DBMS)
  • 表的本质任然是文件

SQL语句分类

  • DDL: 数据定义语句
  • DML: 数据操作语句(增加、修改、删除)
  • DQL: 数据查询语句(select)
  • DCL: 数据控制语句(管理数据库)

创建数据库

CREATE DATABASE [IF NOT EXISTS] db_name 
    [create_spectification [,create_specification]...]
    
[DEFAULT] CHARACTER SET charset_name | 
[DEFAULT] COLLATE collation_name
  1. CHARACTER SET: 指定数据库采用的字符集,如果不指定字符集,默认utf8
  2. COLLATE: 指定数据库字符集的校对规则(常用 utf8_bin【区分大小写】、utf8_general_ci【不区分大小写】 默认是 utf8_general_ci)

查看、删除数据库

# 显示数据库语句
SHOW DATABASES
# 显示数据库创建语句
SHOW CREATE DATABASE db_name
# 数据库删除语句
DROP DATABASE [IF EXISTS] db_name
  • 在创建数据库、表的时候、为了规避关键字、可以用反引号解决

备份恢复数据库

  • 备份
mysqldump -u 用户名 -p -B 数据库1 数据库2 数据库3 > 文件名.sql
  • 恢复(需要进入Mysql 命令行执行)
source 文件名.sql
  • 备份库的表
mysqldump -u 用户名 -p密码 数据库 表1 表2 表n > 文件名.spl

数据类型

数值类型

类型大小范围(有符号)范围(无符号)用途
TINYINT1 Bytes(-128,127)(0,255)小整数值
SMALLINT2 Bytes(-32 768,32 767)(0,65 535)大整数值
MEDIUMINT3 Bytes(-8 388 608,8 388 607)(0,16 777 215)大整数值
INT或INTEGER4 Bytes(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整数值
BIGINT8 Bytes(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)极大整数值
FLOAT4 Bytes(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)0,(1.175 494 351 E-38,3.402 823 466 E+38)单精度 浮点数值
DOUBLE8 Bytes(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)双精度 浮点数值
DECIMAL对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2依赖于M和D的值依赖于M和D的值小数值

在能够满足需求的情况下,尽量使用存储空间小的

  • 数值型(bit)

    1. 基本使用
    create table ta (num bit(8));
    
    1. 细节说明
      • bit字段显示时,按照位的方式显示
      • 查询的时候任然可以使用添加的数值
      • 如果一个值之后0,1可以考虑用bit(1),可以节约空间
      • 位类型。M指定位数,默认值1,范围1~64
      • 使用不多
  • 小数的基本使用

    1. float/double [unsigned] float单精度,double 双精度

    2. decimal[M,D] [unsigned]

    可以支持更加精确的小数位。M是小数位数的总数,D是小数点后面的位数。
    如果D是0,则值没有小数点或者分数部分。M最大65.D最大30.如果D被省略,默认是0.如果M被省略,默认是10.

日期和时间类型

类型大小 ( bytes)范围格式用途
DATE31000-01-01/9999-12-31YYYY-MM-DD日期值
TIME3'-838:59:59'/'838:59:59'HH:MM:SS时间值或持续时间
YEAR11901/2155YYYY年份值
DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
TIMESTAMP41970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07YYYYMMDD HHMMSS混合日期和时间值,时间戳
  • 日期类型的基本使用
    create table birthday(
        t1 date,
        t2 datetime,
        t3 timestamp not null default current_timestamp no update current_timestamp
    );
    

字符串类型

类型大小用途
CHAR0-255 bytes定长字符串
VARCHAR0-65535 bytes变长字符串
TINYBLOB0-255 bytes不超过 255 个字符的二进制字符串
TINYTEXT0-255 bytes短文本字符串
BLOB0-65535 bytes二进制形式的长文本数据
TEXT0-65535 bytes长文本数据
MEDIUMBLOB0-16777215 bytes二进制形式的中等长度文本数据
MEDIUMTEXT0-16777215 bytes中等长度文本数据
LONGBLOB0-4294967295 bytes二进制形式的极大文本数据
LONGTEXT0-4294967295 bytes极大文本数据
  • 字符串基本使用

    1. char(size) 固定长度字符串 最大255字符

    char(4) 是固定的大小,就是说,即使你插入'aa',也会分配4个字符

    1. varchar(size) 可变长度字符串 最大65532字节 【uft8 编码最大21844字符 1-3个字节用于记录大小】

    varchar(4) 是变长,就是说如果,你插入了'aa',实际占用空间大小并不是4个字符,而是按照实际占用空间类分配【varchar 本身还需占用1-3个字节来记录存放内容的长度】

    1. 什么时候使用char,什么时候使用varchar

    如果数据是定长,推荐使用cahr,比如MD5的密码,邮编,手机号,身份证号码等
    如果一个字段的长度是不确定,我们使用varchar,比如留言,文章

创建表

CREATE TABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
) character set 字符集 collate 校对规则 engine 引擎
field:指定列名 datatype:指定列数据类型(字段类型)
character set:如不指定则为所在数据库字符集
collate:如不指定则为所在数据库校对规则
engine:引擎
  • 创建表时,要根据需保存的数据创建相应的列,并根据数据的类型定义相应的列类型。

修改表

  • 添加列
alter table tablename
add ( column datatype [default expr]
[, column datatype]...);
  • 修改列
alter table tablename
modify (column datatype [default expr]
[, column datatype]...);
  • 删除列
alter table tablename
drop (column);
  • 修改列名
alter table tablename
change 原列名 新列明  (column datatype [default expr]
[, column datatype]...);
# 查看表结构
desc 表名;
# 修改表名
Rename table 表名 to 新表名;
# 修改表字符集
alter table 表名 character set 字符集;

CRUD

  • insert语句
insert into table_name [(colum [, colum...])]
values (value, [,value...]);
  • 细节说明
  1. 插入的数据应与字段的数据类型相同。
  2. 数据的长度应在列的规定范围内。
  3. 在values中列出的数据位置必须与被加入的列的排列位置相对应。
  4. 字符和日期类型数据应包含在单引号中。
  5. 列可以插入空值[前提\是该字段允许为空], insert into table value(null);
  6. insert into tab_name (列名) values (), (), () 形式添加多条记录。
  7. 如果是给表中的所有字段添加数据,可以不写前面的字段名称
  8. 默认值的使用,当不给某个字段值时,如果有默认值就会添加,否则报错。
  • update语句
update table_name
        set col_name1=expr1 [, col_name2=expr2 ...]
        [where where_definition]
  • 使用细节
  1. update 语法可以用新值更新原有表行中的各列。
  2. set 子句指示要修改哪些列和要给予哪些值。
  3. where 子句指定应更新哪些行。如果没有where子句,则更新所有的行。
  4. 如果需要修改多个字段,可以通过 set 字段1=值1, 字段2=值2...
  • delete语句
delete from table_name
[where where_definition]
  • 使用细节
  1. 如果不使用where子句,将删除表中所有数据。
  2. delete语句不能删除某一列的值 (可使用update设置为null或者‘’)
  3. 使用delete语句仅删除记录,不删除表本身。如果要删除表,使用drop table语句。
  • select语句
select [distinct] * | {colunm1, column2...}
from tablename;
  • 注意事项
  1. select指定查询哪些列的数据。
  2. column指定列名。
    • 代表查询所有列。
  3. from指定查询哪张表。
  4. distinct 可选,指显示结果时,是否去掉重复数据。
  • 使用表达式对查询的列进行运算
select * | {column1|expression, column2 | expression, 。。。}
from tablename;
  • 在select语句中可使用as语句
select columnname as 别名 from 表名;
  • 在where子句中经常使用的运算符
比较运算符 > < <= >= =<> != 大于、小于、大于(小于)等于、不等于
between ...and... 显示在某一区间的值
in(set) 显示在in列表中的值, 例:in(100,200)
like '小%'
not like ''
模糊查询 以'小'开头的
模糊查询
is null 判断是否为空
逻辑运算符 and 多个条件同时成立
or 多个条件任一成立
not 不成立,例:where not(salary > 100);
  • 使用order by语句排序查询结果
select column1, column2, ...
from table
order by column asc|desc, ...
  1. order by 指定排序的列,排序的列既可以是表中的列名,也可以是select语句后指定的列名.
  2. asc升序[默认]、desc 降序
  3. order by 字句应位于select 语句的结尾。
  • 合计/统计函数 - count
select count(*)| count(列名) from table_name
[where where_definition]

count(*) 和 count(列)区别
count(*):返回满足条件的记录的行数
count(列):统计满足条件的某列有多少个,但是会排除为null

  • 合计函数 - sum
# sum函数返回满足where条件的行的和 -- 一般使用在数值列
select sum(列名) {, sum(列名)...} from tablename
[where where_definition]
  • 合计函数 - avg
select avg(列名) {, avg(列名)...} from tablename
[where where_definition]
  • 合计函数 - max/min
select max(列名) from tablename
[where where_definition]
  • 使用group by 子句对列进行分组
select colunm1,column2,... from tablename
group by column;
  • 使用having字句对分组后的结果进行过滤
select cloumn1,column2...   from tablename
group by column having ...
  1. group by 用于对查询的结果分组统计
  2. having 字句用于限制分组显示结果
  • 字符串相关函数
charsrt(str) 返回字符串字符集
concat(string,[.....]) 连接字符串
instr(string, substring) 返回substring在string中出现的位置,没有返回0
ucase(string) 转成大写
lcase(string) 转成小写
left(string,length) 从string中的左边取length个字符
length(str) 按字节返回 str长度
replace(str,search_str,replace_str) 在str中用replace_str替换search_str
strcmp(string1, string2) 逐字符比较两子串大小
substring(str, position, [length]) 从str的position开始【从1开始计算】,取length个字符
ltrim(string) rtrim(string) trim 去除前端空格或后端空格

dual 亚元表 ,系统表可以作为测试表使用

  • 数学相关函数
abs(num) 绝对值
bin(decimal_number) 十进制转二进制
ceiline(num) 向上取整,得到比num大的最小整数
conv(num, from_base, to_base) 进制转换
floor(num) 向下取整,得到比num小的最大整数
format(num, decimal_places) 保留小数位数
hex(decimalNumber) 转十六进制
least(num1, num2, [...]) 求最小值
mod(number, denominator) 求余
rand([seed]) 范围 0 <= v <= 1.0 每次返回不同的随机数,如果使用seed,seed不变,随机数也不变
  • 时间和日期相关函数
current_date() 当前日期
current_time() 当前时间
current_timestamp() 当前时间戳
date(datetime) 返回datetime的日期部分
date_add(date, interval d_value d_type) 在date中加上日期或时间
date_sub(date, interval d_value d_type) 在date上减去一个时间
datediff(date1, date2) 两个日期差(结果是天)
timediff(date1, date2) 两个日期差(结果是多少小时多少分多少秒)
now() 当前时间
year|month|date (datetime)
from_unixtime()
年月日

date_add() 中的 interval 后面可以是year,minute,second,day 等 datediff(date1, date2) 得到的是天数,而且是date1 - date2 的天数,因此可以取负数
from_unixtime 把时间戳转成格式化时间

  • 加密和系统函数
user() 查询用户
database() 数据库名称
md5(str) 为字符串算出一个md5 32的字符串,(用户密码)加密
password(str)
select * from mysql.user \G
从原文密码str计算并返回密码字符串,通常用于对musql数据库的用户密码加密
  • 流程控制函数
if(expr1, expr2, expr3) 如果expr1为TRUE,则返回expr2 否则返回expr3
ifnull(expr1, expr2) 如果expr1不为空 null,则返回expr1,否则返回expr2
select case when expr1 then expr2
when expr3 then expr4 else expr5 end; [类似多重分支]
如果expr1为TRUE,则返回expr2,如果expr3为TRUE,返回expr4,否则返回expr5
password(str)
select * from mysql.user \G
从原文密码str计算并返回密码字符串,通常用于对musql数据库的用户密码加密

判断为空 需要使用 is null
判断不为空 需要使用 is not null

  • 查询加强

日期类型也可以进行比较
使用like操作符(模糊比较):% 表示0到多个任意字符, _ 表示单个任意字符
desc tablename; 查询表结构
分页查询

select ... limit start, rows 
-- 表示从start+1 行开始取,取出rows行,start从0开始

如果select 语句同时包含有group by,having,limit,order by 那么它们的顺序是:group by,having,order by, limit

  • 多表查询 多表查询是指基于两个和两个以上的表查询在实际应用中,查询单个表可能不能满足你的需求。

在默认情况下:当两个表查询时,规则

  1. 从第一张表中,取出一行和第二章表的每一行进行组合,返回结果【含有两张表的所有列】
  2. 一共返回的记录数 第一张表行数 乘 第二张表行数
  3. 这样多表查询默认处理返回的结果,称之为笛卡尔集
  4. 解决这个多表的关键就是要学出正确的过滤条件 where
  • 自连接 自连接是指在同一张表的连接查询【将同一张表看做两张表】
    需要给表取别名:表名 表别名
    列名不明确,可以指定列别名

  • 子查询

什么是子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询
单行子查询是值只返回一行数据的子查询语句

多行子查询 多行子查询指返回多行数据的子查询 使用in关键字

  • 在多行子查询中使用all操作符
# all表示全部的
select ename,sal from emp where sal > all(
    select sal from emp where depno=30
);
  • 在多行子查询中使用any操作符
# any表示其中一个
select ename,sal from emp where sal > any(
    select sal from emp where depno=30
);
  • 多列子查询 多列子查询:返回多个列数据的子查询语句

(字段1,字段2...)=(select 字段1,字段2...)

表复制

  • 自我复制数据 有时,为了对某个sql语句进行效率测试,我们需要海量数据时,可以使用此法为表创建海量数据。
# 把旧表的结构复制到新表
create table 新表 like 旧表;
  • 表去重
1. 先创建一张临时表temp。该表结构和需要去重的表一样
2. 把需要去重的表的记录,通过distinct关键字处理后,把记录复制到temp表中
3. 清除掉需要去重表的全部记录  
4. 把temp表的记录复制到 需要去重的表中
5. drop temp 表

合并查询

有时在实际应用中,为了合并多个select语句的结果,可以使用集合操作符 union,union all

  • union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会取消重复行

  • union

该操作符用于取得两个结果集的并集。当使用该操作符时,会去重

mysql 外连接

  • 左外连接 (如果左侧表完全显示)

select .. from 表1 left join 表2 on 查询条件;

  • 右外连接 (如果右侧表完全显示)

select .. from 表1 right join 表2 on 查询条件;

mysql约束

约束用于确保数据库数据满足特定的商业规则。在MySQL中约束包括:not null,unique,primary key,foreign key和check 五种。

  • primary key(主键)
字段名 字段类型 primary key

用于唯一的标识表行的数据,当定义主键约束之后,该列不能重复

primary key 不能重复而且不能为null
一张表最多只能有一个主键,但可以是复合主键
主键的指定方式有两种:

  1. 直接在字段名后面指定:字段名 primary key
  2. 在表定义最后写 primary key(列名)
    使用desc 表名,可以看到primary key 的情况
  • not null(非空)

如果在列上定义了not null,那么当插入数据时,必须为列提供数据

  • unique(唯一)

当定义了唯一约束后,该列值是不能重复的,
如果没有指定not null,则unique字段可以有多个null
一张表可以有多个unique字段

  • foreign key 外键

用于定义主表和从表之间的关系:外键约束要定义在从表上,主表则必须具有主键约束或者是unique约束,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为null

foreign key (本表字段名) references 
主表名(主键名或者unique字段)
  1. 外键指向的表的字段,要求是primary key 或者是unique。
  2. 表的类型是innodb,这样的表才支持外键。
  3. 外键字段的类型和主键字段的类型一致(长度可以不用)
  4. 外键字段的值,必须在主键字段中出现过,或者为null【前提是外键字段允许为null】
  5. 一旦建立外键的关系,数据不能随意删除了,
  • check约束 用于强制行数必须满足的条件,假定在sal列上定义了check约束,并要求sal列值在10002000之间如果不在10002000之间就会提示出错。
列名  类型  check(check条件)
# mysql 5.7不支持check约束
  • 自增长 auto_increment
字段名 类型 primary key auto_increment

insert into xxx(colum1, clomn2) value(null, '值');
# 设有自增长的列,传入null则会自增长
  1. 一般来说自增长是和primary key 配合使用的
  2. 自增长也可以单独使用【但需要配合一个unique】
  3. 自增长修饰的字段为整数型的(也可以小数,但是非常少这样使用)
  4. 自增长默认从1开始 ,也可以通过alter table 表名 auto_increment = 新的开始值;
  5. 如果你添加数据时,给自增长字段指定有值,则以指定的值为准。

mysql索引

说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,查询速度就可能提升百倍千倍。

# 创建索引
create index 索引名称 on 表名字(列名字);
  • 索引的原理
    • 没有索引为什么会慢?
      • 因为全表扫描
    • 使用索引为什么会快?
      • 形成一个索引的二叉树
    • 索引的代价
      • 磁盘占用空间大
      • 对dml(update delete inster)语句的效率影响
  • 索引的类型
  1. 主键索引,主键自动的为主索引(类型primary)
  2. 唯一索引(unique)
  3. 普通索引(index)
  4. 全文索引(fulltext)【适用于MyISAM】
    一般开发,不使用MySQL自带的全文索引
    开发中考虑使用:全文搜索 Solr 和 ElasticSearch(ES)
  • 查看索引
show index from table_name;
  • 索引使用
  1. 添加索引
create [unique] index index_name on table_name(col_name[(length)] [ASC|DESC],....); 
# 或者
alter table table_name add index [index_name] (index_col_name, ...);
  1. 添加主键索引
alter table table_name add primary key (col_name,....);
  1. 删除索引
drop index index_name on table_name;
# 或者
alter table table_name drop index index_name;

  1. 删除主键索引
alter table table_name drop primary key;
  • 在哪些列上适合使用索引
  1. 较频繁的作为查询条件字段应该创建索引
  2. 唯一性太差的字段不太适合单独创建索引,即使频繁作为查询条件
  3. 更新非常频繁的字段不太适合创建索引
  4. 不会出现在where字句中字段不该创建索引

事务

  • 事务简介
    • 数据库的事务(transaction)是一种机制、一个操作序列,包含了一组数据库操作命令
    • 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败
    • 事务一个不可分割的工作逻辑单元。
    -- 开启事务
    start transaction
    # 或者
    begin
    
    -- 设置保存点
    savepoint 保存点名
    
    -- 回退事务
    rollback to 保存点名
    
    -- 回滚全部事务
    rollback;
    
    -- 提交事务,所有操作生效,不能回退
    commit;
    
    
  • 事务和锁

当执行事务操作时(dml语句),MySQL会在表上加锁,防止其他用户改表的数据,这对用户来说非常重要

  • 回退事务

在介绍回退事务前,先介绍一下保存点(savepoint),保存点是事务中的点,用于取消部分事务,当结束事务时(commit),会自动删除该事务所定义的所有保存点,当执行回退事务时,通过指定保存点可以回退到指定的点。

  • 提交事务

使用commit语句可以提交事务,当执行了commit语句之后,会确认事务的变化、结束事务、删除保存点、释放锁、数据生效。当使用commit语句结束事务之后,其它会话【其它连接】可以查看到事务变化后的新数据。

  • 事务的四大特征
    • 原子性(Atomicity):事务是不可分割的最小操作单位,要么同时成功,要么同时失败。
    • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
    • 隔离性(Isolation):多个事务之间,操作的可见性
    • 持久性(Durability):事务一旦提交或回滚,它对数据库中的改变就是永久的。
  • MYSQL事务默认自动提交
-- 查看事务的默认提交方式
select @@autocommit;
-- 1 自动提交   0 手动提交

-- 修改事务提交方式
set @@autocommit = 0;
  • 事务的细节
  1. 如果不开始事务,默认情况下,dml操作是自动提交的,不能回滚。
  2. 如果开始一个事务,你没有创建保存点,你可以执行rollback,默认就是回退到事务开始的状态。
  3. 可以在事务没有提交之前,创建多个保存点。
  4. 可以在事务没有提交之前,选择回退到哪个保存点。
  5. InnoDB 存储引擎支持事务,MyISAM不支持。
  • 事务隔离级别
  1. 多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。
  2. 如果不考虑隔离性,可能会引发如下问题。
    • 脏读(dirty read)

    当一个事务读取另外一个事务尚未提交的改变(update,insert,delete)时,产生脏读

    • 不可重复读(nonrepeatable read)

    同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读。

    • 幻读(phantom read)

    同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读(一个已经提交的事务影响到了另一个未提交的事务)。

MySQL隔离级别定义了事务与事务之间的隔离程度

MySQL隔离级别 脏读 不可重复读 幻读 加锁读
读未提交(Read uncommitted) 不加锁
读已提交(Read committed) 不加锁
可重复读(Repeatable read) 不加锁
可串行化(Serializable) 加锁
# 查看事务隔离级别
select @@tx_ioslation;

# 查看系统当前隔离级别
select @@global.tx_ioslation;

# 设置当前会话隔离级别
set session transaction ioslation level repeatable read;

# 设置系统当前隔离级别
set global transaction ioslation level repeatable read;

# mysql 默认的事务隔离级别是 repeatable read,一般情况下,没有特殊要求,有没必要修改(因为该隔离级别可以满足绝大部分项目需求)
  • 全局修改,修改my.ini配置文件,在最后加上

#可选参数有:READ-UNCOMMITTED,READ-COMMITTED,REPEATABLE-READ,SERIALIZABLE.
[mysql]
transaction-ioslation = REPEATABLE-READ

表类型和存储引擎

  • 基本介绍
  1. MySQL的表类型由存储引擎(storage engines)决定,主要包括MyISAM、innoDB、Memory等。
  2. MySQL数据表主要支持六中类型,分别是:CSV、Memory、ARCHIVE、MRG_MYISAM、MYISAM、innoDB。
  3. 这六种又分为两类,一类是”事务安全型“(transaction-safe),比如:innoDB;其余都是第二类,称为”非事务安全型“(no-transaction-safe)【mysiam和memory】。
# 显示当前数据库支持的存储引擎
show engines;
  1. MyISAM不支持事务,也不支持外键,但其访问速度快,是事务完整性没有要求。
  2. innoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是比起MyISAM存储引擎,innoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。
  3. Memory存储引擎使用存在内存中的内容来创建表。每个Memory表只实际对应一个磁盘文件。Memory类型的表访问速度非常快,因为它的数据是存放在内存中的,并且默认使用HASH索引。但是一旦MySQL服务关闭,表中的数据就会丢失掉,表格结构还在。
  • 如何选择表的存储引擎
  1. 如果你的应用不需要事务,处理的只是基本的CRUD操作,那么MyISAM是不二的选择。
  2. 如果需要支持事务,选择innoDB。
  3. Memory存储引擎就是将数据存储在内存中,由于没有磁盘I/O的等待,速度极快。但是由于是内存存储引擎,所做的任何修改在服务器重启后都将消失。【用户的在线状态】
# 修改存储引擎
alter table table_name engine='存储引擎';