mysql – 如何在考虑权重的情况下随机选择一行?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了mysql – 如何在考虑权重的情况下随机选择一行?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1657字,纯文字阅读大概需要3分钟。
内容图文
我有一张看起来像这样的表:
id: primary key
content: varchar
weight: int
我想要做的是从该表中随机选择一行,但考虑到重量.例如,如果我有3行:
id, content, weight
1, "some content", 60
2, "other content", 40
3, "something", 100
第一行有30%被选中的机会,第二行被选中的几率为20%,第三行被选中的几率为50%.
有没有办法做到这一点?如果我必须执行2或3个查询,这不是问题.
解决方法:
我已经尝试过van的解决方案,虽然它有效,但它并不快.
我的解决方案
我解决这个问题的方法是为权重维护一个单独的链接表.基本表结构与此类似:
CREATE TABLE `table1` (
`id` int(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` varchar(100),
`weight` tinyint(4) NOT NULL DEFAULT '1',
);
CREATE TABLE `table1_weight` (
`id` bigint(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`table1_id` int(11) NOT NULL
);
如果我在table1中有一个权重为3的记录,那么我在table1_weight中创建3条记录,通过table1_id字段链接到table1.无论表1中的权重值是多少,这就是我在table1_weight中创建的链接记录数.
测试
在table1中有976条记录的数据集中,总权重为2031,因此table1_weight中有2031条记录,我运行了以下两个SQL:
> van解决方案的一个版本
SELECT t.*
FROM table1 t
INNER JOIN
( SELECT t.id,
SUM(tt.weight) AS cum_weight
FROM table1 t
INNER JOIN table1 tt ON tt.id <= t.id
GROUP BY t.id) tc ON tc.id = t.id,
( SELECT SUM(weight) AS total_weight
FROM table1) tt,
( SELECT RAND() AS rnd) r
WHERE r.rnd * tt.total_weight <= tc.cum_weight
ORDER BY t.id ASC
LIMIT 1
>加入辅助表进行加权
SELECT t.*
FROM table1 t
INNER JOIN table1_weight w
ON w.table1_id = t.id
ORDER BY RAND()
LIMIT 1
SQL 1始终持续0.4秒.
SQL 2需要0.01到0.02秒.
结论
如果选择随机加权记录的速度不是问题,则van建议的单表SQL很好,并且没有维护单独表的开销.
如果,在我的情况下,短的选择时间是关键的,那么我会建议两个表方法.
内容总结
以上是互联网集市为您收集整理的mysql – 如何在考虑权重的情况下随机选择一行?全部内容,希望文章能够帮你解决mysql – 如何在考虑权重的情况下随机选择一行?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。