1

首先,我不确定这是否是处理这个问题的最佳方式……完全可以接受替代解决方案。

其次,我觉得我错过了明显的......但我仍然错过了它,所以不要骄傲地问!

更新:带有 SQL 2005 的 .NET 3.5 环境,因此可以使用动态 linq,尽管我总是倾向于将任何类型的动态(即时构建)查询视为笨重的。PITA 来维护。

更新2:为了响应北极,伪代码/书面文字逻辑/ sql / linq / C#都可以接受(!)......更多的是一个概念上的“什么是好方法”,而不是我需要代码类型的问题。

给定一张看起来像这样的“鞋子”表:

  ShoeID 属性名 属性值
  1 颜色红色   
  2色红色   
  2 尺寸 11
  3色红   
  3 尺寸 11   
  3 制造商 GUCCI

我需要一种方法来查询鞋子,这样

颜色=红色返回

  1
  2
  3

COLOR=RED 和 SIZE=11 返回

  2
  3

COLOR=RED 和 SIZE=11 和 MANUFACTURER=GUCCI 返回

  3

在设计时,我知道可能有多少不同的属性,也不知道可能有多少查询参数......

希望这是有道理的......如果没有,请相应地发表评论,我会再试一次。

4

3 回答 3

1

所以这是否是最好的方法取决于很多事情。例如,您是否需要支持可能具有不同(不兼容)属性的不同类别的实体(例如鞋子与连衣裙)?或者您将拥有的估计实体数量是多少(对于 10K 来说可以很好地工作的东西对 100M 来说是无效的)?或者您需要多久处理一次此类查询以及它们需要执行多长时间?

两个最常见的思想流派是EAV 模型,这或多或少是您所拥有的,以及基于列的方法,其中您的实体属性(颜色、大小等)每个都映射到单独的列。每个都有其优点和缺点,其中最大的是前者的灵活性/性能以及为后者动态更改表结构的必要性。

如果您确实使用现有模型,我建议将您的属性名称移动到一个单独的表中,并将“鞋子”表更改为该表的 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'

如果您具有或多或少均匀分布的属性而不是大量鞋子,那么它应该表现得相当好。

于 2009-08-13T19:49:14.777 回答
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

当然,由于工具的不同,它可能会略有不同。

鲍里斯。

于 2009-08-13T19:29:09.600 回答
0

如果我对您的理解正确,您希望能够创建一个查询,该查询可以具有基于任意数量的字段的条件,这些字段是预先未知的。这很难……

虽然大多数 RDBMS 确实提供了某种“动态 SQL”功能,但这些方法往往使用起来很麻烦,或者速度很慢,或者两者兼而有之。

当然,您也可以在您的客户端代码中将一条 SQL 语句连接在一起,无论是 C#、Java、PHP 还是其他 - 但这又会很麻烦,容易受到 SQL 注入攻击,而且通常相当笨拙。

此外,如果您的查询与一个请求不同,RDBMS 将无法缓存您的任何查询计划,并且获得正确的索引以获得良好的查询性能充其量是具有挑战性的,在最坏的情况下是不可能的。

因此,虽然我完全理解这个要求(并且几乎每天都必须与它作斗争),但这确实是一件效果不佳的事情。我宁愿尝试识别最常用的搜索及其标准,并确保它们工作正常且速度快。限制用户的灵活性以实现不错的查询性能。一个经典的权衡 - 你可以完全灵活,但你的性能很糟糕,或者你可以让你的频繁查询运行得很快 - 但失去了一些灵活性。

在文本字段中搜索自由文本时,您可能会有所收获的一个领域 - 像 SQL Server 这样的 RDBMS 支持全文搜索的概念,这为您提供了一些灵活性和良好的性能。如果您有很多文本字段,请检查。

马克

于 2009-08-13T19:30:44.027 回答