我在做一个网站程序,大致要求效果如下。
用户分为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=Agroup=2,tid=Agroup=3,tid=A
这样在内容读取时直接请求WHERE group=*都可以读出符合条件内容。
但这种方法需要添加大量的关联数据,甚至造成重复,有没有其他解决途径呢?
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
其实你的思路已经很对了。
tid上建立索引,根据group分表。
如果group >=3的组,在程序中动态组合sql如下:
以上索引生效,逻辑可用。
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进行限定,所以就没法使用了。