计算多个登录和注销会话

时间:2014-02-14 17:17:21

标签: java mysql database performance

我正在设计一个系统,用户应在特定时间段内注册然后注销。他可以在白天多次登录和注销。我必须计算所有这些会话来衡量绩效。

那么为它设计数据库的最佳方法是什么

create table scheduler(
  ID  bigint auto_increment,
  userID varchar(100),
  start_session TIMESTAMP,
  end_session   TIMESTAMP,
  primary key(ID),
  INDEX(userID)
)

我必须插入用户的多个会话数据。那么我理想的任务是合乎逻辑的设计吗?还有一个信息,这将是一个实时系统。

2 个答案:

答案 0 :(得分:0)

创建表让我们说几个字段的“登录”,一个应该是:
 entrie_id
 userID(用户实际知道我们在谈论哪个用户)  日期(代表当天)
 login_amount(每次用户登录时应增加)默认值为0.

有了这个,你就会有日复一日的静力学。

在用户登录后包括更新数据库。

例如,如果用户登录ID为1,今天是2014-02-14。

您必须在登录表中搜索userID = 1和数据2014-02-14(现在是我们的情况),如果通过搜索这些来获取错误,请使用今天日期stam和用户ID创建新的entrie,否则将logins_amount更新1,所以如果它是第一次登录,它应该执行0 + 1,这样你就可以获得1的总登录数。

编辑:显然,对于注销,您可以在注销脚本部分执行相同操作。为此你可能需要添加另一个字段logout_amount等。

答案 1 :(得分:0)

除非您使用websockets,否则无法确定用户何时实际断开连接,因此我无法看到end_session将如何有意义。但是,如果您有第三个名为“visit”的表,则可以捕获给定会话下的所有http请求:

CREATE TABLE user(
  id            BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
  email         VARCHAR(255) NOT NULL,
  password      VARCHAR(255) NOT NULL,
  salt          VARCHAR(255) NOT NULL,
  created       DATETIME NOT NULL
);

CREATE TABLE session(
  id      BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
  user    BIGINT NOT NULL,
  created DATETIME NOT NULL
  index(userid)
);

CREATE TABLE visit(
  id            BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
  ip            VARCHAR(55) NOT NULL,
  uri           VARCHAR(255) NOT NULL,
  method        VARCHAR(20) NOT NULL,
  userAgent     TEXT NOT NULL,
  session       BIGINT NULL,
  user          BIGINT NULL,
  created       DATETIME NOT NULL
  index(userid)
);

这可以让您捕获有意义的数据。此外,如果您担心特定会话在X分钟后过期,只需在验证用户会话时将X分钟添加到创建的时间。或者当您正在寻找会话时,您可以使用创建时间的条件进行查询:

SELECT
  id,
  user,
  created
FROM session
WHERE created > {recent}

最近将等于当前时间 - X分钟。

为了更好的安全性,我建议为每个会话生成随机令牌,将用户的cookie值设置为用户id和会话令牌的AES GCM加密,然后生成随机盐以对会话令牌进行散列,最后存储在数据库中散列会话令牌+ salt。如果您只是将会话的id与cookie的值进行比较,我可以像任何用户一样对您的系统进行身份验证...如果您使用随机生成的令牌也是如此。

基于此我将会话表修改为更像这样:

CREATE TABLE session(
  id      BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL,
  user    BIGINT NOT NULL,
  token   VARCHAR(255) NOT NULL,
  salt    VARCHAR(255) NOT NULL,
  created DATETIME NOT NULL
  index(userid)
);

最后,我注意到你在你的架构中使用了TIMESTAMP ...这通常很好,只要知道你只能存储1970年到2038年的日期。

如果你想看到一个有效的例子,我可以在github上找到它:https://github.com/kaeawc/play-encryption

这里有一个工作演示:http://immense-garden-9877.herokuapp.com/