彩票最佳实践设计数据库
Database for Lottery Best Practice Design
我开始设计一个数据库来保存彩票结果以供研究,在我的国家我可以下载 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)
如果此人单击“获胜者”,则会打开一个包含位置数据的模式。
这次我可以在最后一个 table 上做一个 SELECT 并列出,到这里没问题。
但我会尝试构建一些自定义过滤器,然后问题就出来了,我的过滤器会让人们使用这些功能:
- 微尘出现的球是什么?
- 按出现的次数列出有序的球。
- 哪个州赢的人多?
- 有多少人在一个特定城市中获胜?
- 等等
以及可能将结果导出为 PDF 或 DOCX 的重复问题,我将搜索任何 javascript 插件以在这些插件上转换 JSON,在这一点上,我愿意重新制作与原始 Excel 相同的结构(我知道 JOINS),例如:
GameID = 55, ... , State = A, City = A (1 Person)
, ... , State A, City = A (1 Person)
, ... , State A, City = A (1 Person)
GameID = 56, ... , State = C, City = H
GameID = 57, ... , , , (No Winners)
原来的Excel在同一个游戏的单元格中都在同一条线上。等号前(GameID、State、City等)是列的第一行,等号后是botton上的数据,所以GameID在table上很杂乱,像GROUP BY.
那么,最后的table('Prize_Location')有时会有3或6个获胜者,我该如何处理?
我的意思是,有时来自同一城市和州的人会获胜,在这种情况下如何处理这种情况?
当然,这是设计此数据库的最佳方式吗?
PS.: Index, Primary Keys, etc...我会在选择一个最优设计后做。重点是性能,因为我会在我的博客上分享这些数据,并允许人们过滤和查询这些数据,换句话说,我不知道有多少人应该同时使用它。
一个选项可能是重新定义 Prize_Location
table 以允许给定的 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
作为主键,而不是存储计数,但这似乎比只允许对给定游戏和位置进行多个输入更麻烦。
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
。
球有没有订?
您应该考虑在 table 中有 6 行专用于球,而不是 6 列。这将简化计算球数的统计数据。
我认为没有太多必要对位置进行规范化。只要有这些在奖品中 table:
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
我开始设计一个数据库来保存彩票结果以供研究,在我的国家我可以下载 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)
如果此人单击“获胜者”,则会打开一个包含位置数据的模式。
这次我可以在最后一个 table 上做一个 SELECT 并列出,到这里没问题。
但我会尝试构建一些自定义过滤器,然后问题就出来了,我的过滤器会让人们使用这些功能:
- 微尘出现的球是什么?
- 按出现的次数列出有序的球。
- 哪个州赢的人多?
- 有多少人在一个特定城市中获胜?
- 等等
以及可能将结果导出为 PDF 或 DOCX 的重复问题,我将搜索任何 javascript 插件以在这些插件上转换 JSON,在这一点上,我愿意重新制作与原始 Excel 相同的结构(我知道 JOINS),例如:
GameID = 55, ... , State = A, City = A (1 Person)
, ... , State A, City = A (1 Person)
, ... , State A, City = A (1 Person)
GameID = 56, ... , State = C, City = H
GameID = 57, ... , , , (No Winners)
原来的Excel在同一个游戏的单元格中都在同一条线上。等号前(GameID、State、City等)是列的第一行,等号后是botton上的数据,所以GameID在table上很杂乱,像GROUP BY.
那么,最后的table('Prize_Location')有时会有3或6个获胜者,我该如何处理?
我的意思是,有时来自同一城市和州的人会获胜,在这种情况下如何处理这种情况?
当然,这是设计此数据库的最佳方式吗?
PS.: Index, Primary Keys, etc...我会在选择一个最优设计后做。重点是性能,因为我会在我的博客上分享这些数据,并允许人们过滤和查询这些数据,换句话说,我不知道有多少人应该同时使用它。
一个选项可能是重新定义 Prize_Location
table 以允许给定的 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
作为主键,而不是存储计数,但这似乎比只允许对给定游戏和位置进行多个输入更麻烦。
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
。
球有没有订?
您应该考虑在 table 中有 6 行专用于球,而不是 6 列。这将简化计算球数的统计数据。
我认为没有太多必要对位置进行规范化。只要有这些在奖品中 table:
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