数据库设计问题

查看 51|回复 2
作者:hfywy   
目前的数据库表结构(忽略了其他不重要字段)是:
create table if not exists tb_test(
    `id`        bigint unsigned auto_increment comment '主键 ID',
    `A1`         VARCHAR(32) DEFAULT '',
    `B2`        INT UNSIGNED DEFAULT 0,
    PRIMARY KEY(`id`),
    UNIQUE KEY(`A1`),
    KEY (`B2`)
);
常用的 SQL 主要是写入、查询和统计B2字段的数量,如下:
insert ignore into tb_test(A1, B2) values('xxx', 123);
select * from tb_test where A1 = 'xxx';
select count(*) as cnt fro tb_test where B2 = 123;
现在有个问题,这个表现在破亿了,统计 B2 字段耗时有时比较长,将来肯定越来越长,暂时升级数据库配置把耗时降到可接受范围了,目前想的方案是考虑做分表。但是用A1或者B2字段做分表字段都不是很好。A1做分表的话,要统计B2的时候需要每个表都轮询一次。B2字段做分表字段的话,要保证A1字段的唯一性,需要插入前轮询查每一个表当前插入的值是否已经存在。
请教下各位彦祖、亦菲,有没有好的建议,不只是数据库方案,其他存储也可以接受。

tb_test, SQL, 分表字段, 数据库

Karte   
1: 分表分为冷数据表和热数据表 (冷:不查询,堆就可以. 热:今日或当月插入数据表)
2: 创建一个 snapshot 表, 将冷数据时直接进行统计汇总并写入到 snapshot 表中 (标志当前已经有多少了).
3: 之后每月将热数据表统计好后在通过 snapshot 表查询 snapshot 数据, 然后汇总成最新的 (旧的留着无所谓, 如果 A1 字段多, 就删掉) 写入到 snapshot 表中.
4: 汇总完成后重新建立 snapshot 的索引 (如果做删除的情况), 减少页空隙所导致的性能问题.
5: 将热数据写入到冷数据表, 然后清空热数据接收新的数据.
这样之后要统计时可以直接将热数据表的数据做统计 (缓存也可以), 然后直接获取 snapshot 表中的计数即可知道有多少了.
icql   
如果 b2 字段有索引的话 count 还慢说明 b2 索引的区分度不高,相同 b2 值的记录数就是很多,count 就得一条一条累加就是慢,即使分表也解决不了问题。如果 b2 是可枚举的值,直接用另外一个表存储统计 b2 值对应的统计数量,insert 的时候事务里边去更新累加值,或者数据准确性要求不高放在 redis 里边累加也行,定期再校验修正一下
您需要登录后才可以回帖 登录 | 立即注册

返回顶部