我是一个非常有经验的程序员,但是对SQL来说是个新手,它对事物的看法比代码中的观点更为有限。我认为一般来说我可能在SQL上下文中看到这个错误,所以我正在寻找方向。我不认为特定的SQL实现在这一点上确实不重要。我认为这只是我遇到的一般SQL概念问题。
这就是我的想法:
假设我要跟踪大量体育赛事的结果(上千万个或更多),其中包括参加比赛的队伍和最终得分:
CREATE TABLE teams (
TeamID INT NOT NULL PRIMARY KEY,
TeamName VCHAR(255) NOT NULL
)
CREATE TABLE games (
GameID INT NOT NULL PRIMARY KEY,
TeamA INT NOT NULL,
TeamB INT NOT NULL,
TeamAScore INT,
TeamBScore INT,
FOREIGN KEY TeamA(TeamID)
REFERENCES teams (TeamID),
FOREIGN KEY TeamB(TeamID)
REFERENCES teams (TeamID)
)
由于“游戏”表将非常大,因此当查询特定团队的结果时,在我看来,同时搜索“ TeamA”和“ TeamB”列以进行匹配可能会非常耗时-消耗操作。反过来,这将使在UI上立即呈现成为问题。
但是,如果有每个团队玩的游戏列表,则查询可以更快(以增加存储量为代价):
CREATE TABLE team_TeamID_games (
GameID INT NOT NULL,
FOREIGN KEY GameID(GameID)
)
然后显示团队的结果列表仅涉及使用“ team_TeamID_games”表并直接提取“ games”表的结果,而不是对其进行搜索。
这里有问题的部分始于为每个团队引入新表格的想法。上面“ team_TeamID_games”的“ TeamID”部分将替换为团队ID,因此可能会有名为“ team_1_games”,“ team_2_games”等的表。
仅此一项就与我在研究SQL使用中所见所见相悖。
此外,根据到目前为止我对SQL的了解,实际上没有标准的方法将“ team_TeamID_games”表实际链接到“ teams”表的“ TeamID”行,因为外键引用了行,而不是整个表格。这意味着数据库并不真正知道连接。
或者,可以将另一个表名的VARCHAR()字符串存储在“团队”表中,但是我也不认为这实际上对数据库有任何意义。
答案 0 :(得分:1)
不确定您认为“非常”大的内容。与例如如果有2500支球队,则结果游戏桌数约为600万行。如今,这甚至不算是“大笔钱”。如果有5000支队伍,游戏桌将有2500万行。如今仍不是“极端”大型。
可以使用以下查询回答“查找特定团队的所有比赛”查询:
select *
from games
where teama = 42
or teamb = 42;
(通常)可以通过在每列上创建一个索引来改进:
create index idx_team_a on games (teama);
create index idx_team_a on games (teamb);
Postgres(可能还有其他DBMS产品)也可以将两个索引用于该查询。在我的笔记本电脑(拥有2500个团队和620万个游戏)上,查询大约需要3 milliseconds。
另一种选择是在涵盖两个团队ID的表达式上创建索引
create index on games ( (least(teama, teamb)) );
该表达式随后可用于查找一个团队的所有比赛:
select *
from games
where least(teama, teamb) = 1234;
a bit faster仅涉及一个索引:在我的笔记本电脑上大约2毫秒。
在2500万行(5000个团队)中,两种方法之间的差异要大一些。 OR
查询大约需要15-20毫秒,基于表达式的查询大约需要5-10毫秒。
即使20毫秒似乎也不是UI中的问题。
因此,通过仔细的索引编制,我看不到为什么您需要任何其他表。