我们希望在我们的购物网站中存储两种或多种产品之间的比较数据。
我找到了以下链接,但是当我们尝试时,我们遇到了一些性能问题
SQL Group By / Count:跨多列计算相同的值?
我们如何存储我们的数据?比较历史数据的表模式应该是什么?如何显示比较最多的产品?查询会是什么?
我们希望在我们的购物网站中存储两种或多种产品之间的比较数据。
我找到了以下链接,但是当我们尝试时,我们遇到了一些性能问题
SQL Group By / Count:跨多列计算相同的值?
我们如何存储我们的数据?比较历史数据的表模式应该是什么?如何显示比较最多的产品?查询会是什么?
这个问题非常广泛且有点模糊,我的回答可能包含您已经做出的考虑。
为了进行比较逻辑,您需要三件事;产品,该产品的评级和一些逻辑分组产品进行比较的方法。具有适当索引的粒度通常是最好的。
这是我将创建的表/索引的示例:
Create Table Product (ProductID Int, ProductName Varchar(256), etc)
Create Table Groups (GroupID Int, GroupName Varchar(256), etc)
Create Table ProductGroup (ProductID Int, GroupID Int)
Create Table RatingType (RatingID Int, RatingName Varchar(64))
Create Table ProductRatings (ProductID Int, RatingID Int, RatingValue Varchar(32))
Create Clustered Index ix_Product_pID On Product (ProductID)
Create Nonclustered Index ix_Product_pID_pName On Product (ProductID, ProductName)
Create Clustered Index ix_Groups_gID On Groups (GroupID)
Create Nonclustered Index ix_ProductGroup_gID_pID On ProductGroup (GroupID, ProductID)
Create Clustered Index ix_RatingType_rID On RatingType (RatingID)
Create Nonclustered Index ix_ProductRatings_pID_rID On ProductRatings (ProductID, RatingID)
将聚集索引放在 Product、Group 和 RatingType 上是有意义的,因为它们的 ID 列将是它们的标识列,因此您不必担心物理顺序,因为它们是连续的。另一方面,ProductGroup 和 ProductRatings 可以随时以任何顺序接收任何记录,因此在它们上放置聚集索引会减慢插入速度并导致更快的碎片。
要执行链接示例中查询中完成的逻辑,您将执行以下操作:
Create Proc GetProductComparisonRatings (@productID Int, @ratingID Int)
As
Declare @columns Nvarchar(Max),
@SQL Nvarchar(Max);
;With DistinctCols As
(
Select Distinct p.productName
From ProductGroup pg1
Join ProductGroup pg2
On pg1.groupID = pg2.groupID
Join Product p
On pg2.productID = p.productID
Where pg1.productID = @productID
)
Select @columns = Coalesce(@columns + ',','') + '[' + productName + ']'
From DistinctCols
Order By Case
When p.productID = @productID Then 0
Else 1
End; -- This will put your product that was the basis of the comparison as the leftmost column
Select @SQL = ';With baseRecords As
(
Select pg2.productID,
pr.ratingValue,
Count(1) As cnt
From ProductGroup pg1
Join ProductGroup pg2
On pg1.groupID = pg2.groupID
Join ProductRatings pr
On pg2.productID = pr.productID
And pr.ratingID = ' + @ratingID + '
Where pg1.productID = ' + @productID + '
Group By pg2.productID,
pr.ratingValue;
)
Select ratingValue, ' + @columns + '
From baseRecords br
Join product p
On br.productID = p.productID
Pivot (Sum(cnt) For p.productName In (' + @columns + ')) pivot';
Exec sp_executeSQL @SQL;
这更进一步,并将评级比较限制为特定的 ratingType;一些例子可能是(耐用性、尺寸、整体)。如果您只有一个 ratingType,它仍然可以正常工作。您可以根据需要编辑或更改它。