一系列操作,要么全部完成,要么一个都不做
Innodb已经成为Mysql的默认引擎,它的优势是显而易见的。
1. 是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
2. 如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读也有写,请使用InnoDB。
3. 系统奔溃后,MyISAM恢复起来更困难,能否接受;
left join会返回左表的所有行,即使在右表中没有匹配的数据
right join会返回右表所有行,即使在左表中没有匹配的数据
inner join会返回两个表共有的数据
full join会返回两个表所有行,即使没有匹配
第一范式(1NF): 列不可再分(原子性)
第二范式(2NF): 首先满足第一范式,然后必须有主键,非主键必须完全依赖主键,即非主键既不能不依赖主键,也不能只依赖主键的一部分。
首先满足第二范式,同时其他非主键必须直接依赖主键,不能间接依赖
为什么要切分数据库
水平切分:将一张表切分为多张表
垂直切分:按业务切分,同一类业务的表放到同一个库里
水平切分和垂直切分的顺序:应先做水平切分,数据量再增大,考虑垂直切分
池化思想:
生活中的例子:每次都打好了几盒饭在那里放着,你可以直接取。和你要打饭才开始打。
初始预设资源,抵消每次获取资源的消耗,如创建线程的开销,获取远程连接的开销等
数据库连接池:
连接池中先创建一定数量的连接,程序要获取连接直接从池中取,不必创建新的连接。如果池中的连接被用完了,新建一个放入池中。
索引是用于快速查询和检索数据的数据结构,索引的常用数据结构有hash和B+树;
优点:可以提高检索速度,如果是唯一索引还能保证数据每一行的唯一性
缺点: 创建和维护索引的耗时,索引还占用存储空间
B树所有节点既存放key,也存放data。B+树只有叶子节点存放key和data,其余节点只存放key
B树的叶子节点独立的,B+树的叶子节点组成一条链表,可以通过它找到相邻的叶子节点。
B树检索时不一定会检索到叶子节点,B+树检索时一定会检索到叶子节点。
hash索引优点定位快,但不支持顺序查询和范围查询,而且极端情况下发生大量Hash冲突(多个key的hash值相同)的话,查询也会变慢。
B+Tree索引支持顺序查询,范围查询,定位数据也不算慢
MySQL的基本存储结构是页,各个页组成一个双向链表,每个页中的记录又可以组成一个单项链表
关于索引的介绍:https://www.runoob.com/mysql/mysql-index.html
单列索引和组合索引
主键索引和二级索引(辅助索引)
聚集索引和非聚集索引
覆盖索引:查询列和索引列是一致的
alter table user add primary key(id)
alter table user add unqiue(id)
alter table user add index index_name(id)
alter table user add index(username(4))
alter table user add fulltext(username)
alter table user add index index_name(id, age, gender)
选择合适的字段
不合适创建索引的字段
大部分情况下能提高查询性能,数据量很小的情况下不一定
因为在加表锁前,要先解锁已有的表锁
表锁会锁定表中的所有记录,对表中任何记录的请求都有可能被阻塞,所以冲突更多。
事务A:你不出来我就不进去
事务B:你不进来我就不出去
事务A:我想进去,但门锁上了进不去,只能等待开门
事务B:得把事情办完在开门出去
MyISAM没有行锁,InnoDB有行锁
MyISAM没有事务,InnoDB有事务
共享锁(S)
排它锁(X)
用范围条件检索数据时,会给符合范围条件的已有数据记录的索引项加锁。键值在条件范围内但不存在记录,叫做“间隙”,InnoDB也会给这个间隙加锁,这个就叫做间隙锁
例:
select * from emp where id>100 for update;
目的:在可重复读的隔离级别下,使用间隙锁可以防止幻读
悲观锁是数据库层面的锁
对数据加排他锁(X),当事务A更新完成前事务B无法开始更新
具体操作:
select * from user for update
不是数据库层面的锁,而是使用版本字段
事务开始时获取版本字段,要修改时查看版本字段和之前是否一致,一致就更新,不一致就不更新
事务A开始,获取版本号
事务B开始,获取版本号
事务B修改,版本号更新
死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时,就会产生死锁。
生活中的例子:你不出来我不走,你不走我不出去
mysql例子:
//事务A
begin;
update user set name = xx where id = 1;
update user set name = xx where id = 2;
commit;
//事务B
begin;
update user set name = xx where id = 2;
update user set name = xx where id = 1;
A获取id=1的排他锁(X)
B获取id=2的排它锁(X)
A想要id=2的排他锁(X),等待B提交
B想要id=1的排他锁(X),等待A提交
以固定的顺序去操作数据记录,大事务拆成小事务,同一事务一次性锁定所有的资源,降低隔离级别,添加合理的索引
Record Lock:单个行记录上的锁
Gap Lock: 间隙锁,锁定一个范围,但不包括记录本身
Next-Key Lock:锁定一个范围,并且包括记录本身
Check 限制,它在数据库表格里被定义,用来限制输入该列的值。
触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。
1.数据库在刷新脏页,如redo log写满了要同步到磁盘
2.执行时遇到锁
脏页是指内存数据页和磁盘数据页内容不一致
1.没用上索引:如该字段没有索引或者对该字段使用了运算、函数等操作导致无法用索引
2.数据库选错了索引
1.表关联查询的效率要高于子查询,因为子查询走的是笛卡尔积
2.表关联查询可能有多条记录,子查询只有一条记录,如果需要唯一的列,最好走子查询
MyISAM读不是一定比InnoDB快的,要具体情况具体分析,一般来说InnoDB要维护的东西比较多造成读比MyISAM慢
VARCHAR 用于存储可变长宇符串, 它比定长类型更节省空间。
VARCHAR 使用额外1 或2 个字节存储字符串长度。列长度小千255 宇节时,使用1字节表示,否则使用2 字节表示
VARCHAR 存储的内容超出设置的长度时,内容会被截断。
CHAR 是定长的, 根据定义的字符串长妄分配足够的空间。
CHAR 会根据需要使用空格进行填充方便比较。
CHAR 适合存储很短的字符串, 或者所有值都接近同—个长度。
CHAR 存储的内容超出设置的长度时,内容同样会被截断。
使用策略:
简要说下,类似于数据结构中简单实现的HASH 表(散列表) 一样,当我们在
mysql 中用哈希索引时,主要就是通过Hash 算法,将数据库字段数据转换
成定长的Hash 值,与这条数据的行指针一并存入Hash 表的对应位置,如果发
生Hash 碰撞(两个不同关键字的Hash 值相同),则在对应Hash 键下以链表
形式存储。
-索引用来快速地寻找那些具有特定值的记录。如果没有索引, 一般来说执行查询时遍历整张表。
- 索引的原理很简单,就是把无序的数据变成有序的查询
1. 把创建了索引的列的内容进行排序
2. 对排序结果生成倒排表
3. 在倒排表内容上拼上数据地址链
4. 在查询的时候, 先拿到倒排表内容, 再取出数据地址链,从而拿到具体数据
1、FROM : 将数据从硬盘加载到数据缓冲区, 方便对接下来的数据进行操作.
2、WHERE : 从基表或视图中选择满足条件的元组. (不能使用聚合函数)
3、JOIN
4、ON : join on 实现多表连接查询
5 、GROUP BY : 分组
6、HAVING .在元组的基础上进行筛选, 选出符合条件的元组。( 一般与GROUP BY 进行连用)
7、SELECT : 查询到得所有元组需要罗列的哪些列.
8、DISTINCT : 去重的功能。
9、UNION : 将多个亘询结果台并(默认去掉重要的记录) .
10、ORDER BY : 进行相应的排序.
11 、LIMIT 1 : 显示输出一条数据记录(元组)
1、应用服务器与数据库服务器建立一个连接
2、数据库进程拿到请求sql
3、解析并生成执行计划, 执行
4、读取数据到内存并进行逻辑处理
5、通过步骤一的连接, 发送结果到客户端
6、关掉连接, 释放资源
下表分别是delete、truncate和drop
mysql 中的in语句是把外表和内表作hash 连接,而exists 语句是对外表作loop 循环,每次loop 循环再对内表进行奎询。—亘大家都认为exists 比in 语
句的效率要高,这种说法其实是不准确的。这个是要区分环境的。
1. 如果查询的两个表大小相当,那么用in 和exists 差别不大。
2. 如果两个表中一个较小, 一个是大表,则子查询表大的用exists, 子查询表
小的用in。
3. not in 和not exists: 如果查询语句使用了not in, 那么内外表都进行全表扫描,没有用到索引,而not exists 的子查询依然能用到表上的索引。所以无论那个表大,用not exists 都比not in 要快。
当MySQL 单表记录数过大时, 数据库的CRUD 性能会明显下降, 一些常见的优
化措旋如下:
1. 限定数据的范围: 务必禁止不带任何限制数据范围条件的查语句。比如:
我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内.;
2. 读/写分离: 经典的数据库拆分方案, 主库负要写,从库负要读;
3. 缓存存: 使用MySQL 的缓存, 另外对重量级、更新少的数据可以考虑使用应用级别的缓存;
4. 还有就是通过分库分表的方式进行优化,主要有垂直分区、垂直分表和水平分区、水平分表
表格的每一行都由主键唯一标识, 一个表只有一个主键。主健也是侯选键。按照惯例,候选键可以被指定为主键, 并且可以用于任何外键引用.
DISTINCT 在所有列上转换为GROUP BY , 并与ORDER BY 子句结合使用.
先说什么是交叉连接:交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配。
任何标准表最多可以创建16 个索引列。
它会停止递增, 任何进一步的插入都将产生错误, 因为密钥已被使用.
LAST_ INSERT_ ID 将返回由Auto_increment 分配的最后一个值, 并且不需要指定表名称。
show index from <tablename>;
%对应0个或更多字符,_只是LIKE语句中的一个字符.
1、CONCAT(A, B) – 连接两个字符串值以创建单个字符串输出。通常用于将两个
或多个字段合并为一个字段。
2、FORMAT(X, D)- 格式化数字 X 到 D 有效数字。
3、CURRDATE(), CURRTIME()- 返回当前日期或时间。
4、NOW() – 将当前日期和时间作为一个值返回。
5、MONTH(),DAY(),YEAR(),WEEK(),WEEKDAY() – 从日期
值中提取给定数据。
6、HOUR(),MINUTE(),SECOND() – 从时间值中提取给定数据。
7、DATEDIFF(A,B) – 确定两个日期之间的差异,通常用于计算年龄
8、SUBTIMES(A,B) – 确定两次之间的差异。
9、FROMDAYS(INT) – 将整数天数转换为日期值。
在java的开发中,货币在数据库中MySQL常用Decimal和Numric类型表示,这两种类型被MySQL实现为同样的类型。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定;例如:
salary DECIMAL(9,2)
在SQL中,将字符串类型分为了六类:char,varchar,text,blob,enum和set。
这里对text、blob、enum、set做些补充
文本字符串
如果数据量超过255个字符,通常会使用文本字符串。
文本字符串根据存储的数据格式进行分类:
通常二进制数据实际上数据库存储路径,物理文件放在磁盘上面。
枚举
enum,事先将所有出现的结果都设计好,实际存储的数据必须是预先规定的数据的一个。其作用如下:
① 规范数据格式,数据只能是规定的数据中的其中一个;
② 节省存储空间,枚举通常有一个别名-单选框;枚举实际存储的是数值而不是字符串本身。
create table my_enum(
gender enum('男','女','保密')
)charset utf8;
desc my_enum;
集合字符串
集合跟枚举很相似,实际存的是数字而不是字符串本身(集合是多选),区别与枚举,别名可以称为复选框。
Set(元素列表),可以使用元素列表中的多个元素,元素之间可以使用逗号分隔。
create table my_set(
hobby SET('篮球','足球','乒乓球','羽毛球','排球','台球','网球','棒球')
)charset utf8;
分析是一个复杂查询还是多个简单查询速度快
将一个大的查询分为多个小的相同的查询,而且单个查询可以减少锁的竞争
一次性删除1000万的数据要比一次删除1 万,暂停一会的方案更加损耗服务器
开销。
分解关联查询,让缓存的效率更高。
使用缓存
增加汇总表
myisam中没有任何where条件的count(*)非常快
确定ON 或者USING 子句中是否有索引。
确保GROUP BY 和ORDER BY 只有一个表中的列, 这样MySQL 才有可能使用索引。
用关联查询替代子查询,关联查询中,使用标识列分组的效率更高
优化GROUP BY 和DISTINCT,可以使用索引来优化
如杲不需要ORDER BY, 进行GROUP BY 时加ORDER BY NULL, MySQL 不
会再进行文件排序。
limit偏移量大的时候查询效率低,可以记录上次查询的最大ID , 下次查询时直接根据该ID 来查询
UNION ALL效率更高
多数数据库都是从左往右的顺序处理条件的,把能够过滤更多数据的条件放到前
面,把过滤少的条件放在后面。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章