`

mysql数据库设计

阅读更多

1. 适度冗余: 让query尽量减少join,如果要减少join,就不可避免的需要通过表字段的冗余来实现,虽然在设计上有违数据库的范式.
通过多次简单的查询来拆分复杂的join操作,给性能所带来的效果是巨大的.

 

在数据表(如订单orders表)里只存储了用户的ID,我要通过这个ID值得到用户昵称该怎么办呢?一个普遍的解决方法是通过联接(join),在查询时,通过id这个唯一条件联接两个表,从而取到用户的昵称。

这样确实是没问题,我也一直觉得这样是最好的方案,扩展方便,当要更新用户信息时,程序中要修改的地方很少,但是随着数据库里数据不断增加,百万,千万, 同时,用户表的数据肯定也在不断的增加的,它可能是十万,百万。这个时候,你会发现两个表通过联接来取数据就显得相当费力了,可能你只需要取一个 nickname这个用户昵称属性,你就不得不去联一下那个已经几十万的用户表进行检索,其速度可想而知了。

 

这个时候,你可以尝试把nickname这个字段加到orders这个订单表中,这样做的好事是,当你要通过订单表呈现一个订单列表时,涉及用户的部分可 能就不需要再进行联接查询了。当然,有利就有弊,这样做的弊端就是,当你尝试更新用户信息时,你必须记得用户信息表里当前被更新的字段中,有哪些是冗余字 段,分别属于哪些表,找到他们,然后加入到你的更新程序段中来。这个是程序中的开销,开销在开发人员的时间上了。至于这样做是否值得,就得看具体情况而定 了。

 

选择哪一种呢?如果你是一个美学狂人,并且财大气粗,非要使用第一种方案,也没关系,这种方案的短板并非不可救药的。比如,你可以增加服务器,从数据库集 群入手,进行读写分离,读的时候可以将压力分散到不同的数据库服务器上,这样也可以获得很好的性能,只是多付出了硬件成本和维护成本。或者,你可以在数据 库前端架设Memcached之类的缓存服务,减少读写数据库的次数,也可以达到同样的效果。问题在于你确定你需要缓存之类的东西。

 

2. 大字段垂直拆分: 要满足这些字段的使用频率远小于那些频繁使用的字段.它和主表之间存一一对应的关系,在join操作时,对性能的影响是比较小的. 原理是,数据库中的读取操作是基于记录,而不是基于字段,这样当我们要读取的数据中包括不需要的字段时,此时数据库其实也花费了时间在那些块头大但实际并 不需要的字段上面.一些原则:如果某个表上的一些字段被频繁的访问,而这个表的某些字段却相对来说比较的”冷清”,那么我们可以通过表的拆分来提升数据库 性能(主要是减少了硬盘的IO操作).

 

3. 合理的数据类型: 使用合理的数据类型,可以减少存储空间,也可以降低IO的操作.同时对于要比较的数据类型,可以加快速度.如TIMESTAMP只 使用四个字节来存放时间,而DATETIME,DATE等使用八个字节.当然TIMESTAMP只可以存储1970之后的时间,如果应用中不需要1970 之前的时间,完全可以采用它.

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics