我想建立一个MySQL数据库来存储每1小时一场比赛的排名。 由于这个数据库在短时间内会变得相当大,因此我认为正确的设计很重要。因此,我们将不胜感激一些建议。
为了使其尽可能小,我决定只记录排名的前 1500 个位置。玩家的每个排名都包含以下值:
排名位置、玩家姓名、地点、坐标、联盟、种族、等级1、等级2、积分1、积分2、积分3、积分4、积分5、积分6、日期/时间
我的方法是通过 PHP 脚本每小时简单地获取每个前 1500 名玩家的所有值,并将它们作为一行插入到 MySQL 中。所以MySQL每天都会增加36,000行。我将有第二个脚本来删除超过 28 天的每一行,否则数据库将变得非常巨大。这两个脚本都将作为 cronjob 运行。
将对此数据执行以下查询:
- 最重要的是查询某个名称。它应该以数组形式返回玩家每小时的所有统计数据。
- 第二个是一个查询,其中必须返回从最新条目开始的特定时间段内未获得积分 1 的所有玩家。这应该返回未获得积分的玩家列表(例如过去 24 小时)。
- 第三个是一个查询,其中应列出自最新条目以来在特定时间段内失去一定数量或更多积分2的所有玩家。
查询不应该花费一生的时间,所以我想我应该索引玩家名、points1 和 point2。
我的方法是否可以接受,或者我会遇到性能/处理灾难吗?也许有更好的方法吗?
最佳答案
这里是您可能遇到性能问题的地方:
索引会加快读取速度,但会大大减慢写入速度。特别是因为在任何给定时间,您的数据库在该表中都会有超过 100 万行。由于写入是通过 cron 进行的,因此只要批量插入 1500 行而不是每行都到数据库进行一次往返,就应该没问题。我还会研究查询编译,以便您也节省开销。
Ranhiru Cooray 是正确的,您应该只在数据库中存储一次诸如玩家姓名之类的数据。创建球员表并使用主键引用排名表中的球员。
地点
、联盟
和种族
也是如此。我猜测这些或多或少是枚举值,您可以将它们存储在另一个表中以标准化您的设计,并通过适当的JOIN
返回到您的结果中。规范化数据将减少数据库中的冗余信息量,从而减小数据库的大小并提高其性能。您的设计在
排名位置
方面也可能存在缺陷。当您选择行时,数据库不能计算吗?如果不行的话可以用PHP实现吗?它与发票表相同,您永远不会存储发票总额,因为它是多余的。商品/定价/等可用于计算订单总额。随着所有的添加/删除,我一定要经常运行
OPTIMIZE
并保持良好的备份。 MySQL 表(如果使用 MyISAM)在高写入/删除场景中很容易被损坏。在这些情况下,InnoDB 往往表现得更好一些。
这些都是需要考虑的事情。希望对您有所帮助。
关于mysql - MySQL数据库的正确设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6006034/