【问题标题】:Database storage design of large amounts of heterogeneous data海量异构数据的数据库存储设计
【发布时间】:2013-02-16 08:36:31
【问题描述】:

这是我很长一段时间以来一直想知道的事情,但还没有看到真正的(好的)解决方案。这是我想象很多游戏都会遇到的问题,而且我无法轻易想到如何解决(好吧)。欢迎提出想法,但由于这不是一个具体的问题,所以不要费心询问更多细节 - 只是弥补它们! (并解释你的编造)。

好吧,所以,许多游戏都有(库存)物品的概念,而且通常有数百种不同种类的物品,所有物品的数据结构通常都非常不同 - 有些物品非常简单(“一块石头”),其他人可能有疯​​狂的复杂性或背后的数据(“一本书”、“一个编程的计算机芯片”、“一个装有更多物品的容器”)等等。

现在,这样的编程很容易——只要让所有东西都实现一个接口,或者扩展一个抽象的根项。由于编程世界中的对象不必在内部和外部看起来相同,因此任何类型的项目具有多少和什么样的私有字段确实没有问题。

但是当涉及到数据库序列化(二进制序列化当然没问题)时,您将面临一个难题:您将如何在典型的 SQL 数据库中表示它?

我所看到的解决方案的一些尝试,但没有一个令我满意:

  1. 项目的二进制序列化,数据库只保存一个ID和一个blob。

    • 专业版:实施大约需要 10 秒。
    • 缺点:基本上牺牲了所有数据库功能,难以维护,几乎不可能重构。
  2. 每个项目类型一个表。

    • 专业人士:干净、灵活。
    • 缺点:由于 SQL 没有表/类型“引用”的概念,因此有数百个表种类繁多,每次搜索项目都必须查询它们。
  3. 一个表有很多字段,并不是每个项目都使用。

    • 专业版:实施大约需要 10 秒,仍然可以搜索。
    • 缺点:浪费空间、性能、让数据库混淆以判断正在使用的字段。
  4. 一些带有一些“基本配置文件”的表格用于存储,相似的项目被放在一起并使用相同的字段来存储不同的数据。

    • 专业人士:我什么都没有。
    • 缺点:浪费空间、性能、让数据库混淆以判断正在使用的字段。

你有什么想法?您是否见过另一种效果更好或更差的设计?

【问题讨论】:

  • 听起来你想要一个 [Entity-Attribute-Value][1] 模式。 [1]:stackoverflow.com/questions/4705860/…
  • 数据库表中的建模继承已被本网站上的许多帖子所涵盖。我在这篇文章中没有看到的一个选项是:每个类一个表(包括基类)。对于每个对象,在对象的类层次结构的每个表中都放置一条记录。每个表只包含该类实现的新字段。要获取对象的所有字段,请连接其继承层次结构的所有表。

标签: database database-design data-structures


【解决方案1】:

这取决于您是否需要对这些属性进行排序、过滤、计数或分析。

如果你使用 EAV,那么你会很好地搞砸自己。尝试对 EAV 架构进行报告。

最好的选择是使用表继承:

PRODUCT
id pk
type
att1

PRODUCT_X
id pk fk PRODUCT
att2
att3

PRODUCT_Y
id pk fk PRODUCT
att4
att 5

对于不需要搜索/排序/分析的属性,请使用 blob 或 xml

【讨论】:

    【解决方案2】:

    我有两种选择:

    1. 一个表用于基本类型,每个“类”专用类型的补充表。

      在此模式中,所有“对象”共有的属性都存储在一个表中,因此您对游戏中的每个对象都有唯一的记录。对于书籍、容器、可用物品等特殊类型,您可以为这些物品所需的每组独特的属性或关系提供另一个表。因此,每个特殊类型将由两条记录表示:基础对象记录和特定特殊类型表中的补充记录。

      优点:您可以使用数据库的基于列的功能,例如自定义域、检查和 xml 处理;您可以在某些类型上使用更简单的触发器;您的查询在不同的关注点上完全不同。

      缺点:许多对象需要两次插入。

    2. 对特殊类型数据使用“kind”枚举字段和类似 JSONB 的字段。

      这有点像你的 #1 或 #3,除了一些数据库帮助。 Postgres 添加了 JSONB,为您提供了对旧 EAV 模式的改进。其他数据库也有类似的复杂字段类型。在此策略中,您滚动存储在 JSONB 字段中的自己的迷你模式。 kind 字段声明了您希望在该 JSONB 字段中找到的内容。

      优点:您可以在查询中提取特殊类型的数据;可以添加检查约束并有一个简单的模式来处理;即使您的数据是异构的,您也可以从索引中受益;您的查询和插入很简单。

      缺点:您在类似 JSONB 的字段中的数据类型非常有限,您必须自行验证。

    【讨论】:

    • 同意 - 用于可搜索字段的强架构字段和用于不重要的专业字段的弱 achema(json、xml 或只是 blob)的混合体。
    【解决方案3】:

    是的,设计这样的数据库格式很痛苦。我正在设计一个通知系统并遇到了同样的问题。然而,我的通知系统没有你的那么复杂——它保存的数据最多是 id 和用户名。我目前的解决方案是 1 和 3 的混合 - 我序列化与每个通知不同的数据,并为 2 个用户名使用一列(有些可能有 2 或 1)。我回避方法 2,因为我讨厌这种设计,但可能只有我一个人。

    但是,如果您负担得起,我建议您在 RDBMS 领域之外思考 - 听起来非 RDBMS(尤其是键/值存储)可能更适合存储这些数据,特别是如果第 1 项和项目 2 与每个项目有很大不同。

    【讨论】:

      【解决方案4】:

      我敢肯定这已经被问过一百万次了,但是除了您在问题中讨论的选项之外,您还可以查看非常灵活的 EAV 架构,但它有自己的缺点.

      另一种选择是非关系型数据库系统。有对象数据库以及各种键/值存储和文档数据库。

      当您需要查询灵活属性时,通常所有这些事情都会在某种程度上分解。然而,这是一个内在的问题。从概念上讲,准确查询非结构化事物的真正含义是什么?

      【讨论】:

        【解决方案5】:

        首先,您真的需要真实数据库的并发性、可扩展性和 ACID 事务吗?除非您正在构建 MMO,否则您的游戏结构无论如何都可能适合内存,因此您可以直接在那里搜索和操作它们。在这种情况下,“数据库”只是序列化对象的存储,您可以将其替换为文件系统。


        如果您得出结论(需要数据库),那么关键是要弄清楚"atomicity" 的含义是什么从数据管理的角度

        例如,如果一个游戏项目有一堆属性,但这些属性都不是在数据库级别单独操作的(即使它们很可能在应用程序级别),那么它可以被认为是“原子的”从数据管理的角度。 OTOH,如果需要在其中一些属性上搜索项目,那么您需要一种在数据库中索引它们的好方法,这通常意味着它们必须是单独的字段。

        一旦从数据库的角度确定了应该“可见”的属性与应该“不可见”的属性,将后者序列化为 BLOB(或其他),然后忘记它们并专注于构建前者。

        这就是乐趣的开始,您可能需要使用“以上所有”策略才能获得合理的结果。

        顺便说一句,一些数据库支持可以进入异构数据结构的“深度”索引。例如,看看 Oracle 的 XMLIndex,虽然我怀疑你会在游戏中使用 Oracle。

        【讨论】:

          【解决方案6】:

          您似乎正在尝试针对游戏环境解决此问题,因此也许您可以考虑一种基于组件的方法。 我不得不说我个人还没有尝试过,但我已经研究了一段时间,在我看来可以应用类似的东西。

          您的游戏中的所有实体基本上都是一袋组件。例如,这些组件可以是 PositionEnergy 或用于您的库存案例的 Collectable。然后,对于这个Collectable 组件,您可以添加自定义字段,例如类别、numItems 等。

          当您要呈现库存时,您可以简单地在实体系统中查询具有Collectable 组件的物品。

          如何将其保存到数据库中?您可以在它们自己的表中独立定义组件,然后为实体(每个实体也在它们自己的表中)添加一个“组件”列,该列将包含引用这些组件的 ID 数组。这些 ID 实际上就像外键一样,尽管我知道这并不是您在关系数据库中建模事物的确切方式,但您明白了。

          然后,当您在运行时加载实体及其组件时,您可以根据正在加载的组件在其组件包中设置相应的标志,以便您知道该实体具有哪些组件,然后它们将变得可查询.

          Here 是一本关于基于组件的实体系统的有趣读物。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-17
            • 1970-01-01
            • 2012-10-05
            • 1970-01-01
            • 1970-01-01
            • 2012-01-25
            • 1970-01-01
            • 2017-06-15
            相关资源
            最近更新 更多