什么是获得相关项目的最佳SQL查询?

Mar*_*c V 1 sql t-sql linq sql-server-2005

我有一个小网站,我希望在标签的基础上获得相关视频...什么可能是最好的MS SQL 2005查询,以获得基于标签的相关视频.如果你能给出很棒的LINQ查询.

这是数据库架构:

CREATE TABLE Videos
    (VideoID bigint not null , 
    Title varchar(100) NULL, 
    Tags varchar(MAX) NULL, 
    isActive bit NULL  )

INSERT INTO Videos VALUES ( 1,'Beyonce Shakira - Beautiful Liar','shakira, beyonce, music, video',1)
INSERT INTO Videos VALUES ( 2,'Beyonce Ego Remix','beyonce, music, video',1)
INSERT INTO Videos VALUES ( 3,'Beyonce Ego','beyonce, music, video',1)
Run Code Online (Sandbox Code Playgroud)

我希望在观看ID为1的视频时,它应该根据其标签显示相关视频,大多数匹配的术语应该排在最前面.

提前致谢

Ale*_*lli 6

您显示的模式,对于填充到Tags字符串中的每个视频的所有标记进行非规范化,都是为您的目的设计的 - 在TSQL中没有合理的方法来计算这种格式的两个字符串之间有意义的"共性",因此没有合理的方式来检查哪些项目具有相对较高的共性,因此可以被视为"相关".如果模式是不可触及的,那么你必须为此目的实现一个用户定义的函数(用C#或其他.NET语言),即使这样你也会或多或少地扫描整个表,因为没有合理的方法在此基础上的指数.

如果您可以重新设计架构(还有两个表:一个用于存放标签,另一个用于表示标签和视频之间的许多关系),可能会有更好的前景; 在这种情况下,大概有多少(数量级)视频的预期,总体上有多少(同上)不同的标签,以及视频预期会有多少标签,这可能会让设计和有效方式得以实现追求你的目的.

编辑:根据评论,显然可以重新设计架构,虽然仍然没有给出关于我问的数字的指示,所以适当的指数和c将仍然是一个完全神秘的.无论如何,假设模式是这样的(每个表可以根据需要添加其他列,只需将它们添加到查询中;并且VARCHAR长度也无关紧要):

CREATE TABLE Videos (VideoID INT PRIMARY KEY,
                     VideoTitle VARCHAR(80));

CREATE TABLE Tags (TagID INT PRIMARY KEY,
                   TagText VARCHAR(20));

CREATE TABLE VideosTags (VideoID FOREIGN KEY REFERENCES Videos,
                         TagID FOREIGN KEY REFERENCES Tags,
                         PRIMARY KEY (VideoId, TagId));
Run Code Online (Sandbox Code Playgroud)

即只是经典的"多多关系"教科书的例子.

现在给出一个视频的标题,比如@MyTitle,可以很容易地查询与其最"相关"的5个视频的标题,例如:

WITH MyTags(TagId) AS
(
  SELECT VT1.TagID
  FROM Videos V1
  JOIN VideosTags VT1 ON (V1.VideoID=VT1.VideoID)
  WHERE V1.VideoTitle=@MyTitle
)
SELECT TOP(5) V2.VideoTitle, COUNT(*) AS CommonTags
FROM Videos V2
JOIN VideosTags VT2 ON (V2.VideoID=VT2.VideoID)
JOIN MyTags ON (VT2.TagId=MyTags.TagId)
GROUP BY V2.VideoId
ORDER BY CommonTags DESC;
Run Code Online (Sandbox Code Playgroud)