简体   繁体   English

创建可伸缩的数据库架构以存储高尔夫分数

[英]Create a scalable database schema for storing golf scores

I am trying to design a database to store all my friends and my golf scores. 我正在设计一个数据库来存储我所有的朋友和我的高尔夫比分。 As you probably know, a golf score is comprised of 18 hole individual scores. 您可能知道,高尔夫球得分由18洞个人得分组成。 I can think of two ways to design the schema: 我可以想到两种设计架构的方法:

  1. Create a table that has one column for each hole (eg h1 to h18), the table has FK player_id, round_id and course_id that referenced other tables. 创建一个每个孔有一列的表(例如h1到h18),该表有FK player_id,round_id和引用其他表的course_id。 It has a total column, which is the sum of columns h1 to h18. 它有一个总列,它是列h1到h18的总和。 If I change a hole score, I will need to manually update total column. 如果我更改了一个得分,我将需要手动更新总列数。

  2. Create a table that has a column for hole score, a column for hole index, a column for player_id, course_id, and round_id. 创建一个表,其中包含用于孔得分的列,用于孔索引的列,用于player_id的列,course_id和round_id。 To get the total score for a round, I will need to do a SUM query on round_id, player_id. 要获得一轮的总分,我需要在round_id,player_id上进行SUM查询。

For now, the database would probably store scores from less than 20 people, so either approach should be fine. 目前,数据库可能会存储少于20人的分数,因此任何一种方法都应该没问题。 But what if I want to store scores for 20,000 people, which approach is more scalable? 但是,如果我想为20,000人存储分数,哪种方法更具可扩展性呢?

I am using MySQL 5, with PHP5. 我正在使用MySQL 5,PHP5。 Thanks. 谢谢。

Update> Examples of queries: 1. Reading the 9/18 scores from all players for a round and building a scorecard. 更新>查询示例:1。阅读所有玩家的9/18分数并建立记分卡。 2. Basic stats like finding the lowest/average/highest total scores for a player for the last X rounds. 2.基本统计数据,例如查找最后X轮的玩家的最低/平均/最高总得分。 3. More advanced stats like average score of any hole for the last X rounds. 3.更高级的统计数据,比如最后X轮的任何球洞的平均得分。

What was my average, highest and lowest score? 我的平均分,最高分和最低分是多少?

Scenario 1. 场景1。

select (h1+h2+h3+h4+h5+h6+h7+h8+h9+h10+h11+h13+h14+h15+h16+h17+h18) / 18 as avg_score
      ,greatest(h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) as highest
      ,least(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) as lowest
  from scores
 where player_id = 1;

vs.

select avg(score) as avg_score
      ,max(score) as highest
      ,min(score) as lowest
  from scores
 where player_id = 1;

Which hole was my worst? 哪个洞最差?

Scenario 2. 情景2。

select case when h1 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H1'
            when h2 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H2'
            when h3 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H3'
            when h4 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H4'
            when h5 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H5'
            when h6 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H6'
            when h7 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H7'
            when h8 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H8'
            when h9 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18)  then 'H9'
            when h10 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H10'
            when h11 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H11'
            when h12 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H12'
            when h13 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H13'
            when h14 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H14'
            when h15 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H15'
            when h16 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H16'
            when h17 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H17'
            when h18 = greatest(h1,h2,h3,h4,h5,h6,h8,h8,h9,h10,h11,h12,h13,h14,h16,h17,h18) then 'H18'
        end as hole_highest_score      
  from scores
 where player_id = 1;

vs.

select hole, score
  from scores s1
 where player_id = 1
   and score = (select max(score)
                  from scores s2
                 where s2.player_id = s1.player_id)

I would go with scenario 2 any day :) 我会随时使用方案2 :)

Even though the second approach is my preferred one, since the rules of Golf probably won't change very often, the first design could work in this case. 尽管第二种方法是我的首选方法,但由于高尔夫规则可能不会经常改变,因此第一种设计可能适用于这种情况。 The sum column, if you would choose to have one, could be computed with a trigger. 如果您选择使用sum列,则可以使用触发器计算sum列。

However, you would have to handle the situation when you and your friends decide to go a 9-hole or a 36-hole round. 但是,当你和你的朋友决定进入9洞或36洞的比赛时,你必须处理这种情况。 There is also the issue with how to store additional per-hole information, in case there are any. 如果有任何问题,还存在如何存储额外的每洞信息的问题。 A schema with a separate table with a row for each hole played by a player will be much easier to maintain. 具有单独表格的模式将为玩家所玩的每个洞提供一行,这将更容易维护。

As always, the best solution depends on how you are going to use, update and query the data. 与往常一样,最佳解决方案取决于您将如何使用,更新和查询数据。 If your only use case involves displaying total scores and high scores, the first approach could work. 如果您的唯一用例涉及显示总分和高分,则第一种方法可行。

As soon as a use case is to deal with information related to a particular hole, your application code and/or SQL will be harder to write and maintain. 一旦用例处理与特定漏洞相关的信息,您的应用程序代码和/或SQL就会更难编写和维护。 Take for instance getting the average score for a particular hole for all games played. 比如获得所有比赛的特定洞的平均得分。

In any case I would suggest going with the second alternative and store per-hole scores in a separate table. 在任何情况下,我建议使用第二个替代方案并在单独的表中存储每孔分数。 The performance benefits of having all scores in the same table will probably not outweigh the troubles with maintaining it and writing queries towards it. 在同一个表中获得所有分数的性能优势可能不会超过维护它并向其编写查询的麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM