Comment efficacement la requête et globale d'une base de données SQL normalisée?

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

  •  16-10-2019
  •  | 
  •  

Question

En ce qui concerne plus moyen efficace de renvoyer plusieurs agrégats dans un seul proc stocké

J'ai une application de type e-mail et que vous souhaitez sélectionner tous les messages (boîte de réception) pour un utilisateur. Le problème est que je normalise la partie d'en-tête des e-mails dans le DB de telle sorte que les données à plat entre dans une table de messages et de, à, CC, BCC sont stockés à une autre table.

Quelle est la meilleure façon de sélectionner des messages (en plein - ce qui signifie dénormaliser le message complet), de sorte que chaque enregistrement contient tous les champs pertinents de message, y compris tous les champs de la table des messages et des documents connexes de la table bénéficiaire en rapport avec le message selon la PK / FK relation.

Une chose que je suis accorder un poids sur est l'efficacité de la solution SQL parce que ce sera le code qui est exécuté beaucoup à plusieurs reprises et sera probablement le plus sql d'exécution de la DB ensemble

Pour le contexte est ici une vue de mon schéma DB.

DB SCHEMA

Était-ce utile?

La solution

Voici comment je le ferais. Je l'utilise régulièrement pour placer Coalesce lignes dans les champs delimeted et il a toujours et réalise des échelles bien (aussi longtemps que vous vous rendez compte qu'un sous-requête va toujours causer des succès de la performance).

Si vous ne l'avez pas envie de courir comme une procédure stockée, vous pouvez également réécrire facilement une fonction table.

Une autre approche serait un CTE je suppose, mais je ne suis pas aussi familier avec cette approche de type à partir de zéro.

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

Vous pourriez vous demander comment fonctionne Coalesce lorsqu'il est utilisé de cette manière (je l'ai fait, quand je l'ai vu utilisé). Fondamentalement, il crée une requête récursive retour chaque nouvelle valeur non nulle dans l'ensemble, à son tour, jusqu'à la fin du jeu de retour. En sortant l'autre extrémité vous obtenez une liste délimitée par le coma de tous les résultats en une seule chaîne.

Autres conseils

Je voudrais créer une vue appelée viewInbox qui est mis au point par tous les one-to-one tables de relations. Ce serait ma principale vue de la requête. J'utilise ce point de vue (viewInbox) pour afficher une liste de tous les éléments de la boîte de réception.

Lorsque l'utilisateur exercices vers le bas dans le message, je puis ramener toutes les informations, y compris le one-to-many relations du multiple Pour ce, les CC et BCC .

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top