目标:支持可扩展性。优化数据库的结构来提升查询的性能以及支持表的平滑扩展。
反模式:克隆表与克隆列
1、将一张很长的表拆分成多张较小的表,使用表中某一个特定的数据字段来给这些拆分出来的表命名。
2、将一个列拆分成多个之列,使用别的列中的不同值给拆分出来的列命名。
为了达到减少每张表记录数的目的,你不得不创建一些有很多列的表,或者创建很多很多表。但是在2个方案中,
你会发现随着数据量的增长,会有越来越多的表或者列。
缺点:(1)不断产生新的表。要将数据拆分到不同的表中,需要一个规则来定义哪些数据属于哪些表。
(2)管理数据完整性(不同的表定义不同的约束)。
(3)同步数据时,需要多个操作步骤。
(4)确保唯一性:需要确保所有被分隔出来的表中的主键都是唯一的。如果你需要从一张表中移动一条记录到令一张表中,
需要保证被移动记录的主键值不会和目标表中的主键记录冲突。
(主键如果是自增长的Int类型,则很难保证Id一致;如果是Guid类型,则容易控制)。
(5)跨表查询:时间时间的增长,创建了越来越多的表,就需要不断的更新程序代码来引入这些新创建的表。
(6)同步元数据:如果将表进行了拆分,当新增加一个列的数据,需要再所有的表中增加这个新的列。
(7)管理引用完整性:分隔表及时作为一张关联表而不是父表,也可能引起一些问题。
(8)标识元数据分裂列:列也可能根据元数据分类。可以创建一个含有很多列的表,这些列安装他们的类别扩展。
如何识别反模式:当出现以下情况时,可能是反模式
1、我们需要每……创建一张表或者列?
2、数据库支持的最大数量的表或者列是多少?
3、发现程序添加记录失败了:因为王佳伟新的一年添加新表了
4、如何查询很多张表?每张表的列都是一样的。
【如果你需要查询很多结构一样的表,就应该讲数据全部存储在一个表中,使用一个额外的属性列来分组数据】
5、如何将表名称作为一个表里传递?在查询是需要根据辩分动态的生成这些表名称。
合理使用反模式:
手动分隔表的一个合理使用场景是“归档数据”-----将历史数据从日常使用的数据库中移除。
通常在过期数据的查询变的非常稀少的情况下,才会进行如此的操作。
如果你没有时间同时查询当前数据和历史数据的需求,将老数据从当前活动的表转移到其他地方是很合适的操作。
将数据归档到与当前表结构相兼容的新表中,既能支持偶尔做数据分析时的查询,同时能让日常数据查询边的非常高效。
【 备份并回复一个中等规模的数据库比操作一个存储着TB级数据的数据库要方便得多。
尽管将数据对象模型化并将整个对象中的所有东西映射到一个单独的数据库中的做法没有错,但是合理地将大小超过
临界值的数据库拆分开能简化数据库管理的工作。
】
解决方案:分区并标准化
当一张表的数据量变的非常巨大是,除了手动拆分这张表,可以使用水平分区、垂直分区以及使用关联表来提升查询性能。
1、水平分区(或者叫分片):根据数据行来对表进行拆分。同时不用担心那些分隔表所带来的缺陷。
仅需要定义一些规则来拆分一张逻辑表,数据库会为你管理余下所有的工作。
物理上来说,表的确的被拆分了,但你依旧可以向查询单一表那样执行SQL查询语句。
2、垂直分区:当某些列非常庞大或者很少使用的时候,对表进行按列拆分会比较有优势。
Blob类型与Text类型的列大小是可变的,可能非常大。为了提高存储于查询性能,这些数据库会自动地将
这些类型的列和表中的其他列分开进行存储。如果进行一个不包含Blob类型与Text类型的查询,就可以
更高效的获取其他的列,查询性能有所提高。
3、解决元数据分裂列:创建关联表
结论:别让数据繁衍元数据。
SQL反模式,系列学习汇总