如何使用 Entity Framework 在 C# 中为 Messaging/Chatting 系统建模
How to model a Messaging/Chatting system in C# with Entity Framework
我有一个简单的问题
我正在开发一个聊天系统服务,但我遇到了一些有趣的事情。
我目前是这样操作的:
第一个 table :
[Messages] :
SenderID(user),
RecipientID(user),
Content(string)
当然,每次用户向其他用户发送消息时,我都会将其添加到 table。但是我想到如果一个table有一百万行,它会变得一团糟
所以我想到了另一种方式:
第一个 Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
第二个table:
[Messages] in which I have
ConversationID,
Content(string)
基本上,我想问的是,我应该使用哪种配置?
这两种解决方案都适用于简单的消息传递。这里的真正问题是,在相同的两个用户之间是否应该存在不止一个消息对话上下文。
如果两个用户每次聊天时总是在同一个会话范围内交谈context/history,那么您的第一个解决方案就足够了。将此场景想象成 Skype 聊天。随着时间的推移,这只是一场漫长的谈话。
如果他们开始聊天时对话上下文发生变化(即,他们的聊天记录在两天不同的对话之间从未真正持续存在),则解决方案二更有意义。将这种情况想象成两个用户之间的电子邮件。第二天我可以给同一个人写另一封电子邮件,但这是不同的对话。
对于解决方案二,您还需要将 USER 添加到第二个 table 以跟踪哪个用户在对话中发送了消息:
第一个 Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
第二个table:
[Messages]
ConversationID,
Content(string)
USER(user)
总而言之,仅仅因为 table 会有数百万行并不意味着它不是正确的做法。在这种情况下,它只取决于您的应用程序的要求。
这里还有一个思路,Store一个“消息”的概念。无论是电子邮件、文本、短信还是声音文件。这是您存储消息文本和/或其他元数据的地方。将“消息”视为释放对讲机上的停止通话按钮以结束传输的所有内容,以及直到开始和停止的所有内容都存储在“消息”中。由于用户正在回复来自先前一方的通话请求的“消息”,因此该消息可能与其他消息相关联。
如果你想让整个关系变得简单,那么你可以记录发送给用户的“消息”,“收件箱”和用户发送的消息,“发件箱”。这是当今消息传递心态的代名词。
留言
MessageID,
Subject,
Content
...
已收到消息
MessageReceivedID,
UserID,
FromUserID,
MessageID,
DateReceived,
DateRead,
消息已发送
MessageSentID,
UserID,
MessageID,
DateSent,
DeletedStatusID
下面的方法应该可以解决您的问题。这是聊天和消息传递的良好基础,通过聊天,您可以从客户端轮询最近的消息并在直观的 UI.
上打耳光
留言
Message {
MessageId,
FromId, -- Foreign key User.UserId
ToId, -- Foreign key User.UserId
Subject,
Content,
Attachment, -- can be null or default to a 0
DateReceived, -- can be null or default to 1901 or sumin'
DateRead
...
}
用户
User {
UserId
UserName
...
}
查询
Inbox = Message where ToId = Me.UserId
Sent = Message where FromId = Me.UserId
Conversation = Group by Subject
Attachment = (Simple = Path to attachment file. || Better = DocumentId)
附件
Document {
int DocumentId,
int DocTypeId,
virtual DocumentType DocumentType,
string FileName,
int UserId,
string mimeType,
float fileSize,
string storagePath,
int OrganizationId,
string fileHash,
string ipAddress,
DateTime DateCreated = DateTime.Now;
}
然后你运行进入群聊的问题。您是向组中的每个收件人发送消息,还是创建每个收件人都可以访问的单个消息?
但我们保持简单。
我有一个简单的问题
我正在开发一个聊天系统服务,但我遇到了一些有趣的事情。
我目前是这样操作的:
第一个 table :
[Messages] :
SenderID(user),
RecipientID(user),
Content(string)
当然,每次用户向其他用户发送消息时,我都会将其添加到 table。但是我想到如果一个table有一百万行,它会变得一团糟
所以我想到了另一种方式:
第一个 Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
第二个table:
[Messages] in which I have
ConversationID,
Content(string)
基本上,我想问的是,我应该使用哪种配置?
这两种解决方案都适用于简单的消息传递。这里的真正问题是,在相同的两个用户之间是否应该存在不止一个消息对话上下文。
如果两个用户每次聊天时总是在同一个会话范围内交谈context/history,那么您的第一个解决方案就足够了。将此场景想象成 Skype 聊天。随着时间的推移,这只是一场漫长的谈话。
如果他们开始聊天时对话上下文发生变化(即,他们的聊天记录在两天不同的对话之间从未真正持续存在),则解决方案二更有意义。将这种情况想象成两个用户之间的电子邮件。第二天我可以给同一个人写另一封电子邮件,但这是不同的对话。
对于解决方案二,您还需要将 USER 添加到第二个 table 以跟踪哪个用户在对话中发送了消息:
第一个 Table :
[Conversation]
ConversationID,
USER1(user),
USER2(user)
第二个table:
[Messages]
ConversationID,
Content(string)
USER(user)
总而言之,仅仅因为 table 会有数百万行并不意味着它不是正确的做法。在这种情况下,它只取决于您的应用程序的要求。
这里还有一个思路,Store一个“消息”的概念。无论是电子邮件、文本、短信还是声音文件。这是您存储消息文本和/或其他元数据的地方。将“消息”视为释放对讲机上的停止通话按钮以结束传输的所有内容,以及直到开始和停止的所有内容都存储在“消息”中。由于用户正在回复来自先前一方的通话请求的“消息”,因此该消息可能与其他消息相关联。
如果你想让整个关系变得简单,那么你可以记录发送给用户的“消息”,“收件箱”和用户发送的消息,“发件箱”。这是当今消息传递心态的代名词。
留言
MessageID,
Subject,
Content
...
已收到消息
MessageReceivedID,
UserID,
FromUserID,
MessageID,
DateReceived,
DateRead,
消息已发送
MessageSentID,
UserID,
MessageID,
DateSent,
DeletedStatusID
下面的方法应该可以解决您的问题。这是聊天和消息传递的良好基础,通过聊天,您可以从客户端轮询最近的消息并在直观的 UI.
上打耳光留言
Message {
MessageId,
FromId, -- Foreign key User.UserId
ToId, -- Foreign key User.UserId
Subject,
Content,
Attachment, -- can be null or default to a 0
DateReceived, -- can be null or default to 1901 or sumin'
DateRead
...
}
用户
User {
UserId
UserName
...
}
查询
Inbox = Message where ToId = Me.UserId
Sent = Message where FromId = Me.UserId
Conversation = Group by Subject
Attachment = (Simple = Path to attachment file. || Better = DocumentId)
附件
Document {
int DocumentId,
int DocTypeId,
virtual DocumentType DocumentType,
string FileName,
int UserId,
string mimeType,
float fileSize,
string storagePath,
int OrganizationId,
string fileHash,
string ipAddress,
DateTime DateCreated = DateTime.Now;
}
然后你运行进入群聊的问题。您是向组中的每个收件人发送消息,还是创建每个收件人都可以访问的单个消息?
但我们保持简单。