Woooowen You can do anything you set your mind to, man

数据库设计需要注意的地方

数据库表结构的设计非常的重要,因为表设计的好坏将直接影响你项目的性能。

  • 1.适度冗余。关系型数据库的规范化范式最根本的目的就是尽量的去处冗余数据,保持数据的一致性,方便数据更新。避免数据不一致从而出错。但是有的时候就不能不反范式设计。当初定义范式的时候有一部分原因是保持数据的一致性,但还有个重要的原因就是因为当初的存储空间有限。存储设备都很小。所以尽量避免数据冗余。而现在我们完全不必为了存储空间而烦恼。TB的存储设备随处可见。所以我们要做的就是从需求出发,以性能为根本来设计表。以空间换时间。

众所周知Join的操作是非常的消耗数据库性能的。所以我们要尽量避免使用Join操作。而减少Join操作就不得不通过表字段的冗余来实现。

说到避免使用Join字段,就不得不拆分一整条复杂的Join 语句。如果拆分Join语句,就要通过多次简单的查询来实现Join的逻辑。那肯定要增加网络的开销。这就要靠你自己去把控了。其实优化就是在两个极端的点之间选取最合适的那个点。

  • 2.垂直拆分。举个最简单的例子。论坛的帖子。论坛的帖子列表页的PV肯定要比单个帖子的详细页要多。访问的人多了。那么他的性能如何就至关重要。而列表页是不需要显示帖子内容的。(大部分都是只显示一个帖子title就ok了)。所以你需要做的就是在表中将帖子的内容字段拆分出去。或者存入单独的一个表中。为什么?都知道帖子的内容字段一定是个大字段。包含了很长的信息。而访问数据库的时候不是只访问你定义的那几个字段。他会读取全部的字段然后再返回你所需要的那些字段。所以如果你的表设计中有个很大的字段,那么带来的性能影响可想而知。(如果可以索引中完成查询的情况除外)大字段所占的空间比例非常的大,浪费的IO资源也就相当大。因此我们需要将他们拆分出去。 如文章内容,帖子内容,产品的信息,产品介绍等等。

当然字段大只是其中的一点。你将大字段拆分出去,那么要读取他的时候就必须通过Join操作。而上面也说了尽量避免Join操作。所以选择那些个拆分的字段不光光要大。而且也要访问的频率不是那么高。那么就可以选择奖他拆分出去。我们所做的优化是为了全局的性能提升,而不是单一的操作提升。牺牲一点而带来全局的提升是值得的。当然不仅仅非要是大字段。如果你一个表中一些字段的访问频率非常高。而一些访问频率很低。你也可以考虑将他们拆分出去。单独的存在。使用Join操作来读取。

  • 3.水平拆分。当某些个数据的访问量很高,而更新频率很低那么你可以试着将他们单独的创建一个表来存储。例如论坛的置顶帖子。置顶的帖子数量少,访问频率高,更新频率低。单独存放在表中。Mysql读取他们的时候将会使用Mysql的Query Cache。而如果你将他们和更新频率高的数据存放在一起,那么就会频繁地更新不适用Query Cache。

  • 4.准实时优化。对于不需要实时更新的数据。可以通过这个方法来,都知道实时更新,每次都需要连接数据库查询,然后更新数据,这样带来的资源消耗是非常大的。对于那么用户不是特别需要的数据。可以使用准实时来存储一些个。

  • 5.合适的数据类型。当数据量非常大时数据库的检索查询效率就会变低,而如果你选择合适的数据类型,那么数据库的存储空间也会更小。对于检索同样的数据所带来的IO消耗自然也会降低,性能也会自然得到提升。这里说下CHAR类型和TEXT类型。CHAR类型是静态长度类型,存放的长度是固定的。如果存放的长度没有255个字节,那么就会存放空格来代替。但是Mysql在读取的时候会自动忽略最后的所有空格。而超过255字节的存储将会直接拒绝并且报错。在以前的版本中Mysql Char类型在存入超过255个字节的数据时会自动转换成TEXT存储。现在不会了。 另外我们公司的架构师老大说尽量使用Varchar来代替TEXT字段。

  • 6.最后要注意的就是数据库表名的命名尽量加上前缀。以及要有可读性良好的命名。加索引的使用尽量使用idx或者ind来作为前缀。后期维护的时候是个好事。还有就是做好数据字典。

Woooowen 浙ICP备15013647号