我正在信息系统中开发一个消息中心,今天用户Eric建议使用hierarchyid数据类型来跟踪消息回复,因为目标是显示为Outlook或Gmail对话。
为了简化,我在我的数据库表中消息:
MessageId int PK
ReplyToId int FK null
Subject varchar
Body varchar
Hierarchy hierarchyid
插入新邮件时,我会触发更新。
我插入了一条新消息,层次结构为空,因为它是第一条消息,而不是回复。
如果尝试插入对该消息的回复,则hierarchyid仍为null ... :(
我的触发器:
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
我做错了什么?
另一点,我已经读过关于索引的内容,但深度优先不适合因为有许多空值,因为来自会话的第一条消息具有空值,而bread-first是最好的索引类型有更好的表现?或者我可以丢弃这个索引?
提前致谢!
编辑:
我已更新了触发器,但没有以正确的方式执行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 = 2
有parentId = 1
的消息,而id = 3
parentId = 2
有id = 1, hierarchy = \
这样的层次结构:
id = 2, hierarchy = \1\
id = 3, hierarchy = \1\1\
{{1}}
第一个和第二个记录具有正确的层次结构,但下一个记录没有... :(
有任何线索吗?
答案 0 :(得分:1)
实际上是一个正确的层次结构实现。但是,它对批量插入有局限性,但这是另一个问题..同样,开始所有“根”与\x
或一个深度一样,这样的对话可能是有意义的。所以对话不要共享父树。
在任何情况下,插入带有id = 4, parentId = 2
的第二个节点,它应该看起来像hierarchy = \1\2
(它位于同一层次结构级别,但在\1\1
之后)。
hierarchy
“字符串”表单中显示的值不需要与parentId
值相关联!