最佳数据库结构

时间:2020-01-21 16:41:00

标签: mysql database database-design mariadb bigdata

我是数据爱好者,并为广为人知的手机游戏创建了可能的物品组合列表。有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上运行此程序时,尝试获得最佳性能。

1 个答案:

答案 0 :(得分:1)

当您有非常大的数据集而匹配项很少时,最好的性能通常是在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