Zee*_*eep 7 sql-server t-sql eav
我有点坚持如何构建一个有效的查询,该查询返回以下 EAV 结构的数据。
今天,产品表已经存在,包含 4 个固定字段。我们希望升级系统,允许无限量的附加产品字段,由每个产品的制造商定义。我们称这些附加字段为“参数”。
参数可以是以下数据类型:
基于此,我创建了以下数据库模型:
:
我需要在 ASP.NET C# 中构建一个网页,该网页显示所有产品数据的列表,包括每个定义的参数及其对该产品的值。我需要能够通过搜索任何字段/参数来过滤列表。此列表还需要可在任何字段/参数上排序。
我尝试通过外部连接 Product - ProductParameter - ProductParametervalueListItem - ParameterValueListItem 来过滤列表,以获得包含所有数据的表结果,然后使用由 Web 应用程序构建和传递的动态 where 子句过滤该列表。这在您搜索 1 个参数时有效,但是当您开始搜索多个参数时,您会得到不正确的结果,因为每个参数在表结果中都是不同的行,并且参数 A 和 B 之间根本没有“与”匹配,因为它们不存在于同一记录(行)中。
谁能建议我如何实现这一目标?最完美的解决方案是 1 个表结果,其中包含所有数据,并且每个参数都显示为同一产品行中的一列。这是否太复杂而无法在数据库级别处理?
感谢您阅读到这里。欢迎任何建议。
首先,你要设计的可能是一个非常糟糕的主意。更好的解决方案是拥有一个动态模式,您可以在其中添加新表并让应用程序了解如何查询这些表(您可以将它们放在模式中)。这很大程度上避免了使用此模型必然遇到的所有锁定和查询计划问题。CREATE TABLE
偶尔运行的应用程序没有任何问题。
其次,我不确定我理解为什么你已经规范化Parameter
到自己的表中?为什么不直接将其放入ManufacturerParameter
表中。
第三,如果您坚持继续使用当前的模型,则有多种方法可以实现您想要的(至少如果我正确解释您的要求的话)。您可以做的就是以这样的方式编写查询,即在存在匹配时对搜索参数进行求和,然后用于HAVING
过滤掉匹配的值。我假设每条记录仅填充字段Text
、等之一(您可能希望通过约束来强制执行此操作Boolean
)Datum
ProductParameter
例如,要搜索一个参数具有 boolean = true 且其他参数具有 text = 'abc' 的所有产品,您可以执行以下操作:
SELECT P.Name
FROM Product P
JOIN ProductParameter PP
WHERE P.ID = Foo
AND PP.Boolean = 1 OR PP.Text = 'abc' ... /* For each filter */
GROUP BY P.Name /* And any other things you want out of product */
HAVING COUNT(*) >= [Number of where clauses]
Run Code Online (Sandbox Code Playgroud)
如果需要列出该产品的所有参数,可以使用上面的查询模板作为嵌套查询,并回连接到ProductParameter
.
可以通过维护一个计算列来优化上述查询,ProductParameter
该计算列具有该表中不同数据类型的字符串表示形式。这样,上面的 OR 语句可以重写为 IN 列表(您将希望将其作为表值参数传递)。
我想重申一下,你所做的事情可能是非常错误的。如果您这样做,您很可能需要手动调整大部分查询计划 - 优化器将不再为您提供帮助。假设您没有太多查询变体,这将使您的计划缓存满。
归档时间: |
|
查看次数: |
8775 次 |
最近记录: |