我有几个实体,我要求用户能够添加自定义字段。
如果我有一个名为customer的实体,其基本变量如{Name,DateOfBirth,StoreId} 另一个名为Store with {Name}
然后我想要它,以便该商店的所有者可以登录并为所有客户添加一个名为收藏颜色的新变量,这是一个红色,绿色或蓝色作为选项的下拉列表。
现在我已经看过EAV并想出一个看起来像这样的解决方案
属性{StoreId,Name,DataType}, 值{AttributeId,EntityName,EntityId,Value}
我想知道是否有一些最适合SQL Server 2008的解决方案,特别是考虑到我希望能够轻松查看和查询这些信息。
我听说你可以在xml数据类型中查询。这是一个更好的方法吗?
我也可能希望用户能够在某些时候添加外键的自定义字段。
将整天关注此问题,以便快速提问。
答案 0 :(得分:4)
EAV通常是一种反模式,导致性能低下并扼杀可扩展性。现在,如果您决定使用EAV,SQL Server客户咨询团队已发布了一份白皮书,其中包含常见的陷阱和问题以及如何避免这些问题:Best Practices for Semantic Data Modeling for Performance and Scalability。
在SQL中可以查询XML数据类型,但是如果您的XML没有架构,那么查询它将会很慢。如果它有一个模式并且模式是EAV,那么它将具有关系EAV的所有问题以及它自己的一些XML性能问题。 CAT小组的优秀人员再次发表了几篇关于该主题的白皮书:XML Best Practices for Microsoft SQL Server 2005和Performance Optimizations for the XML Data Type in SQL Server 2005。它们也适用于SQL 2008。
答案 1 :(得分:2)
我一直在使用SQL 2005/2008的XML功能。我已经非常依赖XML列了。 你想做什么听起来像是XML的完美候选者。 例如,下面的代码片段定义了您的2个实体(@customers和@stores),其中一个名为“attrs”的列可以扩展为包含更多属性。 我希望这有帮助!
declare @customers as table ( id int, attrs xml);
INSERT INTO @customers VALUES
(1,'<Attrs Name="Peter" DateOfBirth="1996-01-25" StoreId="10" />'),
(2,'<Attrs Name="Smith" DateOfBirth="1993-05-02" StoreId="20" />')
;
declare @stores as table ( id int, attrs xml);
insert into @stores VALUES
(10, '<Attrs Name="Store1" />'),
(20, '<Attrs Name="Store2" />')
;
With c as (
select id as CustomerID,
attrs.value('(/Attrs[1])/@Name', 'nvarchar(100)') as Name,
attrs.value('(/Attrs[1])/@DateOfBirth', 'date') as DateOfBirth,
attrs.value('(/Attrs[1])/@StoreId', 'int') as StoreId
from @customers
), s as (
select id as StoreID,
attrs.value('(/Attrs[1])/@Name', 'nvarchar(100)') as Name
from @stores
)
select *
from c left outer join s on (c.StoreId=s.StoreID);
答案 2 :(得分:1)
已经有很好的答案了。我只会添加您为自定义字段维护元数据的建议。这将使用户界面更容易输入自定义字段 - 例如,您可以限制客户的自定义字段集,并指定DateOfBirth是一个日期,并且该StoreID旨在匹配实际商店的ID。
其中一些元数据可以作为XML模式维护。我已经看到完成了,模式存储在数据库中,并用于验证输入的自定义字段。我不知道这些模式是否也可用于强类型化XML数据。