要存储的实体有 25 多个属性(表列)。实体非常多样化,这意味着大多数列都是空的。我想说,平均而言,不到 20% (<5) 的属性在任何特定项目中具有价值。因此,对于大多数表行,我有很多冗余的空列。几乎所有的列都是十进制数。
鉴于这种情况,您是否建议将列序列化,或者创建另一个名为“Property”的表,该表将包含所有可能的属性,然后创建另一个表“EntityProperty”,该表将使用外键将属性映射到实体? 或者你会保持原样吗?
可能发生这种冗余的示例场景如下:
我们有一个虚构的宇宙,里面有很多行星。我们正在创建一个太空采矿游戏,每个星球都有 30 种不同的矿物含量。大多数行星只有2-3种矿物质。
最简单的解决方案是创建一个包含 30 列的“Planets”表,每种矿物一个列。这里的问题是,“Planets”表中的大多数行都有 25 多列,其中每一列的值为空或零。因此我们有很多冗余数据。比如说,我们将有 500k-1M 条记录。我猜想保存一个空或零十进制值最多需要一个字节。因此,我们浪费了 500,000-1,000,000 字节的空间,即。最多一兆字节。
另一种解决方案是创建两个额外的表。我们没有将所有矿物质存储在“行星”表中,而是将它们全部取出并创建一个名为“矿物质”的矿物质表。这将仅包含 30 行,每行用于每种不同的矿物类型。然后,我们创建一个名为“PlanetMineral”的表,其中包含对行星行和矿物行的引用,此外,该表还有一列说明行星所含矿物的数量。显然,在许多数据库系统中,这会使查询复杂化,因为您必须进行可能的多个连接。我正在使用带有 LINQ to SQL 的 SQL 服务器,它将外键约束搭建到类对象属性中,可通过代码访问。(即。我可以简单地使用planet.Minerals 访问行星所拥有的矿物质)所以,从这个角度来看,它没有 t 增加复杂性。冗余是第一个解决方案的一小部分(如 1/15)。仍然存在一些开销的原因是因为我们需要存储外键。
至于数据查询效率,我真的不知道这两种解决方案的查询成本会如何。