我正在设计一个数据库来存储我所有的朋友和我的高尔夫比分。您可能知道,高尔夫球得分由18洞个人得分组成。我可以想到两种设计模式的方法:
创建一个每个孔有一列的表(例如h1到h18),该表有FK player_id,round_id和引用其他表的course_id。它有一个总列,它是列h1到h18的总和。如果我更改了一个得分,我将需要手动更新总列数。
创建一个包含孔得分列,孔索引列,player_id列,course_id和round_id的表。要获得一轮的总分,我需要在round_id,player_id上进行SUM查询。
目前,数据库可能会存储少于20人的分数,因此任何一种方法都应该没问题。但是,如果我想为20,000人存储分数,哪种方法更具可扩展性呢?
我正在使用MySQL 5,PHP5。感谢。
更新>查询示例: 1.阅读所有玩家的9/18分数,然后建立一个记分卡。 2.基本统计数据,例如查找最后X轮的玩家的最低/平均/最高总得分。 3.更高级的统计数据,比如最后X轮的任何球洞的平均得分。
答案 0 :(得分:4)
我的平均分,最高分和最低分是多少?
情景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;
哪个洞最差?
情景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)
我会随时使用方案2:)
答案 1 :(得分:2)
尽管第二种方法是我的首选方法,但由于高尔夫规则可能不会经常改变,所以第一种设计可能适用于这种情况。 sum列,如果你选择有一个,可以用触发器计算。
然而,当你和你的朋友决定进入9洞或36洞的比赛时,你必须处理这种情况。如果有任何问题,还存在如何存储额外的每洞信息的问题。具有单独表格的模式将为玩家所玩的每个洞提供一行,这将更容易维护。
与往常一样,最佳解决方案取决于您将如何使用,更新和查询数据。如果您的唯一用例涉及显示总分和高分,则第一种方法可行。
只要用例处理与特定漏洞相关的信息,您的应用程序代码和/或SQL将更难编写和维护。比如获得所有比赛中特定球洞的平均得分。
在任何情况下,我都建议使用第二个替代方案并在单独的表中存储每洞分数。在同一个表中获得所有分数的性能优势可能不会超过维护它并向其编写查询的麻烦。