Dynamic Database Schema为动态逻辑数据库架构提供存储的推荐体系结构是什么? 需要说明的是:在要求系统为模型提供存储的情况下,其模型可能会在生产后由其用户扩展或更改,那么哪些好的技术,数据库模型或存储引擎将允许这样做? 一些可能性来说明:
任何基于现实世界经验的答案将不胜感激 您的建议并不新鲜。很多人都尝试过……大多数人发现他们追求"无限"的灵活性,而最终获得的收益却远不止于此。这是数据库设计的"蟑螂汽车旅馆"-数据可以输入,但几乎不可能将其导出。尝试并针对任何类型的约束对代码进行概念化编写,您将明白我的意思。 最终结果通常是一个更难以调试,维护和充满数据一致性问题的系统。情况并非总是如此,但通常情况是这样的。主要是因为程序员看不到火车残骸的到来,并且无法防御性地针对它进行编码。而且,通常最终会出现这样的情况:"无限"的灵活性实际上不是必需的。当开发团队得到一个说明说"天哪,我不知道他们要把什么样的数据放在这里,所以让它们放到哪里"时,这是一个非常糟糕的"气味"……而最终用户也很好具有可以使用的预定义属性类型(编写通用电话号码,并让他们创建其中任何一个,这在一个很好的标准化系统中并不重要,并且可以保持灵活性和完整性!) 如果您有一支非常优秀的开发团队,并且充分意识到使用此设计必须克服的问题,那么您可以成功编写出设计良好,而不是令人毛骨悚然的系统的代码。大多数时候。 但是,为什么为什么要从与您对立的赔率开始呢?
不相信我吗Google"一个真实的查询表"或"单个表设计"。一些好的结果: http://thedailywtf.com/Comments/Tom_Kyte_on_The_Ultimate_Extensibility.aspx?pg=3 http://www.dbazine.com/ofinterest/oi-articles/celko22 http://thedailywtf.com/Comments/The_Inner-Platform_Effect.aspx?pg=2 MSSQL中的强类型xml字段对我们有用。 就像其他人所说的那样,除非您别无选择,否则不要这样做。要求这样做的一种情况是,您要销售必须允许用户记录自定义数据的现成产品。我公司的产品属于这一类。
如果确实需要允许您的客户这样做,这里有一些提示: 如果您可以成功完成这些操作(尤其是第一个操作),那么您提到的任何体系结构都将起作用。我的首选是动态更改数据库对象,因为当您访问存储在自定义字段中的数据时,这使您可以利用DBMS的查询功能。其他三个选项要求您加载大量数据,然后在代码中执行大部分数据处理。 我有类似的要求,因此决定使用无模式的MongoDB。
强调:
Lowdarks(您需要了解的东西,因此您可以正确使用mongo):
我在一个真实的项目中做到了: 该数据库由一个表和一个字段组成,其中一个字段由50个数组组成。该字段上设置了"单词"索引。所有数据都是无类型的,因此"单词索引"按预期工作。数字字段用字符表示,实际排序已在客户端完成。 (如果需要,每种数据类型仍然可以具有多个数组字段)。 逻辑表的逻辑数据模式保存在同一数据库中,但表行"类型"不同(第一个数组元素)。它还支持使用相同的"类型"字段以写时复制样式进行的简单版本控制。 好处: 缺点: 现在我在想下一步可??能是-在文件系统级别上实现这样的数据库。那可能比较容易。 建立关系数据库的全部目的是保持数据安全和一致。从允许用户更改架构的那一刻起,您的数据完整性便随之而来...
既然是2016年,那就不用XML了!使用JSON来存储非关系数据包,并使用适当类型的列作为后端。通常,您不需要在包中按值查询,这会很慢,即使许多现代SQL数据库本机都可以理解JSON。 我知道问题中指出的模型已在整个生产系统中使用。我供职的大型大学/教学机构正在使用一个相当大的应用程序。他们专门使用狭长表方法来映射由许多不同的数据采集系统收集的数据。 此外,Google最近通过其代码站点发布了其内部数据共享协议(协议缓冲区)作为开源。以这种方法为模型的数据库系统将非常有趣。 检查以下内容: 实体-属性-价值模型 Google协议缓冲区 在我看来,您真正想要的是某种"元模式",这是一种数据库模式,能够描述用于存储实际数据的灵活模式。动态模式更改是敏感的,不是您想惹的麻烦,尤其是在允许用户进行更改的情况下。 您不会找到比其他任何数据库更适合此任务的数据库,因此,最好的选择就是根据其他条件选择一个。例如,您使用什么平台托管数据库?应用程序用什么语言编写?等等 为了澄清我的意思是"元模式":
这是一个非常简单的示例,您可能会根据自己的需求找到一些更具体的东西(希望可以更轻松地使用它),但这确实可以说明我的观点。您应该认为数据库模式本身在应用程序级别是不可变的。任何结构上的更改都应反映在数据中(即该架构的实例化)。 创建2个数据库
我相信EAV方法是最好的方法,但是成本很高
我知道这是一个古老的话题,但是我想它永远不会失去现实性。 这是一个简单的实施指南,您可以据此进一步发展。 您将需要实现自己的查询语言解释器,因为有效的SQL太复杂了。 例:
物理数据库布局: 表"规格" :(应缓存在数据访问层中)
表"项目":
表" specs"的内容:
表" items"的内容:
用我们自己的查询语言翻译示例:
标准SQL看起来像这样:
您将需要将规范表缓存在关联数组或哈希表中或类似的东西中,才能从规范名称中获取spec_id。否则,您将需要插入更多的SQL开销才能从名称中获取spec_id,如以下代码片段所示: 不好的例子,不要使用它,避免使用它,而是缓存规格表!
我希望您能想到这个想法,并可以自己确定该方法是否对您可行。 请享用! :-) 在c2.com Wiki上,探讨了"动态关系"的概念。您不需要DBA:列和表都是写时创建的,除非您开始添加约束以使其表现得更像传统RDBMS:随着项目的成熟,您可以逐步"锁定"它。 从概念上讲,您可以将每一行都视为XML语句。例如,员工记录可以表示为:
这并不意味着必须将其实现为XML,这只是一个方便的概念化。如果您请求一个不存在的列,例如" SELECT madeUpColumn ...",则将其视为空白或空值(除非添加了约束禁止这样做)。可以使用SQL,尽管由于隐含的类型模型,在比较时必须小心。但是,除了类型处理之外,动态关系系统的用户会感到宾至如归,因为他们可以利用他们现有的大多数RDBMS知识。现在,如果有人愿意建造它...
我知道这是一篇过时的文章,并且在过去11年中发生了很多变化,但是我想添加一下,因为这可能对将来的读者有所帮助。我和我的共同创始人创建HarperDB的原因之一是在提供完整索引功能的同时,在单个无重复的数据集中本地完成Dynamic模式。您可以在此处了解更多信息: ElasticSearch。特别是在处理可以按日期分区的数据集,可以对数据使用JSON以及不固定使用SQL检索数据时,应该特别考虑这一点。
ES为您发送的任何新JSON字段(自动使用提示)或您可以通过一个HTTP命令("映射")定义/更改的方式推断模式。 过去,我选择了选项C-创建一个"长而狭窄"的表,将动态列值存储为行,然后需要对其进行透视处理以创建一个"短而宽"的行集,其中包含特定实体的所有值。但是,我使用的是ORM,这确实使事情很痛苦。我想不出如何在LinqToSql中做到这一点。我想我必须创建一个哈希表来引用字段。 @Skliwz:我猜他对允许用户创建用户定义的字段更感兴趣。 sql已经提供了一种更改架构的方法:ALTER命令。 只是有一个表列出了不允许用户更改的字段,并为ALTER编写了一个不错的界面。 |