数据库建表 —— 静态数据 和 动态数据 的 拆分

背景

基本表 news、user、news_reply
简单关系:user 创建 news ,user 可以查看 news,并且 回复 news

业务需求

简单来说,具有发布、查询、查看、回复功能。基本表的增删改查OK。

但实际上的需求:要查看 一条新闻的总回复数 、 浏览次数 、 最后一次更新时间。

最简单的做法:在 news 表 加上三列

基于数据的准确性,我们可能用 select count(*) from news_reply where news_id = :news_id 来获取 总回复数

每次 getNews(id) 的时候 news.pageView ++ news, replyNews 的时候 last_upd_time = NOW()

但实际上这样做应该更合理:create table news_ext

news_ext 包含 news_id、page_view、last_upd_time、reply_count 四列

每当 get 的时候 更新 news_ext 的 page_view 和 last_upd_time,reply 的时候 更新 reply_count 的数据


好处:

如果 news 表有 20列属性,那么如果你每次 getNews(id) 的时候 去执行更新,这个代价还是很坑的。
如果 reply 表有 十万条数据,select count() 的 消耗也是很坑的
相对来说, news 表的 title content user_id news_id 等数据都是 比较静态的
page_view、reply_count、last_upd_time 则是 非常动态的。

这就是我理解的所谓 静态数据 和 动态数据 的 拆分。感觉这样做还是具有相当的合理性的。

更新效率 比 直接在 news 表中加 列 快很多。
查询效率 比 直接 select count() 简单很多。

等于是把复杂的问题 拆分成简答的问题处理掉了。

隐患

如果每张表都有个 ext,其实还是挺坑的,多了很多表,不过我自己也只是总结了一下理论,实际应用还没实验,也许不会像想象中那么麻烦吧。

还有个隐患就是:这些数据不是算出来的,而是写出来的,人手动写的错误率比电脑算要高非常多。

/*
Navicat MySQL Data Transfer

Source Server         : Seraph_fd
Source Server Version : 50616
Source Host           : localhost:3306
Source Database       : test

Target Server Type    : MYSQL
Target Server Version : 50616
File Encoding         : 65001

Date: 2014-08-07 23:46:03
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for news
-- ----------------------------
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news` (
  `news_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `content` text,
  `create_time` datetime DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`news_id`),
  KEY `fk_u_n` (`user_id`),
  CONSTRAINT `fk_u_n` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for news_ext
-- ----------------------------
DROP TABLE IF EXISTS `news_ext`;
CREATE TABLE `news_ext` (
  `news_id` int(11) NOT NULL,
  `page_view` int(11) NOT NULL,
  `last_upd_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `reply_count` int(11) NOT NULL,
  PRIMARY KEY (`news_id`),
  CONSTRAINT `fk_n_n_e` FOREIGN KEY (`news_id`) REFERENCES `news` (`news_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for news_reply
-- ----------------------------
DROP TABLE IF EXISTS `news_reply`;
CREATE TABLE `news_reply` (
  `reply_id` int(11) NOT NULL AUTO_INCREMENT,
  `news_id` int(11) DEFAULT NULL,
  `content` varchar(255) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`reply_id`),
  KEY `fk_u_n_r` (`user_id`),
  KEY `fk_n_n_r` (`news_id`),
  CONSTRAINT `fk_n_n_r` FOREIGN KEY (`news_id`) REFERENCES `news` (`news_id`),
  CONSTRAINT `fk_u_n_r` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL,
  `pass_word` varchar(255) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- View structure for view_news
-- ----------------------------
DROP VIEW IF EXISTS `view_news`;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost`  VIEW `view_news` AS SELECT
`user`.user_name,
news.news_id,
news.title,
news.content,
news.create_time,
news.user_id,
news_ext.page_view,
news_ext.last_upd_time,
news_ext.reply_count
FROM
news
INNER JOIN `user` ON news.user_id = `user`.user_id
INNER JOIN news_ext ON news_ext.news_id = news.news_id ;




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值