数据库和逻辑如何设计 目前遇到一个项目
要搞个小系统
A 为帐号 表 accounts 会不停更新新的(如 a b c d ....) (每天增加几万个) T 为任务 表 tasks 固定的几百个个(如 1 号,2 号,3 号)
T 里的每个任务 A 只能做一次
要求: 需要 1 号任务 请求一下随机获得一个 A 的帐号(没有做个 1 号任务的帐号)
自己的想法是 建个黑名单数据库表 black 每完成一个 增加一行 如 a-1 a-2 b-2 c-3
然后获取的时候 select 后面加个 not in 来判断
select * from accounts where id not in (select id from black) order by rand()
但是感觉这样效率很低
英文 black 的数据库会增加得非常快
1 万个帐号 对应 100 个任务 就是 100 万条记录 估计没多久就上亿了 而且我不知这样 not in 这种效率如何
1
SuperMild 2018-03-05 13:45:28 +08:00
accounts 表: a, b, c, d, task_id
select * from accounts where task_id <> 1 就可以筛选出 A 之中没有做过 1 号任务的帐号 |
2
maowenjie OP @SuperMild 这样不行 a 会做很多任务 比如 2 号 3 号 5 号 总共几百个 不能 task_id 设个数值
|
3
calmspeed 2018-03-05 14:12:15 +08:00
accounts 表添加列 taskHistory (每做过一个任务用逗号添加分隔:,1,2,3,)
declare @task_id = '1'; select * from accounts where charindex(@task_id,taskHistory) = 0 题主你想的 black 表可以作为操作的历史记录表,包扩操作的一系列信息。如果业务拓展开应该是必须存在的一张表。但是题目的要求还是用这种方法来实现高效。 |
4
calmspeed 2018-03-05 14:32:49 +08:00
declare @task_id =','+ '1'+',';
select * from accounts where charindex(@task_id,taskHistory) = 0 |
5
newtype0092 2018-03-05 14:36:28 +08:00 1
几百个任务用一个数值按位表示就好了,位运算学过吧?
n=0 表示没做过任务 1 表示只做过 1 号任务 2 (二进制 10 )表示只做过 2 号任务 11 (二进制 1011 )表示做过 4 号、2 号、1 号任务 筛选的时候每个账号只需要用 n 和对应任务号进行一次与运算就行了。 不太懂数据库,不知道有没有更方便的方法。 |
6
akira 2018-03-05 14:36:46 +08:00
感觉楼主是做薅羊毛 /工作室的
|
7
Immortal 2018-03-05 14:43:55 +08:00
not in 转换成 not exists 了解下? 学习资料 http://www.cnblogs.com/zhangminghui/p/4403672.html
|
8
Immortal 2018-03-05 14:44:16 +08:00
然后提供一个思路
类似于你说的黑名单,单纯从你的题目上来看,我会这么设计 |
9
Immortal 2018-03-05 14:50:12 +08:00
除了 account 和 tasks 表可以增加一些记录表,记录每个用户完成 task 后 task id 和 uid
记录表可以是多张,根据你的 task id 取模,比如你要找 task id=1 的任务,你就知道去哪个表里查询了,缓解单表压力压力,mysql 如果使用的好,单表几百万,上千万对于你这个需求的查询还是非常快的 然后查看是否有做过这个任务 用前面说的 not exists,不要用 not in,not in 不走索引 |
10
micean 2018-03-05 14:50:50 +08:00
用字符串代替吧,用 instr(str, n)=1 来表示做过了 n 号任务
|
11
micean 2018-03-05 14:51:43 +08:00
写反了……应该是 instr(str, '1')=n
|
13
MeteorCat 2018-03-05 19:09:36 +08:00 via Android
select id from black 单独获取放置在 NOSQL 之中,执行完一次放入之后 NOT IN 的条件直接获取
|
14
MeteorCat 2018-03-05 19:11:48 +08:00 via Android
对了,不用使用 mysql 内置 Rand 函数来做随机获取,效率和性能都不高
|
17
subdued 2018-03-05 19:23:27 +08:00 via Android
black 表 1 a-b-c-d......如果 1 后面是空的。就在总的账户里面取,然把 a 加到 black 表中。下一次。。先看是不是空的,不是空的就把比如 a 去掉 然后剩下的取 再加到 black 表中 会不会太麻烦了。,。。
|