如何构建可扩展的数据模型
我正在考虑使用 NHibernate 和 Fluent NHibernate 构建一个具有可扩展数据模型的电子商务应用程序。通过拥有可扩展的数据模型,我能够定义产品实体,并允许应用程序中的用户使用具有不同数据类型(包括自定义数据类型)的新字段/属性来扩展它。
例子: 产品可以有附加字段,例如: 大小 - 整数 颜色 - 字符串 价格 - 小数 ColoredImage 的集合 - 名称、图像(例如“Red”、red.jpg(二进制文件))
另一个要求是能够通过这些附加/扩展字段过滤产品。我应该如何实施这个?
提前致谢。
I'm thinking of building a ecommerce application with an extensible data model using NHibernate and Fluent NHibernate. By having an extensible data model, I have the ability to define a Product entity, and allow a user in the application to extend it with new fields/properties with different data types including custom data types.
Example:
Product can have an addition fields like:
Size - int
Color - string
Price - decimal
Collection of ColoredImage - name, image (e.g. "Red", red.jpg (binary file))
An additional requirement is to be able to filter the products by these additional/extended fields. How should I implement this?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为这个链接描述了你想要的东西......
http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx
有关动态组件的更多信息:
http://www.mattfreeman.co.uk/2009/01/nhibernate-mapping-带动态组件/
http://bartreyserhove.blogspot.com/2008/ 02/dynamic-domain-mode-using-nhibernate.html
动态组件背后的想法是,您可以通过不使用数据库列与属性的一对一映射来构建数据模型。相反,您只有一个字典属性,可以包含来自任意多个属性的数据。这样,当您获取实体时,字典就会获取配置为属于其中的所有列的数据。您可以扩展数据库表的架构以包含更多列,如果您相应地更新映射文件(手动或通过应用程序启动时的代码),这些列将反映到数据库模型中。
老实说,我不知道您可以使用“属性”属性查询此类实体,但如果我不得不猜测,我会对其执行 IN 语句。
I think this link describes kind of what you want...
http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx
More info on 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
The idea behind dynamic-component is that you can build your data model by not having a one to one mapping of databse columns with properties. Instead you have only a dictionary property that can contain data from as many properties as you like. This way when you fetch the entity, the dictionary gets the data of all columns configured to belong in there. You can extend the database table's schema to include more columns and that will be reflected to the databse model if you update the mapping file accordingly (manually or though code at application start).
To be honest I do not know you can query such entity using the "attributes" property but if I had to guess I would do an IN statement to it.
其中一种选项是 EAV 模型(实体-属性-值)。
如果您的领域中有一个类,则该模型很适合应用,该表表示会导致宽表(大量列,许多空值)
它最初是为医疗领域设计的,其中对象可能有数千列(症状)。
基本上你有
实体(Id)(例如你的产品表)
属性(ID,列名)
Value(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。
如果您必须对不同的基类使用可扩展性,请使其成为一组单独的 EAV 表。
另一件事是,您必须为您的对象发明一种智能的物化策略。
不要将这些值转换为宽行集,仅根据查询条件需要转换少量列,然后为每个选定对象返回值行的狭窄集合。否则,旋转将涉及大量连接。
有几点需要考虑:
。每个值都占用外键的存储空间
。例如,行级锁定对于此类查询的行为会有所不同,这可能会导致性能下降。
。可能会导致索引大小变大。
实际上,在浅层地狱世界测试中,我的 EAV 解决方案在条件涉及 4 列的查询中的 20 列表上的性能优于其静态对应方案。
One of the options is EAV model (Entity-Attribute-Value).
This model is good to apply if you have a single class in your domain, which table representation would result in a wide table (large number of columns, many null values)
It's originally designed for medical domain, where objects may have thousands of columns (sympthoms).
Basically you have
Entity (Id) (for example your Product table)
Attribute(Id, ColumnName)
Value(EntityId, AttributeId, value)
You can have some additional metadata tables.
Value should better be multiple tables, one for a type.
For example:
ShortStringValue(EntityId, AttributeId, Value nvarchar(50));
LongStringValue(EntityId, AttributeId, Value nvarchar(2048));
MemoValue(EntityId, AttributeId, Value nvarchar(max));
IntValue(EntityId, AttributeId, Value int);
or even a comple type:
ColorComponentsValue(EntityId, AttributeId, R int, G int, B int );
One of the things from my experience is that you should not have EAV for everything. Just have EAV for a single class, Product for example.
If you have to use extensibility for different base classes, let it be a separate set of EAV tables.
Onother thing is that you have to invent a smart materialization strategy for your objects.
Do not pivot these values to a wide row set, pivot just a small number of collumns for your query criteria needs, then return a narrow collection of Value rows for each of the selected objects. Otherwise pivoting would involve massive join.
There are some points to consider:
. Each value takes storage space for foreign keys
. For example row-level locking will behave different for such queries, which may result in performance degradation.
. May result in larger index sizes.
Actually in a shallow hellow world test my EAV solution outperformed it's static counterpart on a 20 column table in a query with 4 columns involved in criteria.
可能的选择是将所有额外字段存储在 XML 结构中,并使用 XPath/XQuery 从数据库中检索它们。
应用程序中的每个可扩展实体都将有一个 XML 字段,例如 ExtendedData,它将包含所有额外的属性。
Possible option would be to store all extra fields in an XML structure and use XPath/XQuery to retrieve them from the database.
Each extensible entity in your application will have an XML field, like ExtendedData, which will contain all extra properties.
另一种选择是使用通常适合此类事情的非关系数据库。
NOSQL 数据库(couchDB、mongoDB、cassandre...)让您动态定义您的属性字段,您可以随时向您的产品类别添加字段。
Another option is to use Non-relationnal Databases which are typically suited for this kind of things.
NOSQL databases(couchDB, mongoDB, cassandre...) let you define dynamically your propretyfields, you could add fields to your product class whenever you want.
我正在寻找类似的东西,刚刚找到了 N2 CMS (http://n2cms.com),它实现了域可扩展性相当有用的方式。它还支持对扩展字段的查询,这一点很重要。我发现的唯一缺点是它是使用 HQL 实现的,因此需要一些时间来重新实现它才能使用 QueryOver/Linq 进行查询,但主要思想和映射都在那里。查看 ContentItem、DetailCollection、ContentDetail 类、它们的映射和 QueryBuilder/DetailCriteria。
I'm searching for similar thing and just found N2 CMS (http://n2cms.com) which implements domain extensibility in quite usable way. It also supports querying over extension fields which is important. The only downside I find out is that it's implemented using HQL so it would take some time to reimplement it to be able to query using QueryOver/Linq, but the main idea and mappings are there. Take a look on ContentItem, DetailCollection, ContentDetail classes, their mappings and QueryBuilder/DetailCriteria.