数据库 关于随机转到一个帖子的实现

Yunich · 2013年01月07日 · 最后由 pobing 回复于 2013年08月04日 · 3505 次阅读

我想问下如果要实现一个链接可以随机转到社区的某个帖子,这该如何实现

我自己想的一个方法...刚学 rails 没多久。在 controller 端获得一个@blog=Blog.last,前台做一个<%form_tag blog,:method=>"post"%> <%=hidden_field_tag(:id,value=rand(Time.now.to_i)%@blog.id)%>,额,这个方法不好,但应该能实现吧~~~

可以通过随机 id 实现

def pickme
  items = Item.select('id')
  item = Item.find(items[Random.rand( items.length)])
  redirect_to item_path(item)
end

上面这个性能不会太好,需要在这个基础上,给 Item.select('id') 加上缓存或随机分页

#3 楼 @suupic ~呵呵,学到了,刚学 rails 三个星期的学生一个。。。~

def random_topic random_topic unless topic = Topic.find(rand 3000) end

30000 就是个占位,填进数据的大概数目就行了

只能保佑 id 字段是连续的不会缺号,不然Random.rand( items.length)会得到一个 nil 的对象出来, 如果有判断是否是已删除帖子之类的delete_flag字段的话,这里应该也要带上这个字段一起检索

#6 楼 @ywjno Random.rand( items.length) 是用来取 items 中元素的,id 不连续也不会出 nil

item = Item.find(Item.pluck(:id).sample)

以 id 查询应该不会太慢吧

#7 楼 @suupicitems = Item.select('id')动作之后有人删了帖子造成某个 item 不存在,这时候再item = Item.find(items[Random.rand( items.length)])是不是会出现 find 不到 item 的情况,是不是这地方加数据库事务进行处理

#9 楼 @ywjno 这两个操作之间只有 0.0x 秒..不需要考虑这种问题吧

#10 楼 @suupic 做多企业项目,编码规约里面有那么些玩意习惯了。。 然后我想到一个好方法,不就是随机转到社区的某个帖子么,信息量不会是那么大撑死需要个帖子 url 跟 title,干脆直接

def pickme
  items = Item.select("你需要的字段")
  item = items[Random.rand(items.length)]
  redirect_to item_path(item)
end

这样能只用进行一次检索数据库有索引的话效率应该不会太慢

#11 楼 @ywjno #8 楼 @diudiutang #3 楼 @suupic 目测不靠谱,Item 有个几十万行的时候你们试试!全表查询啊!

#12 楼 @huacnlee 所以我说要加缓存或者分页呀

#12 楼 @huacnlee 对于有几十万的论坛帖子,那种随机出来的肯定都是伪随机了,比如 created_at 在一星期之内的,再说能产生那么大帖子的论坛早就分讨论区了吧,数据库即使没分表在检索数据的时候 where 条件不是带上该分区的标识更好

记得有看到一个思路,不直接用 ID,大于某个随机数就行了

Item.where("id > ?", rand_method).first

刚才在一张 200w 的表上测了下

item = Item.find(Item.pluck(:id).sample)

其实只是去查询主键 id 而已,1 秒很快的

(1131.2ms)  SELECT id FROM `users`
User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1764711 LIMIT 1

#16 楼 @diudiutang 1s 还快!? 话说 #15 楼 @cxh116 的就是很靠谱的方法

看起来是个假想的问题。想不出在实际项目里面在在足够大的表里面随机取记录对用户体验有什么帮助。加入任何的约束,比如说在最近 x 天,或者依靠某种相关度的算法,都是对用户体验的提升。

@其实我是在果壳网看到的一篇文章,关于作者做了一个能随机进入一篇文章的链接http://www.guokr.com/blog/412815/ 我觉得实际项目中还是可能有这样的需求

#15 楼 @cxh116 這個方法不錯。。

Topic.order("updated_at desc").first 最后一个更新过的帖子,基本上就是随机了. 如果是 order rand,遇上贴子数量多,那服务器吃不消

匿名 #22 2013年01月09日

redis set srandmember

#18 楼 @knwang 应该有这种情形,现在一般网站的大众审贴功能,每次给用户随机呈现一个审核未通过的帖子,审核一个帖子跳到下一个随机的帖子。貌似 sql 语句能达到要求。http://www.111cn.net/database/mysql/40168.htm

需要 登录 后方可回复, 如果你还没有账号请 注册新账号