19.优化数据库对象
19.1 优化表的数据类型
应用设计时需要考虑字段的类型和长度,并留有一定长度冗余。
procedure analyse()函数可以对表中列的数据类型提出优化建议。
procedure analyse()函数用法:
select * from 表名 procedure analyse(); -- 对所有列提出优化建议
select * from 表名 procedure analyse(16,256); -- 不对包含16至256取值的枚举列提出建议
分析的结果是针对每个列,输出该列的最小值、最大值、最小值长度、最大值长度、空字符串或0的个数、null的个数、平均值、方差、优化建议。
注意:该函数只对已存在的表,且包含大量记录时分析有效,这样的表对类型修改时一定要注意DDL锁表的问题。
该函数不能在设计阶段给出类型和长度建议。
19.2 通过拆分提高表的访问效率
对表拆分分为:垂直拆分和水平拆分。
垂直拆分指将主键和常用列放在一张表中(主表),将主键和非常用列放在另一张表中(从表)。
如果从表中除主键列意外所有列都是无效取值(空字符串、null、0),则不需要保存该行信息,所以从表的记录量比主表少,从而优化存储空间。
在查询时如果只从主表查找,则优化查询速度;如果要从主表和从表连接查找,则产生了left join。
并且拆表后主键同时存储在两张表中,增加的冗余,即增加了程序对冗余的管理和事务的管理。
水平拆分指根据一个列或多个列的数据值将数据存放到两个同构且独立的表中。
水平拆分适用场景:表很大,表中数据有独立性,需要把数据存放在多个介质上。
如果查询与分表的依据一致,则只需要在一个分表中执行,优化了速度。
如果查询与分表的依据不一致,则只需要在多个分表中执行并将结果union all在一起,增加了业务复杂度。
水平拆分需要考虑数据量的增长速度。
19.3 逆规范化
规范化保证数据的一致性、完整性,避免数据的冗余,不一致等。
规范化带来的问题是查询时可能产生多表关联,影响查询速度。
逆规范化指通过增加冗余列、派生列或重组表、分割表来提升查询速度,但需要应用程序来保证数据的一致性和完整性。
冗余列:指在多个表中具有相同的列,常用来避免连接查询。例如:给emp表增加dname列,则dname同时存在于emp表和dept表。
派生列:指该列可由其它列计算生成,常用来避免在查询中实时计算。例如:年龄=当前日期-出生日期,年薪=月薪*12。
重组表:指将用户需要查看的多个表连接的结果构造成一张表,常用来避免连接查询,缺点需要实时或定时从查询的多张表向该表同步数据。
分割表:指垂直分割和水平分割。
规范化带来的问题是数据的一致性、完整性不能保证,维护的方法分为:批处理存储过程实现、应用逻辑实现、触发器实现。
批处理存储过程实现:是指定期调用存储过程来更新冗余列、派生列、重组表、拆分表等信息。缺点:实时性不高。
应用逻辑实现:指应用程序在同一个事务内完成本业务和冗余列、派生列、重组表、拆分表的DML操作。缺点:业务逻辑复杂、开发难度大、容易遗漏、数据完整性风险大。
触发器实现:对数据的DML操作立即出发对冗余列、派生列、重组表、拆分表的DML操作,业务逻辑扩展简单、实时性高。缺点:数据库维护难度大,项目数据库迁移难度大。
19.4 使用中间表提高统计查询速度
指先复制业务表及其数据,然后在复制的表(中间表)上进行统计操作。
优点:不影响业务。
缺点:增加存储空间,有一个表和数据的复制过程。
19.5 小结
数据库设计是应用程序的基础,前期设计的好坏影响应用程序的整个生命周期及数据质量。
越到后期的数据库设计调整,对业务影响越大。