假设你有个星际游戏,包含飞船组装内容,地图中的星球数据,你会怎么保存,json可以,但对于很大的数据就不合适了, 这时候就推荐数据库了。
如果是游戏,本地的用sqlite,如果是网站,那就用postgresql或其他,至于mysql,用之前记得上网搜搜它的坑。
本章不包含安装教程和基础增删改查语法,这种网上全是教程
本章包含数据库进阶知识,比如索引,事务,锁,时区等等
以下全部按照自己的理解思路编写
事务可以确保你的两个数据库操作,即要么同时成功,要么同时失败
而同一时间的事务肯定不止一个,所以,事务的隔离级别也就是定义别人的事务对你事务的影响
隔离级别通常在创建会话时设置,不设置就是用默认的
-- 设置 会话 事务 隔离 级别 (隔离级别)
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
mysql的默认隔离级别是“可重复读”,其他常见的是“读已提交”
| 隔离级别 | 底层说明 | |————————|:——————| | 串行化(SERIALIZABLE) | 会锁住自己查询范围,直到提交 | | 可重复读(REPEATABLE READ) | 会锁住自己查询到的所有行,直到提交 | | 读已提交(READ COMMITTED) | 读数据库,会在读取时锁住行 | | 读未提交(READ UNCOMMITTED) | 先读其他事务,再读数据库 |
注意:目前有很多数据库都支持使用多版本并发控制(MVCC)来实现快照隔离,这通常比完全锁定的性能更好。
接下来就可以看看不同事务对这些名词的关系了
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| SERIALIZABLE | 不会发生 | 不会发生 | 不会发生 |
| REPEATABLE READ | 不会发生 | 不会发生 | 会发生 |
| READ COMMITTED | 不会发生 | 会发生 | 会发生 |
| READ UNCOMMITTED | 会发生 | 会发生 | 会发生 |
你看,“可重复读”不会发生“不可重复读”的问题
注意,在旧版mysql里,DDL>TRANSACTION,所以当你在事务里删除一个表,回退时这个表不会被还原的哦,哦吼,完蛋
你在今天早上6点起了床,当你的美国朋友查看你的起床时间时,结果是6点,嗯,和他起的一样早……(任何国家的早晨都是当地时间6点)
事实上你在美国的晚上起来的,这就是时区问题,美国比我们晚了6个小时,如果你希望按照美国的时区获取时间,那么你需要处理时区
为了解决上面的问题,我们需要设置当前会话的时区,来确保读取日期时,返回的是当前时区中那个时间
不同数据库设置时区方式不同,比如SQL Server……这个不能设置时区
比如postgresql
SET TIMEZONE = 'Asia/Shanghai';
直接统一存储为UTC时间,根据不同会话的时区,返回不同时区的时间不行吗?
因为有个夏令时问题,在部分地区,如果你不保存时区信息,系统就无法正确知道该事件是在夏令时还是标准时。
不同数据库的类型和作用不一样,但DATE, TIME, DATETIME基本都一样,只保存时间,不包含日期
但比如TIMESTAMP,在postgresql中不带时区,需要TIMESTAMP WITH TIME ZONE才能包含时区信息
而在mysql中,TIMESTAMP返回时根据当前时区返回不同结果,但是存储时仍不带时区,这就会遇到夏令时问题,不愧是你
在sqlserver,TIMESTAMP甚至不是存储时间的,存储日期的是DATETIMEOFFSET
按安装数据库时一般是本地时区,可以手动设置,用于在会话没有设置时区时使用默认时区
在视频网站中,每个点赞都需要插入一条数据,那么可想而知,哔哩哔哩有多少亿个点赞数据了
分表是将大表拆分成多个小表的操作,能够有效减轻单一表的压力,提升查询和插入的效率。
比如按照时间分表,或者按照ID分表,没什么好说的
此外还有个分库操作
针对热点数据,将数据缓存到Redis中,减少数据库查询,可提升查询效率,但要考虑数据一致性
索引是加速数据库查询的关键,可以大大提升数据检索的速度。
读写分离是数据库的优化策略,将读和写分离到不同的数据库服务器上,从而提升数据库的吞吐量。