动态数据库架构
为动态逻辑数据库架构提供存储的推荐体系结构是什么?
需要说明的是:在要求系统为模型提供存储的情况下,其模型可能会在生产后由其用户扩展或者更改,那么哪些好的技术,数据库模型或者存储引擎将允许这种存储?
一些可能性来说明:
- 通过动态生成的DML创建/更改数据库对象
- 创建具有大量稀疏物理列的表,并且仅使用"重叠"逻辑架构所需的表
- 创建一个"长而窄"表,将动态列值存储为行,然后需要对其进行旋转以创建一个"短而宽"行集,其中包含特定实体的所有值
- 使用BigTable / SimpleDB PropertyBag类型系统
任何基于现实世界经验的答案将不胜感激
解决方案
回答
MSSQL中的强类型xml字段对我们有用。
回答
建立关系数据库的全部目的是确保数据安全和一致。从允许用户更改架构的那一刻起,数据完整性便随之而来...
如果我们需要存储异构数据(例如CMS场景),则建议连续存储经过XSD验证的XML。当然,我们会失去性能和简单的搜索功能,但这是对IMHO的一个很好的折衷。
既然是2016年,那就不用XML了!使用JSON来存储非关系数据包,并使用适当类型的列作为后端。通常,我们不需要在包中按值查询,这会很慢,即使许多现代的SQL数据库本身就了解JSON。
回答
在我看来,我们真正想要的是某种"元模式",这是一种数据库模式,能够描述用于存储实际数据的灵活模式。动态模式更改是敏感的,不是我们想惹的麻烦,尤其是在允许用户进行更改的情况下。
我们不会找到比其他任何数据库更适合该任务的数据库,因此,最好的选择就是根据其他条件选择一个。例如,我们使用什么平台托管数据库?应用程序用什么语言编写?等等
为了澄清我所说的"元模式":
CREATE TABLE data ( id INTEGER NOT NULL AUTO_INCREMENT, key VARCHAR(255), data TEXT, PRIMARY KEY (id) );
这是一个非常简单的示例,我们可能会根据自己的需求找到一些更具体的东西(希望可以更轻松地使用它),但这确实可以说明我的观点。我们应该认为数据库模式本身在应用程序级别是不可变的。任何结构上的更改都应反映在数据中(即该架构的实例化)。
回答
在过去,我选择了选项C-创建一个"长而狭窄"的表,该表将动态列值存储为行,然后需要进行透视以创建一个"短而宽"的行集,其中包含特定实体的所有值。但是,我使用的是ORM,这确实使事情很痛苦。我想不出如何在LinqToSql中做到这一点。我想我必须创建一个哈希表来引用字段。
@Skliwz:我猜他对允许用户创建用户定义的字段更感兴趣。
回答
我知道问题中指出的模型已在整个生产系统中使用。我供职的大型大学/教学机构正在使用一个相当大的应用程序。他们特别使用狭长表方法来映射由许多不同的数据采集系统收集的数据。
另外,Google最近通过其代码站点发布了其内部数据共享协议(协议缓冲区)作为开源。以这种方法为模型的数据库系统将非常有趣。
检查以下内容:
实体-属性-价值模型
Google协议缓冲区
回答
sql已经提供了一种更改架构的方法:ALTER命令。
只是有一个表列出了不允许用户更改的字段,并为ALTER编写了一个不错的界面。
回答
我在一个真实的项目中做到了:
该数据库由一个表和一个字段组成,其中一个字段由50个数组组成。该字段上设置了"单词"索引。所有数据都是无类型的,因此"单词索引"按预期工作。数字字段表示为字符,并且实际排序已在客户端完成。 (如果需要,每种数据类型仍然可以具有多个数组字段)。
逻辑表的逻辑数据模式保存在同一数据库中,但表行"类型"不同(第一个数组元素)。它还支持使用相同的"类型"字段以写时复制样式进行的简单版本控制。
好处:
- 我们可以动态地重新排列和添加/删除列,而无需转储/重新加载数据库。任何新的列数据都可以在零时间内设置为(虚拟)初始值。
- 由于所有记录和表的大小均相同,因此碎片最少,有时可以提供更好的性能。
- 所有表架构都是虚拟的。任何逻辑模式结构都是可能的(甚至是递归的或者面向对象的)。
- 这对于"一次写入,大部分读取,无删除/标记为删除"的数据很有用(大多数Web应用程序实际上就是这样)。
缺点:
- 仅按完整词编制索引,不使用缩写,
- 可能进行复杂的查询,但性能会稍有下降。
- 取决于首选数据库系统是否支持数组和单词索引(在PROGRESS RDBMS中进行了补充)。
- 关系模型仅在程序员心目中(即仅在运行时)。
现在,我正在考虑下一步可能是在文件系统级别上实现这样的数据库。那可能比较容易。
回答
建议并不新鲜。很多人都尝试过……大多数人发现他们追求"无限"的灵活性,而最终获得的收益却远不止于此。这是数据库设计的"蟑螂汽车旅馆"-数据可以输入,但几乎不可能将其释放出来。尝试并针对任何类型的约束对代码进行概念化编写,我们将明白我的意思。
最终结果通常是一个更难以调试,维护和充满数据一致性问题的系统。情况并非总是如此,但往往并非如此,最终就是如此。主要是因为程序员看不到火车残骸的到来,并且无法防御性地针对它进行编码。而且,通常最终会出现这样的情况:"无限"的灵活性实际上不是必需的。当开发团队得到一个说明说"天哪,我不知道他们将要放在这里的数据是什么,所以让他们放进去",这是一个非常糟糕的"气味"……而最终用户也很好具有可以使用的预定义属性类型(编写通用电话号码,并让他们创建其中任何一个-在一个很好的规范化系统中这是微不足道的,并且可以保持灵活性和完整性!)
如果我们有一个非常优秀的开发团队,并且充分意识到使用此设计必须克服的问题,那么我们可以成功编写出设计良好,而不是十分棘手的系统。大多数时候。
但是,为什么为什么要从与我们对立的赔率开始呢?
不相信我吗? Google"一个真实的查询表"或者"单个表设计"。一些好的结果:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0:::::P11_QUESTION_ID:10678084117056
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
回答
创建2个数据库
- DB1包含静态表,并表示数据的"真实"状态。
- DB2是免费的,用户可以根据自己的意愿进行操作-他们(或者我们)将不得不编写代码以从DB1填充其奇形表格。
回答
就像其他人所说的那样,除非我们别无选择,否则不要这样做。要求这样做的一种情况是,我们正在销售必须允许用户记录自定义数据的现成产品。我公司的产品属于这一类。
如果我们确实需要允许客户这样做,这里有一些提示:
创建一个健壮的管理工具来执行模式更改,并且不允许以任何其他方式进行这些更改。
使其具有管理功能;禁止普通用户访问它。
记录有关每个架构更改的每个详细信息。这将调试问题,并且如果客户做一些愚蠢的事情,还将为我们提供CYA数据。
如果我们可以成功完成这些操作(尤其是第一个操作),那么我们提到的任何体系结构都将起作用。我的首选是动态更改数据库对象,因为当我们访问存储在自定义字段中的数据时,这使我们可以利用DBMS的查询功能。其他三个选项要求我们加载大量数据,然后在代码中执行大部分数据处理。
回答
我有类似的要求,因此决定使用无模式的MongoDB。
MongoDB (from "humongous") is an open source, scalable, high-performance, schema-free, document-oriented database written in the C++ programming language. (Wikipedia)
强调:
- 具有丰富的查询功能(也许是最接近SQL数据库的数据库)
- 生产就绪(foursquare,sourceforge使用它)
Lowdarks(我们需要了解的东西,因此我们可以正确使用mongo):
- 没有交易(实际上它有交易,但仅在原子操作上)
- 这个东西在这里:http://ethangunderson.com/blog/two-reasons-to-not-use-mongodb/
- 耐久性..主要是与酸有关的东西