如何有效地查询和聚合规范化的 SQL 数据库?

kac*_*apy 7 sql-server-2005 query

关于在单个存储过程中返回多个聚合的最有效方法?

我有一个电子邮件类型的应用程序,想为用户选择所有消息(收件箱)。问题是我将电子邮件的标题部分规范化到数据库中,这样平面数据就会进入消息表,而从、到、抄送、密件抄送则存储到另一个表中。

根据 PK/ FK 关系。

我非常重视的一件事是 SQL 解决方案的效率,因为这将是多次执行的代码,并且可能是整个数据库中运行次数最多的 sql

这里的上下文是我的数据库模式的视图。

数据库架构

RTh*_*mas 6

这就是我要做的。我经常使用 Coalesce 将行放入分隔的字段中,它总是能很好地执行和扩展(只要您意识到子查询总是会导致一些性能下降)。

如果您不喜欢将它作为存储过程运行,您也可以轻松地将其重写为表值函数。

我想另一种方法是 CTE,但我对这种从头开始打字的方法并不熟悉。

CREATE PROCEDURE GetMessageById
    @pMessageID int
AS
BEGIN

SET NOCOUNT ON;

Declare @pTo varchar(max)
Declare @pCC varchar(max)
Declare @pBC varchar(max)

SELECT @pTo = COALESCE(@pTo + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 1 /** or whatever the id of TO field is */

SELECT @pCC = COALESCE(@pCC + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 2 /** or whatever the id of CC field is */

SELECT @pBC = COALESCE(@pBC + ', ', '') + [EmailAddress]
FROM MessageRecipient
WHERE MessageID = @pMessageID AND RecipientTypeID = 3 /** or whatever the id of BCC field is */

SELECT Message.*, @pTo as [ToField], @pCC as [CCField], @pBC as [BCCField], (SELECT TOP 1 [EmailAddress] FROM MessageRecipient Where RecipientTypeID = 0 /**<sender id>*/ AND MessageID = @pmessageID) AS [FromField] FROM Message Where Message.ID = @pMessageID

END
GO
Run Code Online (Sandbox Code Playgroud)

您可能会问自己,以这种方式使用 Coalesce 时是如何工作的(我第一次看到它使用时确实如此)。基本上它创建一个递归查询,依次返回集合中的每个后续非空值,直到返回集合结束。从另一端出来,您会得到一个以昏迷分隔的所有结果列表作为单个字符串。


Mic*_*nny 5

我将创建一个名为viewInbox的视图,该视图由所有一对一关系表设计。这将是我的主要查询视图。我会使用这个视图 (viewInbox) 来显示所有收件箱项目的列表。

当用户向下钻取到消息,然后,我会带回所有包括信息一到许多从多到的,CC的和BCC的关系。

  • @LazyDBA - 我认为 viewInbox 是“非规范化的”。 (2认同)