论坛数据库设计与性能优化
题目:
一个简单的论坛系统
1:包含下列信息:
2:每天论坛访问量300万左右,更新帖子10万左右。
请给出数据库表结构设计,并结合范式简要说明设计思路。
结合这个题目把论坛系统设计相关知识点进行一下总结。
1 对于发帖主题和回复信息是否放在一张表中的讨论:
支持放在一起的实现和理由:
支持理由:在巨量数据表之间,数据库的连接和表与表之间的连接是相当耗性能的操作,在显示和检索数据时,尽量减少数据库的连接
以及表与表之间的连接。
实现方式:
为了避免T_Topics和T_Reverts两表之间的连接,考虑把发帖主题和回复信息存放在一张表(T_Infos)里面,
字段有:user_id,user_name,email,homepage,tel,add...
2: forum_item:主题和回复混合表
字段有:id,parent_id,user_id,user_name,title,content,....
parent_id=0或者null表示是主题,否则=n表示是id=n那条帖子的回复 。
T_Users和T_Infos连接,可以通过在T_Infos表内增加UserName字段来解决和它的连接,显示时,性能能够得到保证,UserName字段是冗余的,因此在用户修改UserName的时候就会产生同步数据的问题,这个需要程序来进行弥补,并是我们认为用户不会经常性的修改他的用户名这样的前提下。
反对理由:
1不同意冗余的存在的。表面上看起来好像少查了一张表,但是因为帖子数量极大,会因为冗余(有些T_Topics需要的属性T_Reverts不需要,这样会导致冗余)
占用、浪费大量的空间。
2虽然题目中没有说明,但实际应用中,查阅帖子通常只会分页显示,而一页最多也就显示几十个帖子,那么实际上只要SQL语句构造得好,T_USER表其实只是跟一个只有几十行结果集的的子查询进行连接,应该基本不用担心出现性能问题。 而且实际上,一个万行级的表简单关联百万行级的表(其实镇魂歌数量级在我看来其实也算不上很大的表),在数据库方面完全有很多优化方式,甚至可以通过提高硬件配置来改善性能,实在没有很大必要进行结构上的冗余。一旦结构有冗余,为了保证数据一致性,往往你还要消耗更多的资源,反而得不偿失。
纵观网友的意见,几种常用的论坛设计方法,总结如下:
一 分割思想:
1 数据库切分:用户库、主题库、回复库
2 数据表水平切分:用户库1-n、主题库1-n、回复库1-n (比如按时间分)
3 分布式数据库:每台计算机中都有DBMS的一份完整拷贝副本,并具有自己局部的数据库,位于不同地点的许多计算机通过网络互相连接,共同组成一个完整的、全局的大型数据库。
4 论坛功能可以进行分隔,不同的服务器负责不同的功能
5 用主从数据库,master是写, slave是读
6 把内容与其它信息分开,好处就是可以让每个表的文件最小化,对数据库操作压力会减小,这样保证每张表数据量很小,操作速度会快,也可以在这里使用缓存
二 索引:
针对是否建立索引有着一定的分歧:
我觉得建立索引还是很有必要的。理由如下:
1)建立索引可以加快检索速度,对于论坛读和写的比例相差很大,用户体验当然是读多写少,所以综合考虑还是要用索引,而且是加在常用的读关键字上。
2)索引之所以会降低更新的速度,是因为更新还包括对索引的更新,从更新帖子10万左右,这句话是说,我们可能对发帖标题,发帖内容,回复标题,回复内容这4个字段做更新。需要注意的是,这四个字段并不是用来建立表连接的字段,为了优化查询速度我们不会在这四个字段上建立索引,所以从这道题目出发,我们建立的索引不会影响更新帖子的性能。只要被索引的列(例如回复表的标题ID)不被频繁更新,即使索引所在地行的其它列被频繁update,索引也不会被更新从而产生性能消耗,一张表一天30万次的索引更新,因它引起的性能消耗小到即使数据库安装在奔腾3单核CPU下都能轻松承担下来。
3)对于更新的速度慢的问题,我们有解决的方法,你提交更新了后,前台可以让程序返回一个正确结果,后台开个线程异步慢慢跟新数据库就是了,反正更新成功的前提就是假设数据库连接永远正确并处于可靠状态。在数据库和用户之间建立一个缓冲区。(如,将更新的数据放到内存中,达到一定数量的时候再统一更新数据库。假如以100条为例,一旦内存中达到100条数据量将这100条数据统一入库。减少insert操作)
三 缓冲:
读的时候的缓冲:缓存路由表
主题缓存表(这个取每个区的前面100条记录),一般来说负载最大的就是主题的第一页,所以缓存表是个小表。
另外使用hibernate,在数据库上面加了一层缓存。
生成静态页,缓存最热,最新的帖子。
对于经常更新的数据都设计成单独表 ,这样可以最大程度的利用hibernate缓存
缓存常用的数据和表,利用缓存来将经常被访问的帖子留在内存中,为每条缓存的记录添加一个访问时间,如果长时间没被访问就从缓存中删除掉,
避免内存过大,每次用户看帖的时候,首先检索缓存中时候有需要的帖子,没有的话再访问数据库,然后将数据库返回的帖子信息存储到缓存中。
写的时候的缓冲:数据库和用户之间建立缓存,将更新的数据放在内存中,异步操作的。所有的写贴操作 放到一个队列然后批量执行插入数据库操作。
预估计的缓冲:假如用户第一次打开某标题,那将此标题的相关的前100条数据缓存到客户断。这样避开对数据库的直接查询,减少数据库压力。
四 代码优化
1尽量避免表的连接约束通过代码来实现约束 例如用户id的验证在用户登录时验证这样就可以把帖子表的用户id外键去掉这样就成了单表操作、查询 而连接可以通过触发来实现这样最多是查询了3个表而不是连接中的笛卡尔笛卡尔积 回复表的查询限定每次查询的记录数例如限定10条其它的通过点击触发来操作"注代码优化容易出现bug 原因有些开发工具本身有优化"
五 数据库性能调优
尽量用硬件来代替软件优化 原则就是能用硬件的尽量用硬件 比如磁盘阵列 RAID0 有条件用RAID10 加大内存 .避免小表上建索引 对论坛来说数据帖子和回复不是很重要 可以定期删除一些垃圾帖子 楼主说的几百万条记录的论坛对现在的数据库管理系统和计算机来说永不着刻意的优化,定期维护打包备份数据库就可以了
提高速度的关键:
1.建立合理的索引并在查询时充分利用;
2.避免使用关联,这样避免整表扫描;使用关联不如多次使用主键查询来的快;
3.一些处理的功能尽可能放到内存中来做,比如组织主题和回复;
4.海量缓存(使用静态页面也是个不错的做法)
5 定期对表进行转储
论坛数据库设计与性能优化相关推荐
- 一、数据库设计与性能优化--概述
前言 我1998年第一次接触SQL Server 6.5 for Windows NT 4.0,当时的感觉就认为SQL Server只是一个功能强大的Excel文件.现在回想起来,当年抱着这样一种态度 ...
- 熟悉mysql数据库设计和性能优化_Mysql数据库性能优化
Mysql数据库性能优化,可以从下面三点入手: 数据库设计 SQL语句优化 架构优化 一.数据库设计优化 1.适度的违反范式,适度 遵循三大范式就会带来查询时经常需要join,导致查询效率降低 ...
- 熟悉mysql数据库设计和性能优化_MySQL性能优化学习笔记-(1)数据库设计
一.数据库设计 1.数据类型优缺点分析 数据类型的选择要遵循的总体原则 更小的通常更好 一般情况下,应该尽量选择使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为它们站用更小的磁盘.内存 ...
- DB2设计与性能优化:原理、方法与实践
DB2设计与性能优化:原理.方法与实践 王飞鹏 陈辉 张广舟 成孜论 编著 ISBN 978-7-121-13094-6 2011年4月出版 定价:89.80元(含光盘1张) 16开 416 ...
- 数据库设计对性能的影响
数据库结构设计和数据库优化呢,是我们后面几张主要的内容,所以我们这里先简单的看几个和数据库的设计,和SQL优化有关的对数据库性能产生影响的一些易犯的错误,我们现在对如何高性能的数据库设计,和SQL优化 ...
- 阿里P8架构师谈:Web前端、应用服务器、数据库SQL等性能优化总结
web前端性能优化 Web前端指网站业务逻辑之前的部分,包括: 1.浏览器加载 2.网站视图模型 3.图片服务 4.CDN服务等 主要优化手段有优化浏览器访问,使用反向代理,CDN等. 1.浏览器访问 ...
- 数据库的这些性能优化,你做了吗
转载自 数据库的这些性能优化,你做了吗 在互联网项目中,当业务规模越来越大,数据也越来越多,随之而来的就是数据库压力会越来越大. 我们可能会采取各种方式去优化,比如之前文章提到的缓存方案,SQL优 ...
- 关系型数据库大数据性能优化解决方案之:分表(当前表历史表)、表分区、数据清理原则
原因和目的 由于交易量大或者日积月累造成数据库的数据量越来越大.会导致系统性能大幅下降,所以要对部分业务的表数据作备份和清理 减少数据量,来提升请求响应的速度,提升用户体验 数据是否需要清理的阀值判断 ...
- 五、系统架构 - 高性能架构设计及性能优化
目录 性能测试 不同视角下的网站性能 性能指标 性能测试 性能测试报告 性能优化策略 前端性能优化 开启缓存 启用压缩 改代码 后端性能优化 分布式缓存 异步操作(消息队列) 使用集群 代码优化 SQ ...
最新文章
- 给网站增加https的简单方法
- 蓝桥杯-用宏求球的体积(java)
- 【Python进阶】Python进阶专栏栏主自述:不忘初心,砥砺前行
- 【ABAP】BASE64加密及解密
- wxWidgets 富文本编辑器示例
- java axis2小实例_java webservice axis2简单开发实例
- GNU ARM 汇编指令[转载]
- leetcode - 873. 最长的斐波那契子序列的长度(使用到哈希表)
- 数据库数据类型和占用字节数对比
- !DOCTYPE标签的定义与用法
- 微信小程序-携带参数的二维码条形码生成
- web页面视频播放器选型
- 关键信息基础设施网络风险地图
- 毕竟,连少宇都无法击败的人,是没有资格做自己的对手的
- iOS开发:xcode无法选择设备和corner stone如何过滤上传文件
- 机器学习实战——决策树Python实现问题记录
- 简述Android操作系统和IOS系统的区别;
- offsetParent解释
- K-means聚类分析
- matlab的udt,西门子PLC的UDT是干什么的?如何使用?终于讲清楚了