Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL数据库的正确设计_Mysql_Sql_Database Design_Data Modeling - Fatal编程技术网

MySQL数据库的正确设计

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

我想建立一个MySQL数据库,用于存储每1小时一次的游戏排名。 由于这个数据库将在短时间内变得相当大,我认为正确的设计是很重要的。因此,如果您能提出一些建议,我们将不胜感激

为了让它尽可能小,我决定只记录排名的前1500个位置。玩家的每个排名都包含以下值:
排名位置、玩家名称、位置、坐标、联盟、种族、级别1、级别2、点1、点2、点3、点4、点5、点6、日期/时间

我的方法是通过一个php脚本每小时获取每个排名前1500的播放器的所有值,并将它们作为一行插入MySQL。因此,MySQL每天将增长36000行。我将有第二个脚本,删除每一行超过28天,否则数据库将变得异常庞大。这两个脚本都将作为cronjob运行

将对此数据执行以下查询:

  • 最重要的是查询某个名称。它应该以数组的形式返回玩家每小时的所有属性
  • 第二个是一个查询,在该查询中,必须返回在某个时间段内从最新条目中未获得点数1的所有玩家。这将返回一个没有获得积分的玩家列表(例如最近24小时)
  • 第三个是一个查询,在该查询中,应该列出在某个时间段内从最新条目中丢失一定数量或更多点数2的所有玩家
查询不应该花费一生的时间,所以我想我应该索引playername、points1和points2


我的方法是否可以接受,或者我是否会遇到性能/处理灾难?有没有更好的方法可以做到这一点?

这里是您冒性能问题风险的地方:

  • 索引将加快读取速度,但会大大降低写入速度。特别是因为您的数据库在任何给定时间都将在该表中有超过100万行。由于您的写操作是通过cron进行的,因此只要成批插入1500行,而不是每行一次到数据库的往返,就可以了。我还将研究查询编译,以便节省开销

  • Ranhiru Cooray是正确的,您应该只在数据库中存储一次类似于播放器名称的数据。创建一个玩家表,并使用主键引用排名表中的玩家。对于
    位置
    联盟
    比赛
    也将如此。我猜这些或多或少都是枚举值,您可以存储在另一个表中以规范化您的设计,并在结果中使用适当的
    JOIN
    s返回。规范化数据将减少数据库中的冗余信息量,从而减小数据的大小并提高其性能

  • 您的设计在您的
    排名中也可能存在缺陷。当您选择行时,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);