目录
11、当自增主键id达到最大值时,如果继续插入数据,会是什么结果?
13.2、Dependent subquery:子查询
14、一个自增表有5条数据,id为1到5,删除id为4和5的数据,重启MySQL,又新增一条数据,新增的数据id为几?
悲观锁:对数据的冲突采取一种悲观的态度,始终假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住;
乐观锁:认为数据一般情况下不会造成冲突,在数据进行提交更新的时候,才会对数据的冲突与否进行检测,如果发现冲突了,才返回错误信息。
Mysql乐观锁实现:
为数据表增加一个版本标识(int),当读取数据时,同时独处版本标识,数据每更新一次,版本标识加1;更新前,需将读取的版本标识与数据库当前版本标识进行对比,相等的情况下才予以更新,否则操作的就是过期数据;
Mysql悲观锁实现:
首先需关闭mysql的自动提交属性(autocommit),在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。在不同的事务中同时执行包含上面两个关键字段的查询语句时,后开启的事务会被阻塞,直到先开启的事务关闭。
Java乐观锁实现:
冲突检测和数据更新。典型的是Compare and swap(CAS),当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其他线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。
Java悲观锁实现:
Synchronized。
From,on,join,where,group by,having,select,distinct,order by,limit
在where和order by涉及的列上建立索引;
避免在where子句中对字段进行null值判断(空值判断会放弃使用索引而导致全表扫描)
避免在where子句中使用!=,<>操作符和来or连接条件(原因同上);
In和not in也会导致全表扫描;
模糊查询时的%也会导致全表扫描;
在where子句中对字段进行表达式或函数操作会导致全表扫描

散列连接,适用于join的两个表数据量相差很大的情况;
排序合并连接,适用于不等价关联(>,<,>=,<=,<>)、HASH_JOIN_ENABLED=false、没有索引且数据已经排序的情况。
嵌套循环连接,适用于驱动表的记录集比较小(<10000)且内表关联列存在索引的情况。JOIN的顺序很重要,驱动表的记录集一定要小,返回结果集的响应时间是最快的。
小表驱动大表,小表在前可提高执行效率。
左连接的驱动表就是左边的那个表,右连接的驱动表就是右边的那个表。
解释1:通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。
解释2:驱动表查询出数据需要一条一条的加入到join_buffer中,这需要IO操作,比较耗时,因此如果驱动表比较小,那么效率就高,这是小表驱动大表的一个主要原因。
MyISAM专注性能,InnoDb专注事务。两者最大的区别就是InnoDb支持事务和行锁。

其他:
InnoDB为聚集索引,索引和数据文件绑定在一起,必须有主键。
InnoDB的存储文件为frm(表结构)、ibd(表的数据和索引)。
一般来说,如果需要事务支持、大量的update或delete操作,则选择InnoDB。
最多1017列,最多创建64个二级索引,单个索引最多包含16列。
最多4096列,最多创建64个二级索引,单个索引最多包含16列。
binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。

基于SQL语句的复制,每一条会修改数据的SQL都会记录在binlog日志中。
不记录sql语句及上下文信息,仅保存哪条记录被修改了。
一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。
delete操作后,如果磁盘空间未被释放,会在下次增加数据时继续使用。
存储过程是能完成一定操作的一组SQL语句。
优势:
一般的SQL语句每一次使用都需要进行编译,而存储过程只在创建时进行编译,之后执行可直接使用,进而提高数据库的执行速度。
封装复杂的数据库操作。
可以重复使用,减少数据库开发人员的工作量。
安全性高,可设定指定用户使用权限。
Select *from (select *from table1 where age = 11) where height > 170
视图可以理解成虚拟的表,是由数据库中实际的表通过select查询得来。比如,上面所示的SQL语句中,红色字体就可以抽象成一个视图。
通过:create view age_11 as select *from table1 where age = 11,就得到了一个名称为age_11的视图,在后续的操作中就可以直接使用age_11视图(select *from age_11 where height >170)。
规范的数据库设计应该遵守的规则和指导方法。
再次插入时,主键自增ID为最大id,报主键冲突的错误。
正常情况下,自增主键为1,2,3,删除3后,下一个肯定为4,主键不回溯;
回溯情况下,自增主键为1,2,3,删除3后,数据库重启,那下一个主键值为3。
TIMESTAMP优点是带有时区属性,缺点是它的最大值2038年已经快要到了。此外TIEMSTAMP需要通过时区计算时间,调用底层函数__tz_convert时会加锁,高并发访问时,性能也会有问题。
问题:回溯、分布式环境下存在主键不唯一,公开主键值,容易泄露数据。
值为1:每条SQL结束后释放自增锁;
值为2:每次自增释放自增锁。
举例:如果一条Insert语句插入了10条数据,如果mode值为1,那么只需要进行一次获取/释放锁的操作;如果mode值为2,那么久需要进行10次获取/释放锁的操作。
UUID_TO_BIN:将时间高位放在前面,解决了UUID插入时乱序问题。二进制存储,精简了存储空间。
BIN_TO_UUID:将二进制值反转为UUID字符串。
一个页中存放的记录数越多,数据库性能越好。页存放在磁盘上,MySQL数据库要先将磁盘中的页读取到内存缓冲池,然后以页为单位来读取和管理数据。页中存放数据越多,可减少磁盘IO,从而提升性能。
ROW_FORMAT=COMPRESSED:启动页压缩;
KEY_BLOCK_SIZE=8:压缩大小。
COMPRESS页压缩:对性能不敏感,只对存储空间有要求(比如日志表、监控表等)。
TPC压缩:对存储有压缩需求,又希望不影响性能,推荐使用TPC压缩。
性能的差异在于驱动表的不同。
如果主查询中的表较大且又有索引,子查询得出的结果集记录较少时,应该用in;反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
select * from A where A.ID in(select B.ID from B )
首先执行一次子查询,子查询先产生结果集;
然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出。
select * from A where exists(select 1 from B where A.ID=B.ID)
首先执行一次外部查询;
对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值;
当执行计划中有DEPENDENT SUBQUERY时,表示这是一个依赖子查询,执行速度通常特别慢,需要手动转化成两张表的关联查询:Join。
事务不能太大,否则会导致二进制文件很大,事务提交慢。
把大事务拆成小事务。
以上内容为个人学习理解,如有问题,欢迎在评论区指出。
部分内容截取自网络,如有侵权,联系作者删除。