【问题标题】:Should I create a separate database table for temporary users我应该为临时用户创建一个单独的数据库表吗
【发布时间】:2011-12-08 11:45:42
【问题描述】:

我有一个用户表来控制对网站的访问。我们目前有几百个用户,最终可能会增长到几千个。我们要求允许“临时”用户进入。这些临时用户将拥有一个超时的令牌,永远不会再次使用。这些代币的数量可能会大大超过普通用户。我的问题是这些临时用户应该存储在通用表中还是他们自己的表中。

我的倾向是与用户 ID 在其他地方用作外键相同的表,并且对于临时用户仍然有用。 id 的唯一性很重要。但是,我不高兴用户表将充满许多不再需要使用的记录,因此会减慢表的速度。

我考虑过的另一个选项是创建用户记录,捕获 id,删除记录,然后在另一个表中使用 id。因此,我保留了 id 的唯一性,但减少了表格的膨胀。我不介意外键是否引用不同的表。

有人遇到过类似的问题,有什么想法吗?

【问题讨论】:

  • 你可能还想在dba.stackexchange.com上问这个问题
  • 如果它们执行相同的数据库功能,我会将它们放在同一个地方。关于膨胀,是否可以在令牌过期后(或几周/几个月/几年后或您是否需要保留其数据?)简单地清除记录,或者添加一个状态列“非活动”,索引并始终按它过滤。由于非临时用户离开删除也增加了价值。
  • 我也可能会询问 dba,但您让我放心,我没有遗漏一些明显的东西。只是感觉有点不对劲(现在仍然如此),但我找不到实质性的技术论据。谢谢。

标签: database database-design


【解决方案1】:

只要您索引 ID 或将其作为主键,表的大小就不会影响性能。

如果需要,我建议将用户记录留在那里以保留外键约束 - 添加外键也可以提高检索数据时的性能,而不是“软”外键。

如果有意义,您可以将用户与临时用户分开。

【讨论】:

  • “添加外键将提高性能”取决于 dbms。例如,PostgreSQL 的查询计划器根本不考虑外键声明。 (它们对 SELECT 性能没有影响。)
【解决方案2】:

使用同一张桌子。至于性能问题:添加一个显示“临时”的列,当您不想要临时用户时,只需将其过滤为“假”。这不会减慢表格的速度(如果您还向该表格添加索引,则更是如此。)

【讨论】:

    【解决方案3】:

    我们目前有几百个用户,并且最终可能会增长 到几万。

    所以您考虑的是 30,000 到 40,000 个用户。除非您的用户表设计不当或索引不佳,否则 10 倍的用户数不会对性能产生太大影响。但就 SO 提出这个问题并不是解决问题的最佳方法。

    最好的方法是在开发计算机上构建一个用户表,填充 10 倍于您期望的数据,然后对其进行测试。我在这里做到了。我花了 1 分 53 秒(1 分 53 秒),其中包括停下来泡茶。选择一个用户需要 0.049 毫秒,并且使用了索引扫描。

    以下是使用 PostgreSQL 的方法。

    create table users (
      user_id integer primary key,
      user_name varchar(15) not null default '01234567890123',
      -- Use as many other text columns as you need. For testing your scenario,
      -- the values don't matter. They just make the table wider, slower, and
      -- more realistic.
      other_text_1 varchar(30) not null default '01234567890123456789012345678'
    );
    
    insert into users (user_id)
    select generate_series(1,300000);
    
    analyze users;
    
    explain analyze
    select * 
    from users
    where user_id = 200676;
    
    Index Scan using users_pkey on users  (cost=0.00..8.30 rows=1 width=49) (actual time=0.014..0.015 rows=1 loops=1)
      Index Cond: (user_id = 200676)
    Total runtime: 0.049 ms
    

    对于更复杂或更随机的数据,请使用脚本语言。 (Perl、ruby、python ......)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 2018-03-20
      相关资源
      最近更新 更多