Database 海量异构数据的数据库存储设计

Database 海量异构数据的数据库存储设计,database,database-design,data-structures,Database,Database Design,Data Structures,这是我想了很长一段时间,但还没有看到一个真正的(好的)解决方案。这是一个我认为很多游戏都会遇到的问题,我很难想到如何解决这个问题。想法是受欢迎的,但因为这不是一个具体的问题,所以不要费心问更多的细节——只是虚构出来!(并解释你编造的内容) 好的,所以,很多游戏都有(库存)物品的概念,通常有数百种不同的物品,所有物品的数据结构都非常不同——有些物品非常简单(“一块石头”),其他物品背后可能有疯狂的复杂性或数据(“一本书”、“一个编程的计算机芯片”、“一个装有更多物品的容器”)等等 现在,编程这样的

这是我想了很长一段时间,但还没有看到一个真正的(好的)解决方案。这是一个我认为很多游戏都会遇到的问题,我很难想到如何解决这个问题。想法是受欢迎的,但因为这不是一个具体的问题,所以不要费心问更多的细节——只是虚构出来!(并解释你编造的内容)

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

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

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

我见过一些解决方案的尝试,但没有一个让我满意:

  • 对于项的二进制序列化,数据库只保存一个ID和一个blob

    • 专业版:大约需要10秒来实现
    • 缺点:基本上牺牲了所有难以维护、几乎不可能重构的数据库特性
  • 每个项目类型的表

    • 专业:干净、灵活
    • 缺点:由于SQL没有表/类型“reference”的概念,所以有数百个表,每次搜索一个项都必须全部查询它们
  • 一个表包含许多字段,但不是每个项都使用这些字段

    • 专业版:大约需要10秒来实现,仍然可以搜索
    • 缺点:浪费空间,性能,从数据库中判断哪些字段在使用时会产生混乱
  • 一些表包含一些用于存储的“基本配置文件”,在这些表中,相似的项聚集在一起,并对不同的数据使用相同的字段

    • 职业选手:我什么都没有
    • 缺点:浪费空间,性能,从数据库中判断哪些字段在使用时会产生混乱

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

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


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

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

    如果您使用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,我相信这在这里已经被问过无数次了,但是除了您在问题中讨论的选项之外,您可以看看EAV模式,它非常灵活,但有自己的缺点

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


    通常,当您需要查询灵活的属性时,所有这些功能都会在一定程度上崩溃。然而,这是一种内在的问题。从概念上讲,准确地查询非结构化的内容到底意味着什么?

    首先,您真的需要真实数据库的并发性、可伸缩性和ACID事务吗?除非你正在构建一个MMO,否则你的游戏结构很可能会放在内存中,所以你可以直接在内存中搜索和操作它们。在这样的场景中,“数据库”只是序列化对象的存储,您可以用文件系统替换它


    如果您认为您确实需要(需要一个数据库),那么关键在于从数据管理的角度找出的含义

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

    一旦从数据库的角度确定了应该是“可见”的属性和应该是“不可见”的属性,将后者序列化为blob(或其他什么),然后忘掉它们,集中精力构建前者

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


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

    你似乎试图为游戏上下文解决这个问题,所以也许你可以考虑一个<强>基于组件的< /强>方法。 我得说我个人还没试过,