今天遇到了一道面试题,如下某网页可容纳10万用户在线,超出的用户无法访问页面,并告知该用户当前排队位置,当有用户以任何形式退出,排队顺位更改,符合条件的用户自动进入该页面,请写出相关数据库结构和主要逻辑。

解决方案 »

  1.   

    在线用户表
    id 自增主键
    username用户首次登入:加入用户至表中,获取 id 到 $id 作为在线id
    select count(*) from 表 where id<$id
    如果结果小于 10万,则返回页面和在线id
    否则仅返回 在线id用户登出:删除相应 id
      

  2.   

    删相应ID后,ID并不是重新计算的,是在最后的ID上递增。
    也就是说当ID99999被删后,再进来一个,那ID就是100000,这样的自增办法并不是最佳。
      

  3.   

    我有一种方法  user用户表加个
    status字段  登录时间up_time字段
    用户登录,则状态为1,查询status为1,up_time大于自己的up_time的用户数num,if数量超过10万,
    则在前面的为总数量减10万为自己的排队数ret,状态status为2,当有人退出,
    系统查询时间条件,给予权限10万名可进入系统
      

  4.   

    使用redis队列即可。
      

  5.   

    mysql的话用版主的方法设计即可
    假设一个人取到100001号,每次查询比自己id小的,如果前面有一个id删了,<100001的用户就刚好是100000个,就可以进入了
    并发情况下因为用了mysql的自增主键,再多人访问都会有个先后不会取得一样的id,一般压力不会大到mysql撑不住都没事
    改user表的设计太坑,本来一个独立的功能还要和user模块耦合,如果同时两个页面要排队怎么办
    用redis队列是更好的方案,性能会好很多
      

  6.   

    有redis
      

  7.   

    这思路不错,可问题是10万的数据访问量,数据库吃的消吗?我觉得用redis自增好,思路跟你说的差不多。但是效率比数据库快很多,而且不占数据库资源
      

  8.   

    那你认为 redis 是什么?他不也是 NoSQL 数据库的一种吗?
    为什么要狭隘的理解数据库呢?数据库,顾名思义就是存放数据的仓库,至于采用什么架构并不是主要问题
      

  9.   

    我一直以为redis跟memcache一样
      

  10.   

    [b]频繁请求数据库不太现实,就像楼上说的那样,用redis比较靠谱;
    具体你可以参考一下,做一个线性队列,先进先出,定义一个array【length=10w】用于保存数据,头部插入 array_unshift,获取尾部end(),清楚尾部数据array_pop ,序列化后保存结果值redis;
    crontab配置好,队列不为空就执行数据
    愚见~
      

  11.   

    这样的话,id删除后依旧占用。返回在线id使得排队顺序不准确
      

  12.   

    id 只是唯一标识
    递增的 id 可表示曾经出现过
    如过 id 被复用,那才会造成混乱这样的话,id删除后依旧占用。返回在线id使得排队顺序不准确
      

  13.   

    可以用 redis  的有序集合 解决
    排序值 是  当前时间, 
    value值 是 当前用户的sessionId当用户检查是否能访问的时候 先把 所有排序值 与当前时间对比,如果小于 10分钟 的就删除, 表示用户如果不做任何操作10分钟就自动退出。并且检查自己在不在这个集合里,如果在的话,就更新 排序值 为当前时间,如果不在就检查集合的总数,看是否已超过10万,如果没有就插入,并且排序值 为当前时间, 如果超过了就提示用户要排队等待。