3

我正在信息系统中开发消息中心,今天用户 Eric 建议使用 hierarchyid 数据类型来跟踪消息回复,因为目标是显示为 Outlook 或 Gmail 对话。

为了简化,我在我的数据库表 Messages 中有:

MessageId int PK
ReplyToId int FK null
Subject varchar
Body varchar
Hierarchy hierarchyid

当插入新消息时,我有一个触发器来进行更新。

我插入了一条新消息,层次结构为空,因为是第一条消息,而不是回复。

如果尝试插入对该消息的回复,则 hierarchyid 仍然为空... :(

我的触发器:

ALTER TRIGGER [dbo].[trg_UpdateHierarchy] 
   ON  [dbo].[Messages]
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here

    DECLARE @replyId int
    SELECT @replyId = inserted.ReplyId
    FROM inserted
    IF(@replyId IS NULL)
    BEGIN
        RETURN
    END

    DECLARE @parent hierarchyid
    SELECT @parent = Hierarchy
    FROM   [Messages]
    WHERE  [Messages].MessageId = @replyId


    DECLARE @currentHierarchy hierarchyid = @parent.GetDescendant(null, null).ToString()
    DECLARE @messageId int
    SELECT @messageId = inserted.MessageId
        FROM inserted
    UPDATE [Messages]
        SET Hierarchy = @currentHierarchy
        WHERE [Messages].MessageId = @messageId
END
GO 

我做错了什么?

另一点,我读过索引,但深度优先不适合,因为有很多空值,因为来自对话的第一条消息具有空值,而面包优先是最好的索引类型,具有更好的表现?或者我可以丢弃这个索引?

提前致谢!

编辑:

我已经更新了触发器,但没有hierarchyid以正确的方式进行。

现在触发器是:

ALTER TRIGGER [dbo].[trg_UpdateHierarchy] 
   ON  [dbo].[Messages]
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    DECLARE @messageId int
    DECLARE @ParentId int
    SELECT  @messageId = inserted.MessageId,
            @ParentId = inserted.ParentId
        FROM inserted

    IF(@ParentId IS NULL)
        BEGIN
            UPDATE [Messages]
                SET Hierarchy = hierarchyid::GetRoot()
                WHERE [Messages].MessageId = @messageId
            RETURN
        END
    ELSE
        BEGIN
            DECLARE @parent hierarchyid
            SELECT @parent = Hierarchy
                FROM   [Messages]
                WHERE  [Messages].MessageId = @ParentId

            DECLARE @lastHierarchy hierarchyid
            SELECT @lastHierarchy = MAX(Hierarchy) 
                FROM [Messages] 
                WHERE Hierarchy.GetAncestor(1) = @parent

            UPDATE [Messages]
                SET Hierarchy = @parent.GetDescendant(@lastHierarchy, NULL)
                WHERE [Messages].MessageId = @messageId
        END
END  

如果我插入诸如id = 2hasparentId = 1id = 3has之类的消息,则parentId = 2具有此层次结构:
id = 1, hierarchy = \
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\

第一个和第二个记录具有正确的层次结构,但下一个没有...... :(

有什么线索吗?

4

1 回答 1

1

这实际上一种正确的层次结构实现。但是,它对批量插入有限制,但这是另一个问题......而且,所有“根”都以或一层深度开始可能是有意义的,因此对话不共享父树。\x

在任何情况下,使用 插入第二个节点id = 4, parentId = 2,它应该看起来像hierarchy = \1\2(它在同一层次结构级别上,但在 之后\1\1)。

hierarchy“字符串”形式显示的值不需要parentId值相关!

于 2012-11-03T03:51:11.923 回答