专栏首页Netkiller新闻数据库分表案例

新闻数据库分表案例

文章节选自《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;

本文分享自微信公众号 - Netkiller(netkiller-ebook),作者:景峰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-09-27

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据库安全·时间一致性

    以下节选择《Netkiller Architect 手札》地址 http://www.netkiller.cn/architect/ 接下来几周的话题是数据库安...

    netkiller old
  • 网络设备配置管理与版本控制

    网络设备配置管理与版本控制 摘要 2014-12-25 我的系列文档 Netkiller Architect 手札 Netkiller Developer ...

    netkiller old
  • How to Install Nginx and PHP-FPM on FreeBSD 10

    FreeBSD 10 + Nginx 1.4.4 + PHP 5.5.9 + MySQL 5.6.15 摘要 FreeBSD 10.0 的 pkg 无法安装ph...

    netkiller old
  • 加拿大超算中心利用Allinea工具弥合创新缺口

    SciNet运用Allinea的调试工具加速了加拿大领先高性能计算(HPC)系统在软件方面的发展 “如果有人告诉你他的代码是百分百正确的,那他就太夸张了...

    GPUS Lady
  • python 解决方法:ImportEr

    py3study
  • 深入解析 PostgreSQL 系列之并发控制与事务机制

    并发控制旨在针对数据库中对事务并行的场景,保证 ACID 中的一致性(Consistency)与隔离(Isolation)。数据库技术中主流的三种并发控制技术分...

    王下邀月熊
  • Mysql 常用函数(16)- locate 函数

    https://www.cnblogs.com/poloyy/p/12890763.html

    小菠萝测试笔记
  • Android短信验证码自动填写实现代码

    今天给大家分享一个Android短信验证码自动填写的功能。先看下效果图,我发送了一条短信到手机,自动填写验证码。如图:

    砸漏
  • Python遍历文件和内容

    py3study
  • 操作数据表中的记录

    插入记录   语法:INSERT [INTO] [(tbl_name,...)] {VALUE|VALUE} ({expr|DEFAULT},...),(......

    用户1624346

扫码关注云+社区

领取腾讯云代金券