在设计数据库时,某一字段属于一个表,但它又同时出如今另外一个或多个表,且彻底等同于它在其原本所属表的意义表示,那么这个字段就是一个冗余字段。前端
——以上是我本身给出的定义数据库
冗余字段的存在究竟是好仍是坏呢(缓存
冗余是为了效率,减小join。单表查询比关联查询速度要快。
某个访问频繁的字段能够冗余存放在两张表里,不用关联了。
)?这是一个很差说的问题。可能在有人看来,这是一个很蹩脚的数据库设计。由于在数据库设计领域,有一个被你们奉为圭臬的数据库设计范式,这个范式理论上要求数据库设计逻辑清晰、关系明确,好比,”用户昵称”字段”nickname”原本属于表”user”,那么,表示”用户昵称”的字段就惟一的只应该属于”user”表的”nickname”字段,这样,当用户要修改昵称的时候,程序就只须要修改 user.nickname这个字段就好了,瞧,很方便。不过问题也随之而来,我在其余数据表(如订单orders表)里只存储了用户的ID,我要经过这个ID值获得用户昵称该怎么办呢?一个广泛的解决方法是经过联接(join),在查询时,经过id这个惟一条件联接两个表,从而取到用户的昵称。服务器
这样确实是没问题,我也一直以为这样是最好的方案,扩展方便,当要更新用户信息时,程序中要修改的地方不多,可是随着数据库里数据不断增长,百万,千万,同时,用户表的数据确定也在不断的增长的,它多是十万,百万。这个时候,你会发现两个表经过联接来取数据就显得至关费力了,可能你只须要取一个nickname这个用户昵称属性,你就不得不去联一下那个已经几十万的用户表进行检索,其速度可想而知了。数据库设计
这个时候,你能够尝试把nickname这个字段加到orders这个订单表中,这样作的好事是,当你要经过订单表呈现一个订单列表时,涉及用户的部分可能就不须要再进行联接查询了(变成了单表查询)。固然,有利就有弊,这样作的弊端就是,当你尝试更新用户信息时,你必须记得用户信息表里当前被更新的字段中,有哪些是冗余字段,分别属于哪些表,找到他们,而后加入到你的更新程序段中来。这个是程序中的开销,开销在开发人员的时间上了。至于这样作是否值得,就得看具体状况而定了。性能
因此,目前要建立一个关系型数据库设计,咱们有两种选择:spa
选择哪种呢?若是你是一个美学狂人,而且财大气粗,非要使用第一种方案,也不要紧,这种方案的短板并不是不可救药的。好比,你能够增长服务器,从数据库集群入手,进行读写分离,读的时候能够将压力分散到不一样的数据库服务器上,这样也能够得到很好的性能,只是多付出了硬件成本和维护成本。或者,你能够在数据库前端架设Memcached之类的缓存服务,减小读写数据库的次数,也能够达到一样的效果。问题在于你肯定你须要缓存之类的东西。设计