所提出的方法都不是存储它的最佳优化方法。最好的方法是在会话的基础上使用动态表的条带段。
这是具有范式的原型:-
- 与多个参与者进行对话。
- 确认聊天的选项。
- 操作更新选项。
- 发布附件的选项。
- 共享地图坐标的选项,例如您当前的位置。
- 离开聊天的选项。
类型
Coordinates(
lat FLOAT( 10, 6 ) NOT NULL ,
lng FLOAT( 10, 6 ) NOT NULL
)
架构
dbo.User(UserId,<..Details..>)
dbo.Conversation(ConversationId,Title,CreationDate,LastActivityDate)
索引:LastActivityDate、ConversationId
dbo.Participants(ConversationId,UserId)
表的集合 - 动态创建
msg.msg_*ConversationId*(MessageId,FromUserId,Message,Attachment,LocationCoordinates,Action,LogDate,AcknowledgeDate)
抽象
usp_TouchMessage(@Which):
if (not exists (select 1 from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA+'.'+TABLE_NAME = 'msg.msg_'+CAST(@Which as nvarchar(max)))
begin
@dynamic_sql = 'create table msg.msg_'+CAST(@Which as nvarchar(max))+' (MessageId uniqueidentifier,FromUserId uniqueidentifier,Message nvarchar(max),Attachment BLOB,LocationCoordinates Coordinates,Action nvarchar(max),LogDate DateTime, AcknowledgeDate DateTime);';
exec(@dynamic_sql);
@dynamic_sql = 'CREATE TRIGGER msg.trig_msg_'+CAST(@Which as nvarchar(max))+' ON msg.msg_'+CAST(@Which as nvarchar(max))+' AFTER INSERT AS Delete From msg.msg_'+CAST(@Which as nvarchar(max))+' where MessageId in (Select MessageId,ROW_NUMBER() OVER (order by LogDate Desc,AcknowledgeDate Desc,MessageId Desc) RN from msg.msg_'+CAST(@Which as nvarchar(max))+') where RN>=5000';
exec(@dynamic_sql);
end
usp_GetParticipants(@Where) :
Select User.UserId,User.FullName
from Participants
inner join Users on (
Participants.UserId = Users.UserId
And Participants.ConversationId = @Where
);
usp_AddParticipants(@Who, @Where) :
insert into Participants(ConversationId,UserId) values (@Where, @Who);
@action = ( select User.FullName + ' has joined the chat' from User where User.UserId = @Who );
update Conversation set LastActivityDate = GETUTCDATE() where ConversationId = @conversation_id;
exec usp_TouchMessage(@Where);
@dynamic_sql = 'insert into msg.msg_'+CAST(@Where as nvarchar(max))+' (MessageId,FromUserId,Action,LogDate) values (NewId(),@Who,@Action,GETUTCDATE())';
sp_executesql @dynamic_sql, N'@Who uniqueidentifier,@Action nvarchar(max)', @Who = @Who, @Action = @Action;
usp_GetConversationList() :
With Participation As (
Select User.UserId,User.FullName,Participants.ConversationId
from Participants
inner join Users on (Participants.UserId = Users.UserId)
) select Conversation.*,
(STUFF((
SELECT ',' + CAST([FullName] AS nvarchar(max))
FROM Participation
WHERE (Participation.ConversationId = Conversation.ConversationId)
FOR XML PATH ('')
),1,1,'')) ParticipantList
from Conversation
order by Conversation.LastActivityDate;
usp_GetConversationById(@Which,@Lite = 0,@Page = 1) :
Select User.UserId,User.FullName
from Participants
inner join Users on (Participants.UserId = Users.UserId and Participants.ConversationId = @Which);
@dynamic_sql = 'select * from
(select u.UserId,u.FullName,m.MessageId,'
+(case when @Lite=1 then 'm.Message,m.LocationCoordinates,m.Attachment,m.Action,' else '' end)
+'m.LogDate,m.AcknowledgeDate, ROW_NUMBER() Over (order by m.LogDate Desc,m.AcknowledgeDate Desc,m.MessageId Desc) RN
From msg.msg_'+CAST(@Which AS nvarchar(max))+' m
inner join User u on (m.FromUserId = u.UserId)
) tmp
where RN Between ((@Page-1)*20+1) AND (@Page*20+1)
';
sp_executesql @dynamic_sql, N'@Page bigint', @Page = @Page;
If @Page = 1 And @Lite=0
begin
@dynamic_sql = 'update msg.msg_'+CAST(@Which as nvarchar(max))+' Set AcknowledgeDate = GETUTCDATE() where AcknowledgeDate is null and FromUserId <> @Who';
sp_executesql @dynamic_sql, N'@Who uniqueidentifier', @Who = @Who;
end
usp_GetConversation(@Who,@WithWhome,@Lite = 0,@Page = 1) :
@conversation_id = (
Select top 1 ConversationId
from Participants self
inner join Participants partner
on ( self.ConversationId = partner.ConversationId and self.UserId = @Who and partner.UserId = @WithWhome)
where (Select count(1) from Participants where ConversationId = self.ConversationId) = 2
);
if(@conversation_id is not null)
then
exec usp_GetConversationById(@conversation_id, @Lite, @Page);
end
usp_PostConversationById(@Who,@Which,@WhatMessage,@WhichLocation,@WhatAttachment) :
update Conversation set LastActivityDate = GETUTCDATE() where ConversationId = @Which;
exec usp_TouchMessage(@Which);
@dynamic_sql = 'insert into msg.msg_'+CAST(@Which as nvarchar(max))+' (MessageId,FromUserId,Message,Attachment,LocationCoordinates,LogDate) values (NewId(),@Who,@WhatMessage,@WhichLocation,@WhatAttachment,GETUTCDATE())';
sp_executesql @dynamic_sql, N'@Who uniqueidentifier,@WithWhome uniqueidentifier,@WhatMessage nvarchar(max),@WhichLocation Coordinates,@WhatAttachment BLOB', @Who = @Who, @WhatMessage = @WhatMessage, @WhichLocation = @WhichLocation, @WhatAttachment = @WhatAttachment;
usp_PostConversation(@Who,@WithWhome,@WhatMessage,@WhichLocation,@WhatAttachment) :
@conversation_id = (
Select top 1 ConversationId
from Participants self
inner join Participants partner
on ( self.ConversationId = partner.ConversationId and self.UserId = @Who and partner.UserId = @WithWhome)
where (Select count(1) from Participants where ConversationId = self.ConversationId) = 2
);
if(@conversation_id is not null)
then
@conversation_id = newid()
insert into Conversation(ConversationId,CreationDate) values (@conversation_id,GETUTCDATE());
exec usp_AddParticipants(@Who,@conversation_id);
exec usp_AddParticipants(@WithWhome,@conversation_id);
end
exec usp_PostConversationById(@Who,@conversation_id,@WhatMessage,@WhichLocation,@WhatAttachment);
usp_UpdateConversationAlias(@Who,@Which,@WithWhat) :
@action = ( select User.FullName + ' has changed title'+isnull(' from <b>'+Conversation.Title+'</b>','')+isnull(' to <b>'+@WithWhat+'</b>','') from User inner join Conversation on (Conversation.ConversationId = @Which and User.UserId = @Who));
update Conversation set LastActivityDate = GETUTCDATE(), Title = @WithWhat where ConversationId = @conversation_id;
if (not exists (select 1 from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA+'.'+TABLE_NAME = 'msg.msg_'+CAST(@Which as nvarchar(max)))
exec usp_TouchMessage(@Which);
@dynamic_sql = 'insert into msg.msg_'+CAST(@Which as nvarchar(max))+' (MessageId,FromUserId,Action,LogDate) values (NewId(),@Who,@Action,GETUTCDATE())';
sp_executesql @dynamic_sql, N'@Who uniqueidentifier,@Action nvarchar(max)', @Who = @Who, @Action = @Action;
usp_LeaveConversation(@Who,@Which) :
delete from Participants where ConversationId = @Where and UserId = @Who;
if(not exists (Select 1 From Participants Where ConversationId = @Which))
begin
@dynamic_sql = 'drop table msg.msg_'+CAST(@Which as nvarchar(max))+';
exec @dynamic_sql;
delete from Conversation where ConversationId = @Which;
end
else
begin
@action = ( select User.FullName + ' has left the chat' from User where User.UserId = @Who );
update Conversation set LastActivityDate = GETUTCDATE() where ConversationId = @conversation_id;
exec usp_TouchMessage(@Which);
@dynamic_sql = 'insert into msg.msg_'+CAST(@Which as nvarchar(max))+' (MessageId,FromUserId,Action,LogDate) values (NewId(),@Who,@Action,GETUTCDATE())';
sp_executesql @dynamic_sql, N'@Who uniqueidentifier,@Action nvarchar(max)', @Who = @Who, @Action = @Action;
end