作者:I汽车I生活 | 来源:互联网 | 2023-09-25 11:47
概括
做过mysql数据库的优化、其他数据库类似
定位:查找、定位慢查询
优化手段:
- 创建索引:创建合适的索引,我们就可以现在索引中查询,查询到以后直接找对应的记录。
- 分表 :当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用时,采用水平分表和垂直分表来优化
- 读写分离:当一台服务器不能满足需求时,采用读写分离的方式进行集群。
- 缓存:使用redis来进行缓存
- 一些常用优化技巧
数据库表设计时需要遵循方式
表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF
1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系型数据库(mysql/oracle/db2/sysbase/sql server),就自动的满足1NF.关系型数据库中是不允许分割列的。
2NF:表中的记录是唯一的.通常我们设计一个主键来实现
3NF:即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放.(外键)
反3NF :没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。 订单和订单项、相册浏览次数和照片的浏览次数
索引
171. mysql 索引是怎么实现的?
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。
172. 怎么验证 mysql 的索引是否满足需求?
使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。
explain 语法:explain select * from table where type=1。
分表
分表分为水平(按行)分表和垂直(按列)分表
根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉;水平分表能够很大程度较少这些压力。
按行数据进行分表。
如果一张表中某个字段值非常多(长文本、二进制等),而且只有在很少的情况下会查询。这时候就可以把字段多个单独放到一个表,通过外键关联起来。
考试详情,一般我们只关注分数,不关注详情。
水平分表策略:
1.按时间分表
这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表
一般在有严格的自增id需求上,如按照user_id水平分表:
table_1 user_id从1~100w
table_2 user_id从101~200w
table_3 user_id从201~300w
3.hash分表*****
通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。
读写分离
缓存
在持久层(dao)和数据库(db)之间添加一个缓存层,如果用户访问的数据已经缓存起来时,在用户访问时直接从缓存中获取,不用访问数据库。而缓存是在操作内存级,访问速度快。
作用:减少数据库服务器压力,减少访问时间。
Java中常用的缓存有,
1、hibernate的二级缓存。该缓存不能完成分布式缓存。
- 可以使用redis(memcahe等)来作为中央缓存。
对缓存的数据进行集中处理
数据库引擎
选择合适的存储引擎
在开发中,我们经常使用的存储引擎 myisam / innodb/ memory
MyISAM存储引擎
如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用myisam存储引擎. 比如 bbs 中的 发帖表,回复表.
INNODB存储引擎:
对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表.
Memory 存储
我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快.
问 MyISAM 和 INNODB的区别(主要)
1. 事务安全 myisam不支持事务而innodb支持
2. 查询和添加速度 myisam不用支持事务就不用考虑同步锁,查找和添加和添加的速度快
3. 支持全文索引 myisam支持innodb不支持
4. 锁机制 myisam支持表锁而innodb支持行锁(事务)
5. 外键 MyISAM 不支持外键, INNODB支持外键. (通常不设置外键,通常是在程序中保证数据的一致)
MySQL索引
什么是Mysql索引?
首先:先假设有一张表,表的数据有10W条数据,其中有一条数据是nickname='css',如果要拿这条数据的话需要些的sql是 SELECT * FROM award WHERE nickname = 'css'
一般情况下,在没有建立索引的时候,mysql需要扫描全表及扫描10W条数据找这条数据,如果我在nickname上建立索引,那么mysql只需要扫描一行数据及为我们找到这条nickname='css'的数据,是不是感觉性能提升了好多咧....
mysql的索引分为单列索引(主键索引,唯索引,普通索引)和组合索引.
单列索引:一个索引只包含一个列,一个表可以有多个单列索引.
组合索引:一个组合索引包含两个或两个以上的列,
MySQL锁
联系到多线程中锁的概念,多个事务读同一批数据时也容易出问题,所以也有锁的概念。
不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下)
一般也就听过常说的乐观锁和悲观锁,了解过基本的含义之后就没了~~~
定心丸:即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的。因为这些锁数据库隐式帮我们加了
- 对于
UPDATE、DELETE、INSERT
语句,InnoDB会自动给涉及数据集加排他锁(X) - MyISAM在执行查询语句
SELECT
前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT
等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预
只会在某些特定的场景下才需要手动加锁,学习数据库锁知识就是为了:
- 能让我们在特定的场景下派得上用场
- 更好把控自己写的程序
- 在跟别人聊数据库技术的时候可以搭上几句话
- 构建自己的知识库体系!在面试的时候不虚
175. 说一下 mysql 的行锁和表锁?
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
176. 说一下乐观锁和悲观锁?
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。