Как эффективно запросить и агрегировать нормализованный SQL DB?

dba.stackexchange https://dba.stackexchange.com/questions/2569

  •  16-10-2019
  •  | 
  •  

Вопрос

В связи с Наиболее эффективный способ вернуть несколько агрегатов в одном хранилищем Proc?

У меня есть приложение типа электронной почты, и я хочу выбрать все сообщения (входящие) для пользователя. Проблема заключается в том, что я нормализую заголовок части электронных писем в БД, так что плоские данные входят в таблицу сообщений, а от, от, CC, BCC хранятся в другой таблице.

Как лучше всего выбрать сообщения (в полном объеме - это означает, что денормализуйте полное сообщение), чтобы каждая запись содержит все соответствующие поля сообщения, включая все поля таблицы сообщений и любые связанные записи из таблицы получателей, связанных с сообщением в соответствии с PK/ FK отношения.

Одна вещь, на которую я придаю большой вес, - это эффективность решения SQL, потому что это будет код, который будет выполняться много раз и, вероятно, будет самым большим SQL из всего ББ

Для контекста здесь является представление о моей схеме DB.

DB SCHEMA

Это было полезно?

Решение

Вот как я бы это сделал. Я регулярно использую Coalsce, чтобы поместить ряды в поля делиметирования, и он всегда работает и хорошо масштабируется (если вы понимаете, что подзадность всегда вызовет какой -то удар).

Если вам не нравилось запускать его в качестве хранимой процедуры, вы также можете легко переписать в качестве таблицы.

Я полагаю, что другой подход будет 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

Вы можете спросить себя, как Coalesce работает при использовании таким образом (я сделал, когда я впервые увидел его использован). В основном он создает рекурсивный запрос, возвращающий каждое последующее неверное значение в наборе, в свою очередь, до конца возврата. Выходя на другой конец, вы получите список по разграниченному делителю комы в качестве одной строки.

Другие советы

Я бы создал представление под названием ViewInbox что разработано всеми один к одному Таблицы отношений. Это был бы мой главный взгляд на запрос. Я бы использовал этот представление (ViewInbox) для отображения списка всех элементов входящих.

Когда пользователь тренировки вниз В сообщение я бы вернул всю информацию, включая один ко многим Отношения от множественных до CC и BCC.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top