动态数据模型

Jam*_*mes 19 c# database asp.net modeling semantics

我有一个项目,在运行时需要特定对象的用户定义属性(让我们说这个例子中的人物对象).该项目将有许多不同的用户(1000 +),每个用户为他们自己的'Person'对象集定义他们自己的唯一属性.

(例如 - 用户#1将具有一组已定义的属性,这些属性将应用于此用户拥有的所有人对象.多达1000个用户,这是应用程序将使用的最低用户数.)这些属性将用于查询people对象并返回结果.

我认为这些是我可以使用的可行方法.我将使用C#(以及任何版本的.NET 3.5或4),并且有一个免费的统治:用于数据存储的内容.(我有mysql和mssql可用,虽然可以自由使用任何软件,只要它符合要求)

我的评估中是否遗漏了任何错误或做出了错误的假设?

在这些选择中 - 你会选择什么样的解决方案?

  1. 混合EAV对象模型.(使用常规关系模型定义数据库,并为Person表创建一个'property bag'表).

    缺点:每个/查询有很多连接.表现不佳.可以达到查询中使用的联接/表数量的限制.

    我已经敲了一个快速的样本,它有一个Subsonic 2.x'esqe接口:

    Select().From().Where  ... etc
    
    Run Code Online (Sandbox Code Playgroud)

    这会生成正确的连接,然后过滤+转动c#中返回的数据,以返回使用正确类型的数据集配置的数据表.

    我还没有加载测试这个解决方案.它基于Microsoft白皮书中的EA建议: SQL Server 2008 RTM文档用于性能和可伸缩性的语义数据建模的最佳实践

  2. 允许用户在运行时动态创建/更改对象的表.这个解决方案就是我认为NHibernate在使用动态属性时在后台做的事情,如下所述

    http://bartreyserhove.blogspot.com/2008/02/dynamic-domain-mode-using-nhibernate.html

    缺点:

    随着系统的增长,定义的列数将变得非常大,并且可能会达到最大列数.如果有1000个用户,每个用户的"人"对象有10个不同的属性,那么我们需要一个包含10k列的表.在这种情况下不可扩展.

    我想我可以允许每个用户使用一个人属性表,但是如果有1000个用户可以启动,那么应用程序中有1000个表加上另外10个用户.

    我不确定这是否可扩展 - 但似乎并非如此.如果我不对,请有人纠正我!

  3. 使用NoSQL数据存储区,例如CouchDb/MongoDb

    根据我的阅读,这些尚未在基于字符串的大型应用程序中得到证实,并且处于开发阶段的早期阶段.如果我在这次评估中不正确,有人可以告诉我吗?

    http://www.eflorenzano.com/blog/post/why-couchdb-sucks/

  4. 使用people表中的XML列来存储属性

    缺点 - 没有查询索引,因此需要检索和查询每一列以返回结果集,从而导致查询性能较差.

  5. 将对象图序列化到数据库.

    缺点 - 没有查询索引,因此需要检索和查询每一列以返回结果集,从而导致查询性能较差.

  6. berkelyDB的C#绑定

    从我在这里读到:http://www.dinosaurtech.com/2009/berkeley-db-c-bindings/

    Berkeley Db肯定证明是有用的,但正如Robert指出的那样 - 没有简单的界面.您的整个wOO包装器必须手动编码,并且所有索引都是手工维护的.它比SQL/linq-to-sql困难得多,但这是你为荒谬的速度付出的代价.

    似乎有很大的开销 - 但是如果有人能够提供关于如何在C#中维护索引的教程的链接 - 它可能是一个观众.

  7. SQL/RDF混合.奇怪我以前没想过这个.与选项1类似,但不是"属性包"表,只是XREF到RDF商店?查询将涉及两个步骤 - 查询RDF存储以查找正确属性的人员,返回人员对象,并在SQL查询中使用这些人员对象的ID来返回关系数据.额外的开销,但可能是一个观众.

Lau*_*all 7

Windows上的ESENT数据库引擎大量用于这种半结构化数据.一个例子是Microsoft Exchange,它与您的应用程序一样,拥有数千个用户,每个用户可以在其中定义自己的一组属性(MAPI命名属性).Exchange使用稍微修改过的ESENT版本.

ESENT具有许多功能,可以满足具有大量元数据要求的应用程序:每个ESENT表可以定义大约~32K列; 表,索引和列可以在运行时添加; 稀疏列在未设置时不占用任何记录空间; 和模板表可以减少元数据本身使用的空间.大型应用程序通常有数千个表/索引.

在这种情况下,您可以为每个用户创建一个表,并在表中创建每用户列,从而在要查询的任何列上创建索引.这与某些版本的Exchange存储其数据的方式类似.这种方法的缺点是ESENT没有查询引擎,所以你必须手工制作你的查询作为MakeKey/Seek/MoveNext调用.

ESENT的托管包装器在这里:

http://managedesent.codeplex.com/