免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10520 | 回复: 14
打印 上一主题 下一主题

数据表横向切分法思路 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-03 18:06 |只看该作者 |倒序浏览
简单说明一下,假设原始表结构:

ID username
email passwd ...
10000001 小强 aa@qq.com
xxxxxxxxxxxx ...
10000002 张三 bb@gmail.com xxxxxxxxxxxx ...
... ... ... ... ...


以用户名做hash把所有用户打散到不同的表,如取md5('小强')的首英文字母(hash方法很多,这边简单以md5示例)进行横向分表后假设创建如下表名:
users_a、users_b、users_c、users_d、.....、users_other
users_a 设置主健基数 10000000
users_b 设置主健基数 20000000
users_c 设置主健基数 30000000  
....


这样以后,若我们查询  username='小张',则hash后得到小张所在的表名为 users_a,构建sql语句:
select * from users_a where username='小张';

若我们查询用户  ID=21001234,则可间接得到ID21001234所在的表名为 users_b,构建sql语句:
select * from users_b where ID=21001234;
以上这些办法都能在分表后大幅提升数据库查询性能。





但是,虽然解决了使用ID和username查找的问题,如果我想查找 email='xxxx@xxx.com' 怎么办?

首先建立该字段与主键ID的映射关系表结构如下:

email ID
aa@qq.com 10000001
bb@gmail.com 10000002
... ...


其次,针对email的值进行散列/分表,拆分为 email_a、email_b、email_c.....
简单地理解就是:
email_a存放的是以邮件a开头的所有email地址及其对应的用户ID;
email_b存放的是以邮件b开头的所有email地址及其对应的用户ID.....


这样以后,若我们查询  email='aa@qq.com',则可得到该email所在的表名为 email_a,构建sql语句:
select ID from email_a where email='aa@qq.com';
得到用户ID,并根据ID查找到用户数据,实则也是一种自创索引。


总知在大数据量、大并发应用中分表是很必要且很繁琐的工作,而且很多时候衍生出分库乃至分服务器等,在此也仅仅浅显地表达一些思路,希望以此抛砖引玉,理解得不好的地方还请海涵。

论坛徽章:
0
2 [报告]
发表于 2009-07-03 18:13 |只看该作者
支持原创:wink:

论坛徽章:
0
3 [报告]
发表于 2009-07-04 18:26 |只看该作者
为什么不用ID进行HASH呢?
现在的算法有点复杂呀。

论坛徽章:
0
4 [报告]
发表于 2009-07-04 19:17 |只看该作者
算法很简单啊,
假设id为12345678,取表名 SELECT concat('users_',char( 96 + left( '12345678', 1 ) ) )

而ID本身就分好了   
users_a           主健自增基数 10000000
users_b           主健自增基数 20000000
users_c            主健自增基数 30000000  
....
users_other     主健自增基数 90000000






另外是考虑到分表后的数据排序等问题,而目标字段使用ascii码分表等方式可直接解决

[ 本帖最后由 bs 于 2009-7-4 19:45 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-07-05 09:46 |只看该作者
一致性hash多好

论坛徽章:
1
双子座
日期:2013-08-19 14:56:16
6 [报告]
发表于 2009-07-06 21:07 |只看该作者
你何不 分好  0-100 个表   uid %100  定位表呢  ,

论坛徽章:
0
7 [报告]
发表于 2009-07-07 07:55 |只看该作者
从各自需求出发把。呵呵,支持楼主!

论坛徽章:
0
8 [报告]
发表于 2009-07-07 10:21 |只看该作者
呃,似乎我在文字表达方面有待提高。

其实文中提到的更倾向于,分表后的其它字段查询、排序、批量查找的问题
问题不在于用什么来分。

如上面一位朋友说的用ID直接分,这谁都会分,但是分完后其它字段作为where条件来查找的问题如何解决?


如:分表后 where id=123456 其实很简单,但 where email='xxx@xxx.com' 怎么更好地解决,这才是我想表达的重点。

论坛徽章:
0
9 [报告]
发表于 2009-07-07 12:28 |只看该作者
现在大多数数据库(包括mysql)都支持表分区,楼主自己再搞未免累了点。

论坛徽章:
0
10 [报告]
发表于 2009-07-07 18:24 |只看该作者
原帖由 sunnyfun 于 2009-7-7 12:28 发表
现在大多数数据库(包括mysql)都支持表分区,楼主自己再搞未免累了点。

单台服务器能顶住的压力太有限了。所以很多项目会进行表折分,或是一个大业务散到很多台机器上。

希望能深入讨论一下。或是可以猜一下QQ这样的业务的DB设计。

个人猜想:


根据USERID进行环形散列到不同的机器形,象不同的全国的手机号属于不同的基站,基本信息在一个权威DB中存储。
首先通过认证然后到自已所属的那个DB去取权限,然后走不同的服务。

应该前面还有缓存层。不然那么多业务很难整合的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP