首先,我不确定这是处理此问题的最佳方法......完全接受替代解决方案。
其次,我觉得我错过了显而易见的......但是我仍然想念它,所以不要自豪地问!
更新:.NET 3.5环境w / SQL 2005,所以像动态linq这样的东西是可能的,虽然我总是倾向于认为任何类型的动态(构建在线)查询都是笨重的。 PITA维持。
UPDATE 2 :响应northpole,伪代码/写入字逻辑/ sql / linq / C#都可以接受(!)...更多的是一个名义上“什么是好方法”而不是我需要代码的问题。
给出一张“鞋子”表,如下所示:
ShoeID PropertyName PropertyValue 1 COLOR RED 2 COLOR RED 2 SIZE 11 3 COLOR RED 3 SIZE 11 3 MANUFACTURER GUCCI
我需要一种方法来查询鞋子
COLOR = RED返回
1 2 3
COLOR = RED,SIZE = 11返回
2 3
COLOR = RED和SIZE = 11,MANUFACTURER = GUCCI返回
3
在设计时,我不知道可能有多少不同的属性,也不知道可能有多少查询参数......
希望这是有道理的......如果没有,请相应评论,我会再试一次。
答案 0 :(得分:1)
因此,这是否是最佳方法取决于许多事情。例如,您是否需要支持可能具有不同(不兼容)属性的不同类别的实体(例如鞋子与礼服)?或者你所拥有的实体估计数量是多少(对于10K而言效果合理的东西不适用于100M)?或者您需要多长时间处理此类查询以及它们需要执行的程度?
两个最常见的思想流派是EAV model,它或多或少是你所拥有的column-based approach,你的实体的属性(颜色,大小等等)都被映射到一个单独的专栏。每个都有其优点和缺点,其中最大的是前者的灵活性/性能以及动态改变后者的表结构的必要性。
如果您使用现有模型,我建议您将属性名称移到单独的表中,并更改“鞋子”表以使FK到该表。然后,您可以在(property_id
,shoe_id
)上创建索引并生成查询,如下所示:
SELECT shoe_id FROM shoes S_1 [, shoes S_2, ..., shoes S_X]
WHERE S_1.property_id = 3 /* FK for 'color' */
/* the following 3 lines will be repeated for each 'property' you need to query on */
AND S_X.property_id = 4 /* FK for 'size' */
AND S_X.shoe_id = S_1.shoe_id
AND S_X.property_value = 'RED'
如果您的属性分布或多或少均匀,而且鞋子数量不多,那么应该合理地执行 。
答案 1 :(得分:0)
动态sql会帮助你。类似的东西:
ALTER PROCEDURE [dbo].[sp_GetFilteredRecords]
(
...
@ConditionList nvarchar(MAX) = null
)
AS
BEGIN
DECLARE @sql nvarchar(MAX),
@paramlist nvarchar(MAX)
SELECT @sql = 'select ... '
...
SELECT @sql = @sql + ' where 1=1 '
...
SELECT @sql = @sql + ' ' + @ConditionList + ' '
SELECT @paramlist = ...
EXEC sp_executesql @sql, @paramlist
当然,由于工具可能略有不同。
鲍里斯。
答案 2 :(得分:0)
如果我理解正确,您希望能够创建一个查询,该查询可能具有基于任何数量的字段的标准,这些字段在前面是未知的。那太难了......
虽然大多数RDBMS都提供某种“动态SQL”功能,但这些方法往往使用起来很麻烦,或者速度很慢,或者两者兼而有之。
当然,您也可以在客户端代码中将SQL语句连接在一起,无论是C#,Java,PHP还是其他任何东西 - 但这又会变得很麻烦,容易发生SQL注入攻击,而且通常比较笨拙。
此外,如果您的查询与另一个请求不同,则RDBMS将无法缓存您的任何查询计划,并且获得正确的索引以获得良好的查询性能将充其量是挑战,不可能最糟糕的。
因此,虽然我完全理解了这个要求(并且几乎每天都必须自己解决这个问题),但实际上它并不适用。我宁愿尝试识别最常用的搜索及其标准,并确保这些搜索工作正常并且速度很快。限制用户的灵活性,以实现良好的查询性能。一个经典的权衡 - 你可以完全灵活,但是你的表现很糟糕,或者你可以让你的频繁查询运行得很快 - 但是会失去一些灵活性。
在一个可能获得某些东西的领域是在文本字段中搜索自由文本时 - 像SQL Server这样的RDBMS支持全文搜索的概念,这为您提供了一些灵活性和良好的性能。如果你有很多文本字段,请检查一下。
马克