MySQL⼤表拆分多个表的⽅式(横向拆分和纵向拆分)及如何
解决跨表查询效率问题
⼤表分表后每个表的结构相同,可以⽤sql的union。⽐如a,b表结构相同可以通过union来联接
select * from a
union all
select * from b
where ...
⼀、Union和Union All到底有什么区别
Union:对两个结果集进⾏并集操作,不包括重复⾏,同时进⾏默认规则的排序;
Union All:对两个结果集进⾏并集操作,包括重复⾏,不进⾏排序;
⽐如⼀家公司在中美均有雇员,我们使⽤Union这个命令想查出中美所有雇员,是不⾏的。假如我们有
两个名字相同的雇员,他们当中就只会有⼀个⼈被列出来了。UNION 命令只会选取不同的值。⽽Union All则可以查出全部的值。
详细了解:www.w3school/sql/sql_union.asp
⼆、⼤表拆分后的查询效率问题
假如⼀个超级⼤的⽤户表按照数据拆分成10个表后,某个⽤户登录的时候是不是要从10个表⾥⾯去查询这个⽤户的⽤户名和密码是否正确。这样就存在效率问题。
⼀种⽅案就是拆表的时候,按照⼀定规则来拆表,查询的时候按照这个规则来查,通过规则就能知道到底该去哪个表查,如果胡乱拆表,那⼀个表和10个表有什么区别。
三、⼤表拆分
表的拆分分为横向拆分(记录的拆分)和纵向拆分(字段的拆分)。拆分表的⽬的:提⾼查询速度。
(1)横向拆分 - 记录的拆分
我们从⼀个案例去解释,情景是这样的:某某博客,有50W的博客量,有2w的⽤户,发现随着⽤户和博客数的增加,查询速度⽇渐下降,现在要对博客表blog与⽤户表user进⾏优化。
表结构如下:
create table blog(
bid
title
content
pubtime
uidsql中union多表合并
) 50万
create table user(
uid
username
password
nick
......
) 2万
⾸先我们要决定根据哪个字段对记录进⾏拆分,查询决定了拆分,在这⾥我们根据uid字段对两个表进⾏拆分是⽐较合理的。
博客表根据uid去拆分:
1-5000------blog_1
5001-10000-----blog_2
10001-15000----blog_3
15001-20000----blog_4
⼈员表根据uid 等分:
1-5000------user_1
5001-10000-----user_2
10001-15000----user_3
15001-20000----user_4
⽐如查询某⼈的博客:
// 根据uid确认表名:
$num=ceil(12345/5000);
select uid,bid,title,pubtime from blog_$num where uid=12345;
(2)纵向拆分:字段的拆分 - 把活跃字段(常⽤)、惰性字段(不常⽤)分开。
案例:⽐如⼈员表,活跃字段像⽤户名、密码、昵称等,惰性字段像⼿机号、邮箱、性别等不经常使⽤和修改的字段。 ⼀张完整的⽤户表可以拆分为两张表,如下:
create table user(
uid int key auto_increment,
username char(20),
password char(32) not null,
nick char(10)
);
create table user_ext(
uid
regtime
name
email
qq
phone
sex
)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论