2

我一直在对这个问题进行一些研究,但仍然无法做出令人满意的决定。

这个问题最接近,但仍然没有真正帮助我的情况。 MySQL 数据库中的大量列

我基本上是在创建一个“谁会在战斗中获胜”的网站,以解决长期存在的蝙蝠侠与超人风格的争论,用户可以在其中投票决定他们认为谁会赢。

用户可以选择向网站提交“战斗机”,然后将随机匹配到其他所有战斗机,供未来用户投票。

我显然想保留所有比赛的统计数据以显示给用户。

现在我将有一个名为让我们说 FIGHTERS 的表。这将存储主键、名称、描述等信息,但不存储战斗结果。

至于存储战斗结果,我可以看到两个选项。

选项 A:为每个战士创建一个表格,计算他们与其他所有战士主键的获胜票数。

选项 B:创建一个大型投票表,该表将具有由战斗机的主键索引的相同数量的列和行。然后例如要获取战斗机 1 与 战斗机 4 的统计数据,我将查询第 1 行(战斗机 1 PK1)第 4 列(用于战斗机 4 PK4)以获取战斗机 1 胜与战斗机 4 的数量,然后重复但查询第 4 行(PK4 为战斗机 4),第 1 列获得战斗机 4 胜对 战斗机 1。当添加数百(数千?)战斗机时,这张桌子显然会变得非常大。

(希望这不会太混乱!)

所以我想我的问题是,拥有数百个小表是否更好(添加新战斗机时都需要添加列和行)。还是要一张大桌子?

我完全是 50/50,所以请任何建议或其他方式我可以实现这一点将不胜感激。

提前致谢。

编辑:很抱歉留下了这个。我想到的投票基本上可以作为对每个战士的总票数的计数,以支持赢得与其他战士的战斗。

4

2 回答 2

5

在澄清之后,我会考虑

CREATE TABLE FightResults
(
Fighter1Id INT REFERENCES FIGHTERS(FighterId),
Fighter2Id INT REFERENCES FIGHTERS(FighterId),
Fighter1Votes INT,
Fighter2Votes INT,
CHECK (Fighter1Id < Fighter2Id ),
PRIMARY KEY (Fighter1Id,Fighter2Id)    
)

每场比赛都有一排。Gorilla vs Shark、Lion vs Tiger 等。check 和 PK 约束确保相同的比赛不会出现多次。

这确实假设战斗将有两个固定数量的参与者。如果不是这种情况,那么更灵活的模式是

CREATE TABLE Fight
(
FightId INT PRIMARY KEY,
/*Other columns with fight metadata*/
)

CREATE TABLE FightResult
(
FightId INT REFERENCES Fight(FightId),
FighterId INT REFERENCES FIGHTERS(FighterId),
Votes INT,
PRIMARY KEY (FightId,FighterId)
)

但这确实为您的查询增加了很可能不必要的复杂性。

您可能还希望防止同一用户对同一比赛进行多次投票。在这种情况下,您可能会使用类似的东西(假设每场比赛再次有两名战士)

CREATE TABLE Fights
(
FightId INT PRIMARY KEY,
Fighter1Id INT REFERENCES FIGHTERS(FighterId),
Fighter2Id INT REFERENCES FIGHTERS(FighterId),
CHECK (Fighter1Id < Fighter2Id )   
)    

CREATE TABLE Votes
(
FightId INT REFERENCES Fights(FightId),
UserId INT REFERENCES Users(UserId),
Vote INT CHECK (Vote IN (1,2)),
PRIMARY KEY (FightId,UserId)   
)      

但出于性能原因,可能会保留非规范化的投票总数。

于 2013-10-26T22:48:51.973 回答
3

解决方案是创建2个表:

  1. 具有 FighterId(主键)和所有其他数据的战斗机。

  2. FightResult:FightResultId(主键),FighterId1,FighterId2,FightResult。两列 FighterIdX 是 Fighter 的外键。

这将使查询和添加投票变得容易,并使其简单易懂。

如果您愿意,您还可以将诸如哪个用户投票给战斗(用户的外键)之类的信息添加到第二个表中。

于 2013-10-26T22:49:22.287 回答