求教一个mysql建表分组索引问题
迷茫
迷茫 2017-06-28 09:22:55
[MySQL讨论组]

我在做一个网站程序,大致要求效果如下。
用户分为1-5这五个级别,数字越大权限越高。

我有一堆内容,级别越高的用户可见内容越多。
例如有内容:A、B、C、D、E,
用户组1的可见:A
用户组2的可见:A、B
…………
用户组5的可见:A、B、C、D、E
如果要实现这种功能,该如何建立数据库索引比较好呢?

之前有朋友跟我说在内容(topic)表加上一列"group",
写上可见的用户等级1-5,然后建立group_tid的联合索引。
然后查询tid<100周围文章(例如当前用户组为3)时的语句就是:
SELECT * FROM topic WHERE group>=3 AND tid<100 LIMIT 10;
可实际发现这种索引是先将group>3的所有数据读出来,再进行选择查询。
假如有100万条数据,有50万个group>3,该语句执行就要从50万条种筛选,效率极低。

看起来单列的索引只适用于group=*这样的限制条件,而不能是<或>。
所以想在此请教各路大神,有没有过类似的需求?如何正确建立索引或分表?
深表感谢!

补充1:
其实把问题改变一下,就是如何在mysql两个索引中使用<或>限定。
这是个逻辑问题,目前的group_tid索引建立后类似于下图:

即便我对group进行了范围限制,后面的tid还是在group的基础上按顺序排列的。
如果我想知道group>1且tid<6的这种情况,不得不先把group2/3全部读出再筛选。
看起来只有重新规划表结构,各位有没有类似经验?

补充2:
刚才收到了热心朋友的帮助回答,说这种情况他曾经遇到过。
解决的方法是修改发布机制,将符合条件的帖子发布至各个等级。
例如内容A的级别是3,那么发帖时要同时建立三个数据行:
group=1,tid=A
group=2,tid=A
group=3,tid=A
这样在内容读取时直接请求WHERE group=*都可以读出符合条件内容。
但这种方法需要添加大量的关联数据,甚至造成重复,有没有其他解决途径呢?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(3)
学习ing

其实你的思路已经很对了。

tid上建立索引,根据group分表。

如果group >=3的组,在程序中动态组合sql如下:

select * from group3 where tid < 100
union all 
select * from group4 where tid < 100
union all 
select * from group5 where tid < 100

以上索引生效,逻辑可用。

怪我咯

group条件的过滤性很差,单独建立索引意义不大。

根据你描述的场景,只要tid的值不是太大(几千的数量级),针对tid建立索引就可以了。
如果还担心tid条件过滤后的数据量大,可以创建tid,group的组合索引。

黄舟

首先非常感谢各位对我问题的关注和回答!!
问题解决之后针对boxsnake的建议有一个思考,在这里发一下。
group_tid这种索引方式除了解决读取之外还能解决分页问题,
例如我每页文章数量是10,用户级别为3,那么读取时分别从group1、group2、group3中,
按范围tid<100各取10篇,即便某group中没有符合条件的结果,几项加起来也可以覆盖全。

但如果用tid_group这种索引方式来读取,如果需要group<=3的情况,我不知道该取多少篇文章。
比方说取10篇,tid90-tid99,如果他们的group都是4,那么就无法取出符合条件的数值。
tid_group在限定group之前又必须对tid进行限定,所以就没法使用了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号