我是数据爱好者,并为广为人知的手机游戏创建了可能的物品组合列表。有21.000.000组合(被逻辑过滤掉的无用组合)。

因此,我现在想做的是创建一个网站,人们可以访问该网站以查看他们需要什么才能获得最好的装备,或者他们现在可以使用装备最好地做什么。

我的物品数据库当前如下所示:

CREATE TABLE `items` (
 `ID` int(8) unsigned NOT NULL,
 `Item1` int(2) unsigned NOT NULL,
 `Item2` int(2) unsigned NOT NULL,
 `Item3` int(2) unsigned NOT NULL,
 `Item4` int(2) unsigned NOT NULL,
 `Item5` int(2) unsigned NOT NULL,
 `Item6` int(2) unsigned NOT NULL,
 `Item7` int(2) unsigned NOT NULL,
 `Item8` int(2) unsigned NOT NULL,
 PRIMARY KEY (`ID`)
) ENGINE=InnoDB


ID范围:1-21.000.000

每个项目都以其编号来知道,例如11.第一个数字描述类别,第二个数字描述该类别的项目。例如34表示Item3->4。它的保存方式是这样,因为我也有要使用此编号作为标识(34.png)稍后在网站上显示的图像。

统计数据库现在看起来像这样:

CREATE TABLE stats (
 Stat1 FLOAT UNSIGNED NOT NULL,
 Stat2 FLOAT UNSIGNED NOT NULL,
 Stat3 FLOAT UNSIGNED NOT NULL,
 Stat4 FLOAT UNSIGNED NOT NULL,
 Stat5 FLOAT UNSIGNED NOT NULL,
 Stat6 FLOAT UNSIGNED NOT NULL,
 Stat7 FLOAT UNSIGNED NOT NULL,
 Stat8 FLOAT UNSIGNED NOT NULL,
 ID1 INT UNSIGNED,
 ID2 INT UNSIGNED,
 ID3 INT UNSIGNED,
 ID4 INT UNSIGNED,
 ID5 INT UNSIGNED,
 ID6 INT UNSIGNED,
 ID7 INT UNSIGNED,
 ID8 INT UNSIGNED
) ENGINE = InnoDB;


Stat *代表攻击,防御,健康等内容,而ID *代表项目数据库的ID。有些组合在所有8种可能的统计数据上具有相同的统计数据组合,因此我将它们组合在一起以保存一些条目(如果还算不错的话,不知道)。例如,一个Stat组合可以填充ID1,ID2和ID3,而另一个组合仅包含ID1(我计算得出的最大值是8个ID)。

现在,即时消息显示了一个巨大的表,可以按每个Stat排序,并且工作正常。

我将来想要的是让用户搜索项目或从列表中排除某些项目。我知道我可以通过一些联接和where子句(where items.ID == stats.ID1或items.ID == stats.ID2等)来做到这一点,但是我想知道我当前的结构是否是最聪明的解决方案?我尝试在旧的Pi 2上运行此程序时获得最佳性能。

最佳答案

当您有非常大的数据集而仅具有少量匹配项时,最佳性能通常是在FROMWHERE子句中使用子查询。

SELECT SP.TerritoryID,
       SP.BusinessEntityID,
       SP.Bonus,
       TerritorySummary.AverageBonus
FROM   (SELECT   TerritoryID,
                 AVG(Bonus) AS AverageBonus
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS TerritorySummary
       INNER JOIN
       Sales.SalesPerson AS SP
       ON SP.TerritoryID = TerritorySummary.TerritoryID


Copied from here

这样可以有效地创建仅包含匹配行的虚拟表,然后在虚拟表上运行联接-就像将匹配的行选择到tmp表中,然后在tmp表上联接一样。在整个表上运行联接,尽管您可能会认为不错,但通常会很糟糕。

您可能还会发现在WHERE子句中使用子查询有效

... where items.id in (select id1 from stats union select id2 from stats)


或在stats表中选择匹配的IDs tmp,然后为tmp表建立索引。

这完全取决于您的其他选择逻辑。

听起来您应该在stats表上获得一些索引。如果您不对其进行大量更新,则为每个ID编制索引都可以。只需确保未填写的stats ID的值为NULL

关于mysql - 最佳数据库结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59845597/

10-12 17:07
查看更多