铭轩同学

铭轩,为自己代言!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  我之前曾参与维护过一个舆情监控系统,该系统每天源源不断地监控着互联网上的新闻,不断从网上下载新闻保存进入数据库。

提出问题

  为了表述简单,我特意模拟了一张类似的表:

  CREATE TABLE NEWS(
      Id    int PK,
      Title    nvarchar(500)    --新闻标题
      Content    text        --新闻内容
     CreateTime DateTime
)

  随着时间的推移,数据库里的新闻变得越来越多,系统开始跑得越来越慢。随后,技术经理考虑到,舆情监控需要的仅仅是近期的数据,过时的数据,不太重要。于是,新建了一个表,该表以时间命名,字段一样:

  CREATE TABLE NEWS2009(
      Id    int PK,
      Title    nvarchar(500)    --新闻标题
      Content    text        --新闻内容
     CreateTime DateTime
  )

  1、不断产生的新表

  照我的估计,这个数据库之后还会有

    News2010,News2011,News2012.......

  添加时需要选择表:

  由于数据要被拆分到不同的表中,假如系统不似我的舆情监控系统一样,不断有不同时间的数据录入,那么根据不同的数据,选择不同的数据添加就成了你的责任。

  INSERT INTO NEWS2010 (2010年的数据)

  特殊时间点:

  如果元旦到了,你还在享受着美满的假期,突然客户打电话来,问系统为什么不监控了,shit,2013.1.1你忘了建新表。导致大量数据漏掉了,你难免比老板痛扁一顿。

  2、管理数据完整性

  加入某一天,你运行:

SELECT * FROM NEWS2009
    WHERE CreateTime NOT BETWEEN '2009-01-01' AND '2009-12-31'

  结果居然有返回,那么你又有麻烦了。为了避免这种情况,你不得不对每一张新闻表添加约束,不在规定时间内的数据,不允许添加规定的表。

  3、同步数据

  突然,产品经理要求将几条数据的CreateTime由进库时间,改为新闻网站的发布时间。例如有一点时是2010-01-02,但实际发布时间稍早是2009-12-31。

  你满怀自信兴冲冲地敲入:

  UPDATE NEWS2010
      SET CreateTime = '2009-12-31'
  WHERE Id = 12345

  运行时,突然一想,这数据变成了一条无效数据,它应该存入NEWS2009这张表中。UPDATE无用了,你必须添加进NEWS2010然后再删除本条数据。

  4、确保唯一性

  分割出来的数据,其主键要在所有年份的表里都是唯一的,如果你要从NEWS2010表移一条数据到NEWS2009表,那么你得确保主键不会冲突。你不得不自己实现主键策略。

  5、跨表查询

  假如老板要每年2月14号的数据报表。你不得不拼命地

复制代码
SELECT * FROM NEWS2009
UNION
SELECT * FROM NEWS2010
UNION
SELECT * FROM NEWS2011
.
.
.
复制代码

  6、同步元数据

  假如产品经理突然要求所有新闻添加一个字段,那么你不得不ALTER多张表。

  7、管理引用完整性

  假如产品经理要求评论也一起抓取回来,NEWS表的NEWSID不行被Comments评论表引用,那么这个外键不得不被关键多张表。

解决方案 - 分区表

  基于以上种种分析,明显已经看出,这样的设计不是一个好的设计。

  对于这种时间效应比较强,数据比较多的表,我们应该博览群魔,分区表。

  关于分区表的实现,之前已经写过http://www.cnblogs.com/kissdodog/p/3156758.html

 

 
 
 
0
0
 
(请您对文章做出评价)
 
« 上一篇:逻辑数据库设计 - 多列属性(多列转行)
» 下一篇:NHibernate 集合映射基础(第四篇) - 一对一、 一对多、多对多小示例
posted on 2015-07-17 17:13  铭轩同学  阅读(309)  评论(0编辑  收藏  举报