如何构建可扩展的数据模型

时间:2009-12-22 09:00:33

标签: c# .net nhibernate fluent-nhibernate

我正在考虑使用NHibernate和Fluent NHibernate构建具有可扩展数据模型的电子商务应用程序。通过拥有可扩展的数据模型,我可以定义一个Product实体,并允许应用程序中的用户使用包含自定义数据类型的不同数据类型的新字段/属性来扩展它。

实施例: 产品可以有以下附加字段: 大小 - int 颜色 - 字符串 价格 - 小数 ColoredImage的集合 - 名称,图像(例如“Red”,red.jpg(二进制文件))

另一个要求是能够通过这些附加/扩展字段过滤产品。我该如何实现呢?

提前致谢。

5 个答案:

答案 0 :(得分:1)

我认为这个链接描述了你想要的东西......

http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx

有关dynamic-component的更多信息:

http://www.mattfreeman.co.uk/2009/01/nhibernate-mapping-with-dynamic-component/ http://bartreyserhove.blogspot.com/2008/02/dynamic-domain-mode-using-nhibernate.html

动态组件背后的想法是,您可以通过不对数据库列与属性进行一对一映射来构建数据模型。相反,您只有一个字典属性,可以包含任意数量的属性数据。这样,当您获取实体时,字典将获取配置为属于该列的所有列的数据。您可以扩展数据库表的模式以包含更多列,如果相应地更新映射文件(手动或通过应用程序启动时的代码),这些列将反映到数据库模型。

老实说,我不知道你可以使用“attributes”属性查询这样的实体,但是如果我不得不猜测我会对它做一个IN语句。

答案 1 :(得分:1)

其中一个选项是EAV模型(实体 - 属性 - 值)。

如果您的域中有一个类,那么该模型很适用,哪个表表示会产生一个宽表(大量列,多个空值)

它最初是为医疗领域设计的,其中物体可能有数千列(症状)。

基本上你有

实体(Id)(例如您的产品表) 属性(Id,ColumnName) 值(EntityId,AttributeId,value)

您可以拥有一些额外的元数据表。

值最好是多个表,一个用于类型。 例如: ShortStringValue(EntityId,AttributeId,Value nvarchar(50)); LongStringValue(EntityId,AttributeId,Value nvarchar(2048)); MemoValue(EntityId,AttributeId,Value nvarchar(max)); IntValue(EntityId,AttributeId,Value int);

甚至是补充类型: ColorComponentsValue(EntityId,AttributeId,R int,G int,B int);

根据我的经验,其中一件事就是你不应该拥有一切的EAV。只需要一个类的EAV,例如Product。 如果必须对不同的基类使用可扩展性,请将它作为一组单独的EAV表。

另一件事是你必须为你的对象发明一种智能的物化策略。 不要将这些值转换为宽行集,仅根据查询条件需要调整少量列,然后为每个选定对象返回一组窄值行。否则,转动将涉及大规模加入。

有几点需要考虑: 。每个值都占用外键的存储空间 。例如,对于此类查询,行级锁定的行为会有所不同,这可能会导致性能下降。 。可能会导致更大的索引大小。

实际上,在一个浅层的hellow世界测试中,我的EAV解决方案在查询中的20列表上优于它的静态对应物,其中4列涉及标准。

答案 2 :(得分:0)

可能的选择是将所有额外字段存储在XML结构中,并使用XPath / XQuery从数据库中检索它们。 应用程序中的每个可扩展实体都将具有XML字段,如ExtendedData,它将包含所有额外属性。

答案 3 :(得分:0)

另一种选择是使用通常适用于此类事物的非关系型数据库。

NOSQL数据库(couchDB,mongoDB,cassandre ...)允许您动态定义您的propretyfields,您可以随时在产品类中添加字段。

答案 4 :(得分:0)

我正在寻找类似的东西,只是找到了N2 CMS(http://n2cms.com),它以非常实用的方式实现了域可扩展性。它还支持查询扩展字段,这很重要。我发现唯一的缺点是它是使用HQL实现的,所以重新实现它需要一些时间才能使用QueryOver / Linq进行查询,但主要思想和映射是存在的。看一下ContentItem,DetailCollection,ContentDetail类,它们的映射和QueryBuilder / DetailCriteria。