数据库表设计对性能的影响

很多人看来,数据库Schema设计是一件非常简单的事情,大体按照系统设计时候的相关实体对象对应成一个一个表格就可以了。为了在功能上尽可能容易扩展,根据数据库范式规则进行调整,做到第三范式或第四范式,基本就算完事了

真的这么简单么?看一个案例

需求概述:一个简单的讨论区系统,需要有用户、用户组、组讨论区这三部分基本功能

简要分析:

(1)须要存放用户数据的表;

(2)须要存放分组信息和用户与组关系的表;

(3)须要存放讨论信息的表

方案一:分别用4个表来存放用户、分组、用户与组关系,以及各组的讨论帖子的信息,如下所示。

user用户表:

id 

nick_name 

password 

email 

status 

sexuality 

msn 

sign 

birthday  

hobby 

location 

description

groups分组表:

id 

gmt_create 

gmt_modified 

name 

status 

description  

user_group关系表:

user_id 

group_id 

user_type 

gmt_create 

gmt_modified 

status

group_message讨论组帖子表:

id 

gmt_create 

gmt_modified 

group_id 

user_id 

subject 

content

方案二

user用户表:

id 

nick_name 

password 

email 

status

user_profile用户属性表(记录与user一一对应):

user_id 

sexuality 

msn 

sign 

birthday  

hobby 

location 

description

groups和user_group这两个表和方案一完全一样

group_message讨论组帖子表:

id 

gmt_create 

gmt_modified 

group_id 

user_id 

subject 

author

group_message_content帖子内容表(记录与group_mes-sage一一对应):

group_msg_id 

content

区别主要体现在两点上

一个是在group_message表中增加了author字段来存放发帖作者的昵称,与user表的nick_name相对应

另一个就是第二个方案将user表和group_message表都分拆成了两个表,分别是一一对应的

方案二看上去比方案一要更复杂一些,首先是表的数量多了2个,然后是在group_message中冗余存放了作者昵称

一个讨论区系统,访问最多的页面会是什么?是帖子标题列表页面。而帖子标题列表页面最主要的信息都来自group_message表中,同时帖子标题后面的作者一般都是通过用户名(昵称)来展示的。按照第一种解决方案设计,须要执行类似SQL

SELECT t.id, t.subject,user.id, u.nick_name
FROM (
    SELECT id, user_id, subject
    FROM group_message
    WHERE group_id = ?
    ORDER BY gmt_modified DESC LIMIT 20
) t, user u 
WHERE t.user_id = u.id

但是第二种解决方案就会简单很多

SELECT t.id, t.subject, t.user_id, t.author
FROM group_message
WHERE group_id = ?
ORDER BY gmt_modified DESC LIMIT 20

不仅如此,由于一方案中的group_message表中包含一个大字段“content”,该字段所存放的信息要占整个表的绝大部分存储空间,但在这条系统中执行最频繁的Query完全不需要该字段所存放的信息,可是这个Query没办法不访问group_message表的数据,所以第一条Query在数据读取过程中会须要读取大量没有任何意义的数据

在系统中用户数据的读取也是比较频繁的,但是大多数地方需要的用户数据只是几个基本属性,如用户的id、昵称、密码、状态、邮箱等,所以将用户表的这几个属性单独分离出来,也会让大量的Query语句在运行的时候减少数据的检索量,从而提高性能

可能有人会觉得,将一个表分成两个表,如果要访问被分拆出去的信息,性能不是就会变差了吗?是的,但是由于两个表都是一对一的关联关系,关联字段的过滤性也非常高,而且这样的查询需求在整个系统中所占有的比例也并不高,这里带来的性能损失实际上要远远小于在其他Query上节省出来的资源

原文发布于微信公众号 - 性能与架构(yogoup)

原文发表时间:2015-07-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏禁心尽力

会优化,你真的会优化吗?其实你可能真的缺少一份理解【数据库篇】

  其实,在写这篇博客之前,我也是感觉自己会点优化,至少知道不要使用“*”号啊,给经常查询的列创建索引啊什么的,其实都不是大家想的那样简单的,其实它们背后存在很...

1986
来自专栏Rgc

项目中记录影响性能的缓慢数据库查询

如果程序性能随着时间推移不断降低,那很有可能是因为数据库查询变慢了,随着数据库规模的增长,这一情况还会变得更糟。优化数据库有时很简单,需要在程序和数据库之间加入...

36911
来自专栏好好学java的技术栈

java实现沙箱测试环境支付宝支付和整合微信支付和支付宝支付到ssm(附源码)

下载地址:https://docs.open.alipay.com/270/106291/

5267
来自专栏友弟技术工作室

mysql优化

上篇文章是关于mysql优化的,那个内容是我大学的时候学习的笔记,最近学习发现一些比较好的内容,在这里分享给大家。 版权源于网上。 工作中使用最多的就是MySQ...

4987
来自专栏Web项目聚集地

Spring MVC+Spring+Mybatis实现支付宝支付功能(图文详解)

本教程详细介绍了如何使用ssm框架实现支付宝支付功能。本文章分为两大部分,分别是「支付宝测试环境代码测试」和「将支付宝支付整合到ssm框架」,详细的代码和图文解...

2541
来自专栏吴伟祥

mysql 自增id和UUID做主键性能分析,及最优方案

UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领...

4122
来自专栏数据和云

Oracle 12.2新特性掌上手册 - 第七卷 Big Data and Data Warehousing

编辑手记:也许Oracle 12.2在内核上的智能改进只能让你眼前一亮,那今天基于Big Data和数据仓库的性能优化增强则会让你伸手触Oracle的强大灵魂。...

3057
来自专栏小怪聊职场

MySQL(五)|《千万级大数据查询优化》第二篇:查询性能优化(1)

3108
来自专栏杨建荣的学习笔记

关于MySQL极限值的初步验证纠错

晚上从珠江边回来之后,看到一篇文章说,MySQL有几个极限值,一个表的字段最多只有1017个,我看了以后表示怀疑。怎么快速验证呢,我看到文章的时候已经11点了,...

3395
来自专栏跨界架构师

C#和NewSQL更配 —— CockroachDB入门(可能是C#下的全网首发)

  CockroachDB(https://www.cockroachlabs.com)是Google备受瞩目的Spanner的开源模仿,承诺提供一种高存活性、...

1125

扫码关注云+社区

领取腾讯云代金券