MySQL数据库的正确设计
我想建立一个MySQL数据库,用于存储每1小时一次的游戏排名。 由于这个数据库将在短时间内变得相当大,我认为正确的设计是很重要的。因此,如果您能提出一些建议,我们将不胜感激 为了让它尽可能小,我决定只记录排名的前1500个位置。玩家的每个排名都包含以下值:MySQL数据库的正确设计,mysql,sql,database-design,data-modeling,Mysql,Sql,Database Design,Data Modeling,我想建立一个MySQL数据库,用于存储每1小时一次的游戏排名。 由于这个数据库将在短时间内变得相当大,我认为正确的设计是很重要的。因此,如果您能提出一些建议,我们将不胜感激 为了让它尽可能小,我决定只记录排名的前1500个位置。玩家的每个排名都包含以下值: 排名位置、玩家名称、位置、坐标、联盟、种族、级别1、级别2、点1、点2、点3、点4、点5、点6、日期/时间 我的方法是通过一个php脚本每小时获取每个排名前1500的播放器的所有值,并将它们作为一行插入MySQL。因此,MySQL每天将增长3
排名位置、玩家名称、位置、坐标、联盟、种族、级别1、级别2、点1、点2、点3、点4、点5、点6、日期/时间 我的方法是通过一个php脚本每小时获取每个排名前1500的播放器的所有值,并将它们作为一行插入MySQL。因此,MySQL每天将增长36000行。我将有第二个脚本,删除每一行超过28天,否则数据库将变得异常庞大。这两个脚本都将作为cronjob运行 将对此数据执行以下查询:
- 最重要的是查询某个名称。它应该以数组的形式返回玩家每小时的所有属性李>
- 第二个是一个查询,在该查询中,必须返回在某个时间段内从最新条目中未获得点数1的所有玩家。这将返回一个没有获得积分的玩家列表(例如最近24小时)李>
- 第三个是一个查询,在该查询中,应该列出在某个时间段内从最新条目中丢失一定数量或更多点数2的所有玩家
我的方法是否可以接受,或者我是否会遇到性能/处理灾难?有没有更好的方法可以做到这一点?这里是您冒性能问题风险的地方:
- 索引将加快读取速度,但会大大降低写入速度。特别是因为您的数据库在任何给定时间都将在该表中有超过100万行。由于您的写操作是通过cron进行的,因此只要成批插入1500行,而不是每行一次到数据库的往返,就可以了。我还将研究查询编译,以便节省开销
- Ranhiru Cooray是正确的,您应该只在数据库中存储一次类似于播放器名称的数据。创建一个玩家表,并使用主键引用排名表中的玩家。对于
、位置
和联盟
也将如此。我猜这些或多或少都是枚举值,您可以存储在另一个表中以规范化您的设计,并在结果中使用适当的比赛
s返回。规范化数据将减少数据库中的冗余信息量,从而减小数据的大小并提高其性能JOIN
- 您的设计在您的
排名中也可能存在缺陷。当您选择行时,DB是否可以计算该值?如果没有,可以用PHP来完成吗?这与发票表相同,您从不存储发票总额,因为它是冗余的。项目/定价/etc可用于计算订单总额
- 在所有添加/删除操作中,我一定要经常运行
,并保持良好的备份。MySQL表——如果使用MyISAM——在高写/删除场景中很容易损坏。在这些情况下,InnoDB往往会稍微好一点优化
这些都是需要考虑的事情。希望有帮助。如果数据库设计得当,我认为您不需要存储玩家名称、联盟或种族。这些将简单地存储在player表中,不会在排名表中重复。对于MySQL来说,每天36000行并不是很多行。当你达到一百万的时候,回来问一些关于表现的问题。您正在进行未经分析的预成熟优化,我们都应该知道这是所有罪恶的根源。我认为,将每一行简单地“按输入”存储会更好的原因是,有些玩家可能会从前1500名中退出,而其他玩家则会进入新的排名。因此,当cronjob执行插入操作时,不需要进行比较,因此不需要从数据库中提取数据。否则,我必须检查添加的每一行在player表中是否存在用户名。这不是性能更密集吗?另外,php的最大执行时间肯定会成为一个问题,因此脚本需要快速。排名网站的http获取也将是一个时间野兽。我在如此大型的星展银行没有经验,因此我将依靠这里的专业知识。当然,插入要比获取多得多。每天只有5个人会使用这个数据库几次。遗憾的是,我不得不承认,到目前为止,我在测试中插入了每一行,每一行都有一个对DB的调用。我可能会把它提高到一次插入100个。但以上任何事情都是一个问题。我无法同时获取所有排名数据,因为php执行时间最长。因此cronjob必须调用多个脚本(秩1-100、101-200…)。第2点见上面的评论,3关于PHP的最大执行时间,您是对的,我将在您的cron中覆盖它,使其成为一个更合理的数字:set_time_limit(5000);