MySQL中的字段太多?

MySQL中的字段太多?,mysql,database-design,Mysql,Database Design,几年前,我为一个游戏开发了一个统计网站,作为一个学习项目。它今天还在用,我想把它清理一下 数据库是一个需要改进的领域。我有一个游戏统计表,其中有GameID、PlayerID、死亡、伤害处理、伤害采取等。总的来说,这个表中大约有50个字段,将来还可以添加更多字段。什么时候字段过多?它目前有57341行,本身是153.6 MiB 我还有几个字段将数组存储在同一个表中的BLOB中。玩家对玩家的比赛就是一个例子。该数组存储该玩家在游戏中杀死另一玩家的次数。这些是文件大小中较大的字段。是否建议在BLOB

几年前,我为一个游戏开发了一个统计网站,作为一个学习项目。它今天还在用,我想把它清理一下

数据库是一个需要改进的领域。我有一个游戏统计表,其中有GameID、PlayerID、死亡、伤害处理、伤害采取等。总的来说,这个表中大约有50个字段,将来还可以添加更多字段。什么时候字段过多?它目前有57341行,本身是153.6 MiB

我还有几个字段将数组存储在同一个表中的BLOB中。玩家对玩家的比赛就是一个例子。该数组存储该玩家在游戏中杀死另一玩家的次数。这些是文件大小中较大的字段。是否建议在BLOB中存储阵列

该数组看起来像:

        [Killed] => Array
            (
                [SomeDude] => 13
                [GameGuy] => 10
                [AnotherPlayer] => 8
                [YetAnother] => 7
                [BestPlayer] => 3
                [APlayer] => 9
                [WorstPlayer] => 2
            )

这些玩家一般不会超过10人。

桌子的设计似乎基本上很好。只要存储的列不能从同一行中的其他列计算。例如,您没有存储自杀倾向、其他死亡倾向和总体死亡倾向(其中总体死亡倾向=自杀倾向+其他死亡倾向)。那没有道理,可能会被从你的桌子上剪下来

我很想了解更多关于如何在BLOB中存储这些数组的信息——它们在BLOB中的用途是什么?为什么不将它们规范化为一个表,以便于数据转换和分析?(或者,它们只是作为数组存储在这里,以便向最终用户显示数据)


此外,我还想知道,相对于表中的其他部分,您的BLOB占用了多少数据。一般来说,行的大小并不像行的数量那么重要,而且~60K根本不是什么大问题。只要您不编写需要检查每个列值的查询(理想情况下,您在尝试编写where子句时忽略BLOB)。

我不希望有一个列数不确定的表(还有更多列),而是希望有一个标签和值的关联表,因此,每个用户都有一个id,您可以使用该id作为标签和值表的键。这样,您只存储每个用户所需的数据。我相信这种方法被称为EAV(根据Triztian的评论),这就是医学数据库的保存方式,因为每个患者都有很多潜在的字段,即使任何给定的患者只有非常少的带有实际数据的字段

那么,你应该

user:
id | username | some_other_required_field

user_data:
id | user_id | label | value
现在,您可以根据每个用户的需要拥有任意多或任意少的用户_数据行

[编辑]

至于你的数组,我也会用关系表来处理。比如:

player_interraction:
id | player_id | player_id | interraction_type

在这里,您可以存储有交互的两个玩家以及交互的类型。

使用mysql,您可以获得大约4000列(字段)的硬限制和每行65Kb的总存储空间。如果需要存储大字符串,请使用文本字段,它们存储在磁盘上。blob确实应该为非文本数据保留(如果必须的话)

一般来说,不要担心数据库的大小,但要考虑它的结构以及它的组织和索引方式。我见过小分贝跑得很烂


如果您仍然需要数字,当您的总DB在GB范围内或超过单个表中的几十万行时,那么就开始担心更多的事情——60K行中的150M并不多,表扫描也不会在性能上花费太多。但是,现在是时候确保在大量使用的查询上创建良好的覆盖索引了

随着时间的推移,向数据库表中添加列并没有什么错。数据库设计一直在变化。要记住的是数据是如何分组的。我一直将数据库表视为相似项的集合

我认为如下:

将数据插入行时,有多少列将为空?
此新列是否适用于我已有的80%数据?
我会对该表中的几列进行几次更新吗?
如果是这样的话,我是否需要跟踪previos值,以防万一


考虑到这样的数据,您可能会发现您需要将表拆分为几个单独的较小表,这些表通过外键链接在一起。

它被称为EAV或。作为统计数据的汇总表,我认为假设没有动态的“更多”是可以的,而且他将来想添加的栏目数量有限。此外,我认为每个玩家都会使用每一列。因此,可能不需要EAV的所有灵活性——尽管我同意EAV在这种情况下很容易工作。EAV通常也是性能杀手,它使查询变得更加困难。只有在不能预先定义列的情况下才应该使用它。我认为EAV对这个数据库没有好处。我同意数组是它们自己的表,这是我可能首先要做的。我不同意这个观点。如果您有一对一的关系,为什么要分成多个表?有一点是肯定的:将数据分隔成的表越多,服务器端代码就越复杂。“这没有意义,可能会从表中删除。”这不一定是真的。如果您通过
TotalDeaths
进行了大量查询,那么在表中存储计算版本是有意义的,这样您就不必每次运行查询时都在所有57000行上运行计算。您完全正确。我有两个不同的想法,“信息存储”是其中之一,然后我开始“查询大行”,甚至没有把它们放在一起考虑。