彩票最佳实践设计数据库

时间:2018-11-12 01:18:12

标签: database-design group-by mariadb database-normalization

我正在开始设计一个数据库,以保存彩票研究结果,在我所在的国家/地区,我可以在excel中下载所有结果。

由于excel全部包含在电子表格中,因此我愿意对导入的数据进行一些标准化,我的问题是我的设计是否正确地关注性能,以及如何处理Group By,我不确定,但是我认为我在最后一个方面失败了。

我的最初设计是:

对于结果:

CREATE TABLE `Game_Results` (
    `Id` int UNSIGNED NOT NULL,
    `Date_Game` date NOT NULL,
    `Ball_01` tinyint UNSIGNED NOT NULL,
    `Ball_02` tinyint UNSIGNED NOT NULL,
    `Ball_03` tinyint UNSIGNED NOT NULL,
    `Ball_04` tinyint UNSIGNED NOT NULL,
    `Ball_05` tinyint UNSIGNED NOT NULL,
    `Ball_06` tinyint UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

有关奖励数据:

CREATE TABLE `Game_Prize` (
    `Game_Id` int UNSIGNED NOT NULL,
    `Total_Bets` decimal UNSIGNED NOT NULL,
    `Winners` smallint UNSIGNED NOT NULL DEFAULT '0',
    `Prize_Per_winner` decimal UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

获奖者位置:

CREATE TABLE `Prize_Location` (
    `Game_Id` int UNSIGNED NOT NULL,
    `State_Prize` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
    `City_Prize` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

此设计基于所需的网页,可以这样说:

一个div,最后一个结果,因此查询为:

SELECT `Ball_01`, `Ball_02`, `Ball_03`, `Ball_04`, `Ball_05`, `Ball_06` FROM Game_Results WHERE Id IN (SELECT MAX(Id) FROM Game_Results)

当前ID将在php / Javascript中全局化

同一页面上的另一个div包含奖金信息,因此查询为:

 SELECT `Total_Bets`, `Winners`,  `Prize_Per_winner` FROM Game_Prize Where Game_Id = Id (from php / javascript)

如果该人单击“获胜者”,则将打开一个包含位置数据的模式。

这次我可以在最后一张桌子上进行SELECT并列出,直到这里都没问题。

但是我会尝试构建一些自定义过滤器,然后问题就会出来,我的过滤器会让人们使用这些功能:

  • 什么时候出来的球呢?
  • 按多少时间列出有序球。
  • 更多人赢得选举的州是什么?
  • 在一个特定的城市中有多少人获胜?
  • 等等。

还有重复的问题,可能会将结果导出为PDF或DOCX,我将搜索任何javascript插件以将JSON转换为JSON,这时,我愿意重新制作与原始Excel相同的结构(我知道JOINS),例如:

  

GameID = 55,...,State = A,City = A(1 Person)

     

,...,州A,城市= A(1人)

     

,...,州A,城市= A(1人)

     

GameID = 56,...,State = C,City = H

     

GameID = 57,...,,,,(没有获奖者)

原始Excel都在同一行中处理同一游戏的单元格。在等号(GameID,州,城市等)之前是第一行,在等号之后是botton上的数据,因此GameID像表中的GROUP BY一样在表上处理。

那么,由于有时会有3或6个优胜者,我应该如何处理最后一张表('Prize_Location')?

我的意思是,有时来自同一个城市和州的人们会获胜,在这种情况下如何应对这种情况?

当然,这是设计此数据库的最佳方法吗?

PS .:索引,主键等...选择最佳设计后,我会做的。重点是性能,因为我将在博客上共享这些数据,并允许人们过滤和查询这些数据,换句话说,我不知道有多少人同时使用它。

2 个答案:

答案 0 :(得分:1)

一个选项可能是重新定义Prize_Location表,以允许给定的Game_Id与同一位置多次关联。我建议以下内容:

CREATE TABLE Prize_Location (
    Game_Id int UNSIGNED NOT NULL,
    Location_Id int NOT NULL
)

CREATE TABLE Locations (
    Id int UNSIGNED NOT NULL,
    State_Prize varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
    City_Prize varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
)

现在在Prize_Location中,给定的Game_Id可能会多次与给定的Location_Id关联。这就是您代表一个给定的城市和州碰巧有多个获胜者的方式。您还可以将Game_Id, Location_Id用作主键,而存储一个计数,但这似乎比只允许给定游戏和位置输入多个条目更为麻烦。

答案 1 :(得分:1)

SELECT `Ball_01`, `Ball_02`, `Ball_03`, `Ball_04`, `Ball_05`, `Ball_06`
    FROM Game_Results WHERE Id IN (SELECT MAX(Id) FROM Game_Results)

最好通过这种方式完成:

SELECT `Ball_01`, `Ball_02`, `Ball_03`, `Ball_04`, `Ball_05`, `Ball_06`
    FROM Game_Results  ORDER BY Id DESC  LIMIT 1

请谨慎使用裸露的DECIMAL。考虑对整个数字使用某种形式的INT

球有序吗?

您应该考虑在专用于球的表中有6行,而不是6列。这样可以简化计算球数的统计数据。

我认为没有必要对位置进行规范化。只需将这些放在奖品表中即可:

state CHAR(2)     CHARACTER SET ascii,
city  VARCHAR(40) CHARACTER SET ascii

(不需要255和utf8mb4)。

您仍然可以通过以下方式在一个城市中发现多个获胜者:

SELECT city, state, COUNT(*)
    FROM prizes
    GROUP BY city, state
    HAVING COUNT(*) > 1