第一篇-数据库相关
1、springboot的自动配置原理
1、@SpringBootConfiguration 本质上是@Configuration
2、@EnableAutoConfiguration
2、分布式锁的三种实现方式:
1、基于数据库
2、基于redis实现分布式锁
3、基于zookeeper实现分布式锁
automic 是通过cas来进行原子性
3、并发编程中的三个概念
-
原子性
一个或者多个操作,要么全部执行完成,要么全部执行失败
-
可见性
多个线程同时访问同一个变量时,一个线程修改了值,其它线程能够立即看到修改之后的值
-
有序性
程序按照代码的先后顺序执行。
4、mysql数据库的优化
-
选择合适的字段属性
-
尽量把字段设置为NOT NULL
-
使用连接join来代替子查询
-
使用联合(Union)来代替手动创建的临时表
-
事务
-
使用索引,一般来说,索引应该建立在那些将用于join,where判断和orderby排序的字段上
5、事务必须满足的四个条件:
-
原子性:一个事务中的所有操作,要么全部成功,要么全部失败
-
一致性:事务开始之前和事务结束之后,数据的完整性不会被破坏
-
隔离性:数据库允许多个事务同事对数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行导致数据的不一致。
事务的隔离分为不同的级别:读未提交、读已提交、可重复读和串行化
- 持久性:事务处理结束后,对数据的影响是永久的。
6、事务的并发问题
- 脏读:事务A读取了事务B更新的操作,然后B回滚操作,事务A读取的就是脏数据
- 不可重复读:事务A多次读取同一数据,事务B在事务A读取的过程中,多次对事务A读取的数据进行了更新的操作,导致事务A多次读取的数据不一致。
- 幻读:事务A将数据更新的时候,事务B插入一条新的数据。导致新插入的这条数据没有被更新到,就像是发生了幻觉一样,这就叫幻读。
小结:不可重复读和幻读很容易搞混淆,不可重复是修改数据的更新造成的,幻读是新增或者删除数据造成的。解决不可重读的问题只需要锁住满足的条件就行了,解决幻读需要锁表
事务的隔离级别:
事务的隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | ✔ | ✔ | ✔ |
不可重复读 | × | ✔ | ✔ |
可重复读 | × | × | ✔ |
串行化 | × | × | × |
mysql的默认隔离级别是可重复读
7、sql优化
-
对查询优化要尽量避免全表扫描,首先考虑在where和order by涉及的列上创建索引
-
尽量避免在where字句对字段进行null值判断,这样会导致引擎弃用索引而全表扫描
-
尽量在where字句中使用 != 或者<> ,这样将会导致弃用索引而全表扫描
-
避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
-
in 和 not in 也要慎用,否则会导致全表扫描
用 exists 代替 in 是一个好的选择
对于连续的数值,能用 between 就不要用 in
-
避免使用 like '% %' 查询全表扫描
-
如果在 where 子句中使用参数,也会导致全表扫描
select id from t where num = @num
-
避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
-
避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描
-
不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
-
在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
-
Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志
-
索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要
-
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了
-
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
-
任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段
-
在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
-
尽量避免大事务操作,提高系统并发能力。
8、MySQL数据库引擎InnoDB和MyISAM区别
-
存储结构
MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件,这个具体要看
独立表空间是否默认开启
,如果默认开始(5.7已经默认
),那便是多个文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。 -
存储空间
二者的存储区别其实也就是聚簇索引和非聚簇索引的区别
MYISAM索引和数据是分开的
,而且其索引是压缩的,可以更好地利用内存。所以它的查询性能明显优于INNODB。压缩后的索引也能节约一些磁盘空间。MyISAM缓存在内存的是索引
,不是数据。而InnoDB缓存在内存的是数据,相对来说,服务器内存越大,InnoDB发挥的优势越大。InnoDB:
索引和数据是在一起的,都在ibd文件中
,需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 -
可移植性、备份及恢复
MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。
-
事务支持
MyISAM:强调的是性能,每次查询具有原子性,其执行速度比InnoDB类型更快,但是
不提供事务支持
。InnoDB:
提供事务支持事务,外键等高级数据库功能
。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 -
联合索引
MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长也必须是组合索引的第一列。
-
表锁差异
MyISAM:
只支持表级锁
,用户在操作MyISAM表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。InnoDB:
支持事务和行级锁
,是InnoDB的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在Where的主键是有效的,非主键的WHERE都会锁全表的。 -
全文索引
MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
-
表主键
MyISAM:保存有表的总行数,如果
select count(*) from table;
会直接取出出该值。InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了where条件后,MyISAM和InnoDB处理的方式都一样。
-
CURD操作
MyISAM:
如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。
-
外键
MyISAM:不支持
InnoDB:支持
总结:
通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。
一些关于MyISAM与InnoDB选择使用:
MYISAM和INNODB是Mysql数据库提供的两种存储引擎。两者的优劣可谓是各有千秋。INNODB会支持一些关系数据库的高级功能,如事务功能和行级锁,MYISAM不支持。MYISAM的性能更优,占用的存储空间少。所以,选择何种存储引擎,视具体应用而定。
如果你的应用程序一定要使用事务,毫无疑问你要选择INNODB引擎
。但要注意,INNODB的行级锁是有条件的。在where条件没有使用主键时,照样会锁全表。比如DELETE FROM mytable这样的删除语句。如果你的应用程序对查询性能要求较高,就要使用MYISAM
了。MYISAM索引和数据是分开的,而且其索引是压缩的,可以更好地利用内存。所以它的查询性能明显优于INNODB。压缩后的索引也能节约一些磁盘空间。MYISAM拥有全文索引的功能,这可以极大地优化LIKE查询的效率
。有人说MYISAM只能用于小型应用,其实这只是一种偏见。如果数据量比较大,这是需要通过升级架构来解决,比如分表分库,而不是单纯地依赖存储引擎。
其他一些说法:
现在一般都是选用innodb了,主要是myisam的全表锁,读写串行问题,并发效率锁表,效率低,myisam对于读写密集型应用一般是不会去选用的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示