之前通过视频网站买了mysql优化技能,学习完毕以后收获颇丰,才明白之前用的MySQL都是瞎用,只有了解之后你才能知道什么存储引擎适合什么系统,什么情况下应该加索引什么情况下不加索引,索引用什么sql语句会失效,用什么sql语句会有效,庞大的数据表或者是高并发压力是用分库分表还是读写分离等等等等,反正对数据库是有新的认识了!今天我就来总结第一篇MySQL基础知识。
1.数据库设计就是建表时的类型的选择,MySQL的数据类型支持的非常多,选择正确的数据类型对于获得高性能至关重要。一般情况下,应该尽量使用可以正确存储的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘、内存、CPU和缓存,并且处理时需要的CPU周期也更少
2.数据库存储引擎有多种,举例 MyISAM:不支持事务,表级锁。InnoDB:事务级存储引擎,完美支持行级锁,事务ACID特性;ps表级锁锁住一整张表,行级锁只锁住某一列,那么正常情况下使用表还是行级锁性能要高啊!
3.SQL语句的编写能大大提高性能
4.数据库参数配置 ,数据库参数也很重要比如说设置最大的连接数啊,缓存数据啊等等
5.服务器操作系统与硬件,这个就不用解释了服务器硬件好那程序应用也高
mySql分为有符号(SIGNED)和无符号(UNSIGNED),如果int值不会出现负数的话,可以选择无符号,无符号代表数字可以取值是0和正数,有符号会可以是负数。
一般情况下表的自增id都要设置成bigint,因为表的数据无限增长那么设置最大的范围比较合适,如果有表设计字段比如是is_Del是否删除0是未删除、1是已删除,像这样的就应该使用thinyint存储空间小取值范围也小就很适合
下图是整数类型信息和取值范围
因为需要额外的空间和计算开销,所以应尽量只在对小数进行精确计算时才使用DECIMAL —— 例如财务数据。但在数据量比较大的时候,可以考虑使用BIGINT 代替 DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可,这样可以避免浮点存储计算不精确和DECIMAL 精确计算代价高的问题。
varchar 变体长度,根据实际内容保存数据
char属于定长数据,char定义好以后就不会发生长度改变
若定义一个字段为timestamp,这个字段里的时间数据会随其他字段修改的时候自动刷新,所以这个数据类型的字段可以存放这条记录最后被修改的时间。
反范式设计就是为了让sql更加的简便而出现的,故意的增加表冗余,让sql语句变的更简单
事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。
如:张三给李四转账,必须是张三扣钱、李四加钱这两个环节一起完成,这两个动作必须是原子化的,要么都成功,要么都失败
事务开始前和结束后,数据库的完整性约束没有被破坏。
如:上面转账的例子,双方必须保持一致,不能说张三的钱被扣了,但是李四的钱没有加上,这样就会导致数据错乱
同一时间,只允许一个事务请求同一个数据,不同的事物之间彼此没有任何干扰
如:在张三转账这个事务没有完成之前,其他事务看到张三的钱不会变少,假设开始有100元,那么在他没完成转账之前,看到的还应该是100元
事物完成后,事物对数据库的所有更新将被保存到数据库,不能回滚。
如:转账完成之后,数据就会固定下来,不可回滚,此时其他事务可以正确看到张三扣钱之后的金额
一个事物可以读取另一个未提交事物的数据。由于只要库里数据改变没有提交都会被读取,所以就会出现脏读。甚至不可重复读,幻读,所以很少使用此。
事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。
一个事务要等另一个事物提交后才能读取数据。在读的时候,若有事务对数据进行更新(update)操作时,读操作事务要等待这个更新操作事物提交之后才能读取事务可以解决脏读问题,但是以下例子中出现了一个事务范围内两个相同的查询却返回了不同的数据,这个是不可重复读。
事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他买单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。
事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他买单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。
分析:重复读可以解决不可重复读,不可重复读对应的是修改,即UPDATE操作。但是还有可能出现幻读问题,幻读问题对应的是插入insert操作,而不是UPDATE操作。
事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。
Serializable是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读、幻读,但是这种事务级别效率低下,比较耗数据库性能,一般不使用。Serializable(序列化)不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、不可重复读和幻读的问题了;
MySQL基本知识就记录到这里。