新闻数据库分表案例
时间:2022-05-03
本文章向大家介绍新闻数据库分表案例,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
文章节选自《Netkiller Architect 手札》
6.3. 新闻数据库分表案例
这里我通过一个新闻网站为例,解决分表的问题
避免开发中经常拼接表,我采用一个一劳永逸的方法,建立一个 news 表使用黑洞引擎,然后通过出发器将数据分流到匹配的表中。同时采用uuid替代数字序列,可以保证未来数年不会出现ID用尽。
CREATE TABLE IF NOT EXISTS `news` (
`uuid` varchar(36) NOT NULL COMMENT '唯一ID',
`title` varchar(50) NOT NULL COMMENT '新闻标题',
`body` text NOT NULL COMMENT '新闻正文',
`ctime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`atime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '访问时间',
PRIMARY KEY (`uuid`)
) ENGINE=BLACKHOLE DEFAULT CHARSET=utf8;
该表仅仅用于举例,结构比较简单。接下来创建年份分表,你也可以每个月一个表,根据你的许下灵活调整。表结构与上面的news表相同,注意 ENGINE=InnoDB。
CREATE TABLE IF NOT EXISTS `news_2012` (
`uuid` varchar(36) NOT NULL COMMENT '唯一ID',
`title` varchar(50) NOT NULL COMMENT '新闻标题',
`body` text NOT NULL COMMENT '新闻正文',
`ctime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`atime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '访问时间',
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='news 表';
CREATE TABLE IF NOT EXISTS `news_2013` (
`uuid` varchar(36) NOT NULL COMMENT '唯一ID',
`title` varchar(50) NOT NULL COMMENT '新闻标题',
`body` text NOT NULL COMMENT '新闻正文',
`ctime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`atime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '访问时间',
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='news 表';
uuid 索引表,主要的功能是通过uuid查询出该记录在那张表中。更好的方案是将数据放入solr中处理,包括标题与内容搜索等等。
CREATE TABLE `news_index` (
`uuid` VARCHAR(36) NOT NULL,
`tbl_name` VARCHAR(10) NOT NULL,
PRIMARY KEY (`uuid`)
)
COMMENT='news uuid 索引表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
news_insert 过程,用于向目标表中插入数据,可以单独call 但不建议。因为insert 远比 call 更通用,要考虑移植性与通用性
DELIMITER //
CREATE DEFINER=`neo`@`%` PROCEDURE `news_insert`(IN `uuid` vARCHAR(36), IN `title` VARCHAR(50), IN `body` TEXT, IN `ctime` TIMESTAMP)
BEGIN
if year(ctime) = '2012' then
insert into news_2012(uuid,title,body,ctime) values(uuid,title, body, ctime);
end if;
if year(ctime) = '2013' then
insert into news_2013(uuid,title,body,ctime) values(uuid,title, body, ctime);
end if;
insert into news_index values(uuid, year(ctime));
END//
DELIMITER ;
插入触发器,负责获取 uuid 然后调用存储过程
SET @OLDTMP_SQL_MODE=@@SQL_MODE, SQL_MODE='';
DELIMITER //
CREATE TRIGGER `news_before_insert` BEFORE INSERT ON `news` FOR EACH ROW BEGIN
IF new.uuid is null or new.uuid = '' or length(new.uuid) != 36 THEN
set new.uuid=uuid();
END IF;
call news_insert(new.uuid,new.title,new.body,new.ctime);
END//
DELIMITER ;
SET SQL_MODE=@OLDTMP_SQL_MODE;
这个触发器用户保护表中的 uuid 值不被修改。
SET @OLDTMP_SQL_MODE=@@SQL_MODE, SQL_MODE='';
DELIMITER //
CREATE TRIGGER `news_before_update` BEFORE UPDATE ON `news_2013` FOR EACH ROW BEGIN
set new.uuid = old.uuid;
END//
DELIMITER ;
SET SQL_MODE=@OLDTMP_SQL_MODE;
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介
- webpack配置别名alias出现的错误匹配
- 在Java程序中处理数据库超时与死锁
- 如何用TensorFlow和TF-Slim实现图像标注、分类与分割
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合
- 使用shell脚本查看数据库负载情况(第二篇)(r3笔记第92天)
- tensorflow LSTM + CTC实现端到端OCR
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(七)图片上传功能
- 黑客比程序员牛在哪?
- oracle工具集初探(r4笔记第8天)
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(二)Log4j讲解与整合
- 京东JData算法大赛-高潜用户购买意向预测(github源码)
- 巧用linux命令做图片下载器(r4笔记第7天)
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法