《MySQL高性能书籍_第3版(中文)》学习笔记


并发控制(锁和事务):
1、读写锁
共享锁(读锁):读锁是共享的,或者说是相互不阻塞的,多个客户在同一时刻可以同时读取同一个资源,而互不干扰。

排他锁(写锁):写锁是排他的,出于安全策略考虑,一个写锁会阻塞其他的写锁和读锁。

2、锁粒度:

锁的各种操作,包括获得锁、检查锁是否已经解除、释放锁等。

锁策略:
表锁:是MySQL中最基本的锁策略,并且是开销最小的策略。

行级锁:可以最大程度地支持并发处理,同时也带来了最大的锁开销。

事务:事务是一组原子性的SQL查询,或者说一个独立的工作单元。换句话说,事务内的语句,要么全部执行成功,要么全部执行失败。

事务的标准特征ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。
原子性:一个事务必须被视为一个不可分割的最小工作单元,要么全部提交成功,要么全部失败回滚。
一致性:数据库总是从一个一致性的状态转换到另一个一致性的状态。
隔离性:一个事务所做的修改在最终提交以前,对其他事务是不可见的。
持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。

事务的隔离级别:未提交读(READ UNCOMMITTED)、提交读(READ COMMITTED)、可重复读(REPEATABLE READ)、可串行化(SEAIALIZABLE)。
READ UNCOMMITTED(未提交读):事务可以读取未提交的数据,也叫脏读,实际中很少使用。
READ COMMITTED(提交读):一个事务从开始直至提交前,所做的任何修改对其他事务都是不可见的,也叫不可重复读,因为两次执行同样的查询,可能结果不同。
REPEATABLE READ(可重复读):保证了在同一个事务中多次读取同样记录的结果是一致的。解决了脏读的问题,但是无法解决幻读问题。
SEAIALIZABLE(可串行化):最高的隔离级别。通过强制事务串行执行,避免了幻读。SEAIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题,实际中很少使用。

脏读(Dirty Read):事务可以读取未提交的数据。
幻读(Phantom Read):指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。

数据类型:

1、基本数据类型

(1)整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT分别使用8,16,24,32,64位存储空间。存储值得范围从-2^(N-1)到2^(N-1)-1,其中N是存储空间的位数
整数类型有可选的UNSIGNED属性,表示不允许负值,可以使正数的上限提高一倍。如TINYINT UNSIGNED可存储范围是0~255,而TINYINT存储范围是-128~127。

(2)实数类型:FLOAT,DOUBLE,DECIMAL。实数是带有小数部分的数字,也可以用于存储整数,如使用DECIMAL存储比BIGINT还大的整数。
FLOAT,DOUBLE类型支持使用标准的浮点运算进行近似计算;
DECIMAL类型用于存储精确的小数。MYSQL5.0和更高版本中的DECIMAL类型允许最多65个数字。
浮点类型在存储同样范围的值时,通常比DECIMAL使用更少的空间。
FLOAT使用4个字节存储,DOUBLE占用8个字节。
DECIMAL尽量只在堆小数进行精确计算时才使用,因为其需要更多的空间和计算开销。
设计中可以适当地考虑使用BIGNIT代替DECIMAL,将存储的金额根据小数位乘以相应的倍数后存储值BIGINT里,这样可以避免DECIMAL精度计算代价高,以及使用浮点存储计算不精确的问题。

(3)字符串类型:VARCHAR和CHAR类型、BINARY和VARBINARY类型、BLOB和TEXT类型
VARCHAR类型用于存储可变长字符串。它比定长类型更节省空间。
采用字符方式存储。
VARCHAR会使用1或2个字节记录字符串的长度:如果列的最大长度小于或者等于255字节,则只需要1个字节表示;否则两个字节。如一个VARCHAR(10)的列需要11个字节的存储空间。
VARCHAR使用场合:字符串列的最大长度比平均长度大很多,列的更新很少。因为由于行是变长的,在UPDATE时可能是行变得比原来更长,那么就导致一个行占用的空间增长,InnoDB就需要分裂页来使行可以放进页内,这就会导致了些额外的工作。

问题:使用VARCHAR(5)和VARCHAR(200)存储"abc"的空间开销是一样的,我们是否可以设置比实际存储大很多?不能。
MYSQL通常会分配固定大小的内存块来保存内部值,使用更长的列会消耗更多的内存。
尤其是使用内部临时表进行排序或操作时会特别糟糕,在利用磁盘临时表进行排序时也同样糟糕。
所以最好的策略是只分配真正需要的空间。

CHAR类型是定长的,存储时,CHAR值会根据需要采用空格进行填充以方便比较。
采用字符方式存储。
CHAR适合存储很短的字符串或者所有值都接近同一个长度。
对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。
对于非常短的列,CHAR也比VARCHAR在存储空间上更有效率,例如CHAR(1)存储Y/N,如果采用单字节字符集只需要一个字节,但VARCHAR(1)需要两个字节,因为还有一个记录长度的额外字节。

BINARY和VARBINARY类型,存储方式为二进制字符串。二进制比较对大小写敏感,且根据一个个字节的数据进行比较,比字符比较更简单更快。

BLOB:TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB,存储很大的数据的字符串数据类型,采用二进制方式存储。

TEXT:TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT,存储很大的数据的字符串数据类型,采用字符方式存储。

尽量避免使用BLOB和TEXT类型,因为Memory引擎不支持BLOB和TEXT类型,如果查询使用了BLOB和TEXT列并需要使用隐式临时表,将不得不使用MyISAM磁盘临时表,这样会导致严重的性能开销。

如果EXPLAIN执行计划的Extra列包含“Using temporary",则说明这个查询使用了隐式临时表。

(4)日期和时间类型:DATA、DATATIME、TIME、TIMESTAMP、YEAR
DATETIME:保存范围从1001年到9999年,精度为秒,它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关。使用8个字节的存储空间,默认显示格式为"2019-07-08 14:49:15"。
TIMESTAMP:保存范围从1970年到2038年。使用4个字节存储空间。精确到秒或者毫秒时,显示的值依赖于时区,按照DATETIME的方式格式化。
DATE:保存范围从1601-01-01到9999-01-01,只精确到天,格式YYYY-MM-DD,如“2019-07-08”。
TIME:保存范围从00:00:00到23:59:59,格式HH:mm:ss。
YEAR:保存范围为1901到2155,存储年。

优质内容筛选与推荐>>
1、25种提高网页加载速度的方法和技巧
2、[Z] 用GDB调试程序
3、Server Application Error 解决方案
4、从I/O事件到阻塞、非阻塞、poll到epoll的理解过程
5、ListBox控件


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号