问题描述
我想建设使用NHibernate和流利的NHibernate的可扩展数据模型中的电子商务应用。通过拥有一个可扩展的数据模型,我必须定义一个产品的实体,并且允许在应用程序的用户将其与新的领域/属性使用不同的数据类型,包括自定义数据类型的扩展能力。
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.
例:产品能有一个像另外的字段:尺寸 - INT颜色 - 字符串价格 - 十进制收集ColoredImage的 - 名,图像(如红,red.jpg(二进制文件))
Example:Product can have an addition fields like:Size - intColor - stringPrice - decimalCollection 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?
在此先感谢。
推荐答案
选项之一是EAV模型(实体 - 属性 - 值)。
One of the options is EAV model (Entity-Attribute-Value).
这个模型是好的,如果你在你的领域一个类,其中表重新presentation将导致宽表(大量列,许多空值),以适用
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)
它的最初设计用于医疗领域,在那里对象可能有数以千计的列(sympthoms)。
It's originally designed for medical domain, where objects may have thousands of columns (sympthoms).
基本上你
实体(ID)(例如,您的产品表)属性(ID,的ColumnName)值(EntityId,AttributeId,值)
Entity (Id) (for example your Product table)Attribute(Id, ColumnName)Value(EntityId, AttributeId, value)
您可以有一些额外的元数据表。
You can have some additional metadata tables.
值最好是多个表,一个是类型。例如:ShortStringValue(EntityId,AttributeId,价值为nvarchar(50));LongStringValue(EntityId,AttributeId,价值为nvarchar(2048));MemoValue(EntityId,AttributeId,价值为nvarchar(max));的intValue(EntityId,AttributeId,值INT);
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);
甚至完井类型:ColorComponentsValue(EntityId,AttributeId,R INT,G INT,B INT);
or even a comple type:ColorComponentsValue(EntityId, AttributeId, R int, G int, B int );
一,从我的经验的事情是,你不应该有EAV的一切。只要有EAV的一个类,产品为例。如果你有使用的可扩展性为不同的基类,让它成为一套独立的EAV表。
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的事情是,你必须创造一个聪明的策略,物化为对象。不要转动这些值宽行集,透视只是少数collumns为您查询条件的需求,然后返回一个狭窄的收藏价值排为每个选定的对象。否则,旋转将涉及大量的加入。
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.
其实在浅hellow世界的测试我的EAV的解决方案胜过它在一个20列的表对应的静态与参与标准的4列的查询。
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.
这篇关于你如何建立可扩展的数据模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!