【问题标题】:PHP/SQL: Leveling/XP System for users on a website. How should I store the data? Thinking about sessionsPHP/SQL:网站用户的 Leveling/XP 系统。我应该如何存储数据?考虑会议
【发布时间】:2011-11-09 21:05:43
【问题描述】:

我希望用户能够在我的网站上获得 XP(经验值)。达到一定数量后他们会升级。

我需要有关如何处理所有数据的建议。更准确地说:XP 的数量和所代表的等级。

  • 用户级别将显示在每个顶部的栏中 页面。
  • 甚至可能是确切的 XP
  • 应该是高效的(不是很重的数据库)
  • 每个级别所需的 XP 都会有所不同(级别越高,需要的 XP 越多)

我为我的网站使用 CodeIgniter。
我猜我的 PHP 技能介于初学者和有经验的人之间:)


我的第一个想法:

“仅数据库”
将 xp 存储在我已经存在的“用户”表的列中。为了获得相应的级别,我将创建另一个包含 2 列的表:级别 --- 需要 XP
例如:

1 --- 0
2 --- 100
3 --- 500
等等

不得不承认,我真的不知道如何从中获得关卡。但我想它会以某种方式起作用。 但这意味着我每次都必须连接到数据库并从两个表中检索数据。我认为这不是一个好的解决方案。所以这里是

我的第二个想法:

“更新的会话”
将 XP 存储为会话数据,并在我的“用户”表中为 XP 创建一列。每次 XP 更改时,我都必须更新会话数据和数据库,但我不必访问数据库来检索 XP 的数量。我可以从会话数据中做到这一点。 (安全问题?!我对会话使用 CodeIgniters 加密)

为了获得关卡,我可能会在存储关卡的“用户”表中添加另一列。我可以使用获取相应级别(?)的 php 函数,而不是数据库中存储所需 XP 的额外表。那有意义吗?将为我节省额外的数据库连接。
类似于:get_level($xp)

要更新级别,我必须在每次更改 XP 时检查级别。效率高吗?

我如何准确地获得已知 XP 数字的相应级别?可以用PHP开关吗?


如你所见,我不知道自己在做什么;P
有很多想法,但似乎没有什么是最好的。

感谢任何帮助/建议 :)

问候
迪勒

【问题讨论】:

    标签: php sql database-design codeigniter


    【解决方案1】:

    我会有一个单独的表格来跟踪每个用户的事件及其相应的 XP 调整:

    • xp_events
      • 事件:事件为字符串或外键 ID 或其他。
      • user:有问题的用户。
      • delta:相应的 XP 更改。

    然后将总经​​验值和当前等级与您的用户一起存储。将触发器添加到xp_events 以在添加 xp 事件时更新用户表中的总 XP 和当前级别。我建议不要更改或删除 xp_events 中的条目,审计跟踪非常有用,您始终可以通过添加另一个事件来撤消一个事件。

    这种方法几乎可以免费为您提供摘要信息,因此您不必进行大量额外的聚合来计算用户的列表页面。您还可以在xp_events 中获得一份不错的历史记录,以供审核或以防万一人们想看到他们的进展。作为额外的奖励,您可以在xp_events 中获得审核跟踪,当您的触发器中有错误时,您可以使用它来重新生成每个用户的总 XP 和当前级别。

    您还希望在数据库中拥有 xp 到级别的信息,您的触发器将需要它,并且无论如何将所有数据都保存在数据库中不会有什么坏处。像这样的:

    min_xp | level
    -------+------
         0 | 1
       100 | 2
       500 | 3
      1000 | 4
    ...
    

    然后你可以通过以下方式获得$xp XP 的等级:

    select max(level)
    from xp_levels
    where $xp - min_xp >= 0
    

    【讨论】:

    • 非常感谢。我喜欢事件列表的想法,以了解为什么有人获得 X 数量的 XP。对用户来说可能非常好。 “事件”将是 XP 更改的原因,对吗?类似于:事件:“回答正确”,user_id:“1”,delta:“+5”。触发器是什么意思?我想到了一个更新 xp_event 表的 php 函数,然后是存储总 xp(旧总 xp + xp 更改)的用户表,然后检查 xp 是否足够高以达到新的水平,并在需要时更新它。您还有其他解决方案吗?
    • @DiLer:是的,“事件”将是触发 XP 更改的任何东西,我想不出还有什么可以称呼它的。触发器是数据库中的一些代码,在插入、更新或删除行时对数据执行操作;这是一些MySQL information。你可以在 PHP 中做同样的事情,但是如果同时处理两个 XP 事件,你可能会遇到并发问题,使用数据库触发器可以避免这个问题;当您在 xp_events 中插入某些内容时,触发器会触发,它会为您更新用户。
    • 哦,谢谢,我不知道。我一定会读一读。看起来很有趣。 :)
    【解决方案2】:

    您需要将 XP 存储在数据库中并每次都进行查询。您可以将它存储在会话等中,但除了可能充当短暂的缓存之外,它没有多大意义......但我怀疑你会注意到任何性能成本(会话不是免费)。非常简单和重复的查询基本上是免费的。

    最好将Level 也存储在数据库中,而不是从XP 中派生出来……但这取决于你。如果您不想存储它,只需保留一个包含所有级别及其 XP 要求的数组。然后,您只需遍历数组,直到找到与用户拥有的 XP 数量相对应的等级。

    如果没有更具体的问题,我发现很难比这更深入。

    但总而言之,将 XP 存储在数据库中,如果您愿意,也可以将 Level 存储...并且每次都查询。

    附言。此外,如果您是初学者,请确保在将所有用户数据放入 SQL 查询之前对其进行转义! mysql_real_escape_string() ... 否则你会发现一些用户在做各种你不希望他们做的事情。

    PS2。忘记这个级别的性能问题,你不会有它们......如果你开始在循环中循环并在每个请求中查询成千上万条记录......那么你需要仔细检查你在做什么。

    【讨论】:

    • 感谢您的帮助 :) 所以我想我也存储了关卡。我猜再多一个查询应该不是问题?!我有一个网站,可以显示网站上的每个用户以及(将来)他们的级别。从 xp 计算每个级别可能比从我连接到的数据库中获取更多的工作......
    • @DiLer 我的建议是在合理的范围内为自己做一切尽可能简单的事情。您可以轻松地对每个请求执行 10 个基本的 1 行查询,而无需担心性能。大多数论坛可以为每个页面请求执行 10-20 个稍微复杂的查询。所以说真的,让自己变得简单,忘记性能,快速开发更重要......但是,请确保为您的查询创建适当的索引!
    • 嗯,这将是一个简单的“user_id = X”或类似的东西。所以我想这是合适的。 CodeIgniter 默认转义所有用户输入。是啊,反正页面只供几个人使用,但有好的表现也无妨,嘿嘿:)
    • @DiLer 是的,差不多,除非你有一个很大的数据库,否则你可以告诉 MySQL 将所有内容都保存在内存中,从而使非连接查询几乎免费。所以说真的,别想了,只是不要在循环等内部进行查询。
    • 好的,谢谢 :) 我必须查一下,但我认为 CodeIgniter 甚至可以帮助处理经常执行的简单查询。您可以缓存它们等。考虑到这一点,我想这确实是最好和最简单的方法。感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 2018-02-03
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多