Database 跟踪用户最近活动的策略

Database 跟踪用户最近活动的策略,database,database-design,user-input,n-tier-architecture,Database,Database Design,User Input,N Tier Architecture,我们的客户想知道谁在线并且正在使用我们为他们编写的自定义应用程序。我和他们讨论过,这不需要精确,更多的客户估计会起作用 所以我的想法是用15分钟的时间间隔来确定用户活动。我对此的一些想法如下: 每次他们做一些访问数据库的事情,或请求一个网页时,都在他们的用户记录上打上他们上次活动的日期和时间戳。。。不过,这可能需要大量的数据库 从我们的软件发送“谁在线请求”,寻找响应,这可以在预定的时间间隔内完成,然后在用户记录上标记我收到的每个响应的当前日期和时间 你的想法是什么?你会如何处理这种情况 澄清

我们的客户想知道谁在线并且正在使用我们为他们编写的自定义应用程序。我和他们讨论过,这不需要精确,更多的客户估计会起作用

所以我的想法是用15分钟的时间间隔来确定用户活动。我对此的一些想法如下:

  • 每次他们做一些访问数据库的事情,或请求一个网页时,都在他们的用户记录上打上他们上次活动的日期和时间戳。。。不过,这可能需要大量的数据库

  • 从我们的软件发送“谁在线请求”,寻找响应,这可以在预定的时间间隔内完成,然后在用户记录上标记我收到的每个响应的当前日期和时间

  • 你的想法是什么?你会如何处理这种情况

    澄清

    如果可能的话,我想在Windows或Web上使用相同的体系结构。我有一个单一的业务逻辑层,可以与多个用户界面交互,可以是Windows或Web

    我所说的Windows是指客户端服务器

    澄清

    我使用的是n层体系结构,因此我的业务对象处理与表示层的所有交互。该表示层可以为客户机-服务器Windows应用程序、Web应用程序、Web服务等提供数据


    它不是一个高流量的应用程序,因为它是为我们的客户开发的,最多可能有100个用户。

    我以前见过策略1起作用。当然,这个网站很小

    我只需在数据库中删除一个日志记录表

    用户ID int FK
    动作字符(3)(“输入”或“输出”)
    时间日期时间


    当有人登录或注销时,您可以在表中删除一条新记录,或者为用户更新最后一条记录。

    我使用过许多系统,它们使用了您列出的第一种方法,经过一点仔细的规划,可以以一种实际上没有多大效果的方式完成

    这完全取决于你到底什么时候/如何/试图跟踪什么。如果您需要跟踪多个会话,我通常会看到使用绑定到用户帐户的会话系统的人,然后在经过特定时间后,该会话被视为已死亡


    如果你真的在网上寻找,你的第一个选择是最好的。

    如果你有会话数据,就使用它。大多数会话系统已经有时间戳,因此它们可以使x分钟内未使用的会话过期

    您可以在每次创建用户会话时递增全局变量,并在销毁时递减。这样,您将始终知道在任何给定时刻有多少用户在线

    另一方面,如果您想随时间监视它,我认为将会话开始和结束记录到数据库是最好的选择,您可以通过一个简单的查询来计算用户活动。

    [免责声明1---Java解决方案]

    如果给每个有意义的用户一个会话,那么您可以编写自己的SessionListener实现来跟踪创建和销毁的每个会话

    [免责声明2——未测试或编译的代码]

    public class ActiveSessionsListener implements HttpSessionListener {
        public void sessionCreated(HttpSessionEvent e) {
            ServletContext ctx = e.getSession().getServletContext();
            synchronized (ctx) {
                Integer count = ctx.getAttribute("SESSION_COUNT");
                if (count == null) { count = new Integer(0); }
                ctx.setAttribute("SESSION_COUNT", new Integer(count.intValue() + 1);
            }
        }
        public void sessionDestroyed(HttpSessionEvent e) {
            ... similar for decrement ...    
        }
    }
    
    并在web.xml中注册:

    <listener-class>com.acme.ActiveSessionsListener</listener-class>
    
    com.acme.ActiveSessionListener
    

    希望这能有所帮助。

    web应用程序解决方案的唯一问题是您通常不知道何时有人注销。显然,如果您有登录/身份验证需求,您可以捕获某人何时登录,并且作为数据访问代码的一部分,您可以在某人访问数据库时登录。但你必须承认,当一个人注销时,会有一种可靠的捕获方式——许多人只是离开网站而没有“注销”行动。

    我认为使用触发器将是一个合理的选择,可以避免您必须处理web和非web环境(或任何其他环境)之间的任何逻辑差异。但是,这只捕获对环境的更改,在执行select语句时不会执行任何操作。但是,如果应用程序中的所有命令都通过存储过程运行,则可以克服这一问题。

    我想知道像stackoverflow这样的网站是如何做到的


    他们必须针对一个特定的事件,因为我刚刚在网站上浏览了一下,看了看我的个人资料,还说了一些类似于8分钟前最后一次看到的

    我们的解决方案是维护一个“事务”表(遵循所做的事情),除了“会话”表(遵循谁在这里)之外。UPDATE、INSERT和DELETE指令都是通过一个“Transaction”对象进行管理的,一旦在数据库上成功执行,这些SQL指令中的每一条都存储在“Transaction”表中(取决于更新的表:我们有可能专门遵循某些表而忽略其他表)。这个“Transaction”表还有其他字段,如transactiontType(I表示插入,D表示删除,U表示更新)、transactionDateTime等,还有一个外键“sessionId”,告诉我们最终是谁发送了指令。甚至可以通过一些代码来识别谁做了什么,何时做了什么(Gus在周一创造了记录,Tim在周二改变了单价,Liz在周四增加了额外折扣,等等)

    此解决方案的优点是:

  • 您可以告诉“什么人和什么时候”,并向您的用户显示它!(您需要一些代码来分析SQL语句)
  • 如果复制了数据,但复制失败,则可以通过此表重建数据库
  • 缺点是

  • 每月10万次数据更新意味着Tbl_事务中有10万条记录
  • 最后,此表往往占数据库卷的99%

  • 我们的选择:所有超过90天的记录每天早上都会被自动删除

    使用一个web应用程序,即“onl”的概念
    <?php
    function updateLastSeen($user_ref, $session_id, $db) { /*Parameters: The user's primary key, the user's session id, the connection to the database*/
      $timestamp = date('Y-m-d H:i:s');
      if ($session_id !== '') {
        /*logged in*/
        $sql_check = "SELECT user_id FROM user_last_seen WHERE user_id = ?";
        $stmt_check = $db->prepare($sql_check);
        $stmt_check->bind_param('s', $user_ref);
        $result_check = $stmt_check->execute();
        $stmt_result_check = $stmt_check->get_result();
        if ($stmt_result_check->num_rows > 0) { /*If the user's last seen was previously recorded, update his record*/
          $sql = "UPDATE user_last_seen SET last_seen = ? WHERE user_id = ?"; 
        } else { /*Otherwise, insert a record for him*/
          $sql = "INSERT INTO user_last_seen (last_seen, user_id) VALUES (?,?)";
        }
        $stmt = $db->prepare($sql);
        $stmt->bind_param('ss', $timestamp, $user_ref);
        $result = $stmt->execute();
      }
    }
    if( !isset($_SESSION['lastSeen']) ){ /*User logs into the website or lands on the current page, create a lastSeen variable*/
      $_SESSION['lastSeen'] = time();
      updateLastSeen($user_ref, $session_id, $db);
    } else {
      $last_seen_time_difference = (time() - $_SESSION['lastSeen']) / 60;
      if ($last_seen_time_difference > 5) { //if the difference between now and the lastSeen is 5 minutes or more, record his last seen.
        updateLastSeen($user_ref, $session_id, $db);   
        $_SESSION['lastSeen'] = time(); /*after updating the database, reset the lastSeen time to now.*/
      }/* else {
        //do nothing. Don't update database if lastSeen is less than 5 minutes ago. This prevents unnecessary database hits.
      }*/
    }