我正在开始设计一个数据库,以保存彩票研究结果,在我所在的国家/地区,我可以在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 .:索引,主键等...选择最佳设计后,我会做的。重点是性能,因为我将在博客上共享这些数据,并允许人们过滤和查询这些数据,换句话说,我不知道有多少人同时使用它。
答案 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