(MS SQL)如何实现相关文章功能(多关键字匹配)

前言:大家或许会觉得很惊讶:为什么灵感之源会讨论SQL?或许应该这样说吧:搞业务系统,不跟SQL扯上关系似乎比较难。

场景:在开发某系统的过程中,我遇到了要实现“相关文章”功能:任何文章都可以定义“关键字”,每篇文章依靠这个“关键字”来确定其它文章是否跟它相关,如果没有定义关键字,则可能需要使用全文检索来实现了,这是别的话题了。

思考:因为允许关键字可以通过“,”分隔符号来定义多个,所以加大了难度。经过思考,可以通过在保存文章的时候便分解关键字,建立一关键字表,把所有关键字逐个按对应的文章ID来保存。并决定采用纯SQL存储过程的办法,因为这种重复的操作,与其用通用函数,倒不如用预编译的存储过程更加快,这样能把所有处理都留給SQL Server。

解决方案:首选要做的是在原有文章表(Details)的基础上建立相关文章表(RelatedDetails),字段包括ItemID(主键)、DetailID(文章ID)和Keyword(关键字)。以下是主要存储过程:

1、UpdateRelatedDetails:更新相关文章关键字

CREATE   procedure  dbo.UpdateRelatedDetails

@DetailID 
INT ,
@Keywords 
NVARCHAR ( 500 )

AS

EXEC  DeleteRelatedDetails @DetailID

DECLARE  @I  INT
DECLARE  @Keyword  NVARCHAR ( 50 )

SET  @Keywords = REPLACE (@Keywords, ' ' ' , ' )
SET  @Keywords = REPLACE (@Keywords, ' ' ' , ' )
SET  @Keywords = RTRIM ( LTRIM (@Keywords))

SET  @I = CHARINDEX ( ' , ' , @Keywords)

WHILE  @I >= 1
    
BEGIN
        
SET  @Keyword = LEFT (@Keywords, @I - 1 )
        
INSERT   INTO  DetailKeywords (DetailID, Keyword)  VALUES (@DetailID, @Keyword)
        
SET  @Keywords = SUBSTRING (@Keywords, @I + 1 , LEN (@Keywords) - @I)
        
SET  @I = CHARINDEX ( ' , ' , @Keywords)
    
END

IF  @Keywords <> ''
    
INSERT   INTO  DetailKeywords (DetailID, Keyword)  VALUES (@DetailID, @Keywords)
GO

2、DeleteRelatedDetails:删除原有相关文章关键字
CREATE   PROCEDURE  dbo.DeleteRelatedDetails

@DetailID 
INT

AS

DELETE   FROM  DetailKeywords  WHERE  DetailID = @DetailID
GO

3、GetRelatedDetails:获取相关文章,其中Details就是文章表
CREATE   procedure  dbo.GetRelatedDetails

@DetailID 
INT

AS

DECLARE  @Keywords  NVARCHAR ( 500 )

SELECT  @Keywords = Keywords  FROM  Details  WHERE  ItemID = @DetailID

IF  @Keywords <> ''
    
BEGIN
        
SELECT   DISTINCT  d.ItemID, d.Subject, d.ItemFile
        
FROM  Details d  RIGHT   OUTER   JOIN  DetailKeywords k  ON  k.DetailID = d.ItemID          WHERE  d.ItemID  <>  @DetailID  AND  @Keywords  LIKE   ' % ' + k.Keyword + ' % '
    
END
GO


代码很简单,但希望能給大家带来一点思考:)

p.s.因为前台是使用.NET写的,那这个帖子也算是部分.NET技术了,呵呵。

你可能感兴趣的:(sql)