当前位置:首页 > Mysql教程 > 列表

高手谈数据库设计优化策略教程

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-20 11:14:54 浏览: 评论:0 

数据库设计是建立数据库及其应用系统的技术,是信息系统开发和建设中的核心技术,由于数据库应用系统的复杂性,为了支持相关程序运行,数据库设计就变得异常复杂,因此最佳设计不可能一蹴而就,而只能是一种“反复探寻,逐步求精”的过程.

1)范式和反范式

第一范式:每一列都是一个不可分割的原子数据项.

第二范式:第一范式基础上消除部分依赖.

第三范式:第二范式基础上消除传递依赖.

反范式是针对第三范式来说的,通过添加冗余的方式破坏了第三范式,前两个范式还是要遵循的.

范式的优点:

a.写入快,因为不需要写冗余数据,所以减少了写的负担.

b.更新快,因为通常只需要更新更少的数据.

c.由于没有冗余,所以不会造成数据不一致.

d.更少的需要GROUP BY和DISTINCT。

缺点是:需要关联.

范式的缺点,就是反范式的优点,不需要关联,并且因为在同一个表中,可以设计合适的索引,实际应用中通常不会采用完成的范式,而是放置一些冗余,以减少表与表的关联,加快查询速度.

笔者之前所从事的项目中,数据包含定义态的和实例态的,实例态的冗余了定义态的数据,实例态又分多个级别,低级别的实例表,冗余了高级别表的数据,这样在一个事务中都是单表查询,减少了表关联.

2)分表

如果表中的数据有状态,比如完成态和运行态,那么可以考虑将表分为运行态和完成态数据,数据转换到完成态时可以将数据归档到完成态表中,由于数据总是要运转到完成态,所以这样无论系统运行多长时间,运行态表中的数据几乎都是恒定的,而且完成态的数据除了统计分析用外,几乎不不需要查询,这样就大大提高了系统运行的速度,表中的数据量得到了控制。

另外对于统计分析的场景,为了减少表的union 可以要求业务查询从运行态和完成态两种状态中二选一,对于一些海量数据,也可以考虑根据某个字段的值做hash,来分表存储,当然这加大了应用的复杂度,这没办法,通常没有十全十美的办法,架构就是根据实际应用场景做权衡,正所谓忠孝不能两全,只是某种办法更合适而已。

另外可以通过分布式数据库解决分表的问题,由分布式数据库自动分表存储,查询时自动合并,由分布式数据库中间件类屏蔽复杂性,各种脏活、累活交给它就是了。

3)汇总表

对于一些大数据量的报表统计工作,如果不是要求实时的话,可以定期汇总,比如每小时汇总一次或者每天汇总一次,如果要求实时的话,由于各种大表,各种group by,不但统计非常慢,而且容易影响正常的业务操作。笔者之前待的公司,每天晚上都开各种各样的定时任务进行数据汇总,在数据库不太忙的晚上,从12点干到早上6点,定时任务排的满满的,真是累死它的节奏啊,还好计算机不会闹脾气,发飙。。当然这样报表统计的数据是截止到昨天的,每次都晚一天,通常这是允许的。

4)计数器表

web应用为了记录点击次数,可以设计一个点击次数表,create table hit_counter(cnt int unsigned not null);由于只有一条记录这样锁争用太严重,想到了什么解决方案,同concurrenthashmap一样做锁拆分。

表结构修改为:

create table hit_counter(slot tinyint unsigned not null primary key,cnt int unsigned not null);--phpfensi.com

预先放入100条数据,这样修改的时候可以使用如下语句,update hit_counter set cnt = cnt+1 where slot = RAND()*100;获取的时候求和就可以了,select sum(cnt) cnt from hit_counter;不知道iteye的博客计数是不是也采用了类似的设计.

Tags: mysql优化 mysql设计

分享到: