金沙棋牌app手机下载

当前位置:金沙棋牌 > 金沙棋牌app手机下载 > 有关站内信的数据库设计,NET中发送电子邮件的

有关站内信的数据库设计,NET中发送电子邮件的

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-09-14 22:07

站内信:网站运营人员可以向单个(单发)或多个(群发)用户推送消息,站内信其实就是向数据库中插入一条条记录。

  前几日,发布了博客“群发“站内信”的实现”,得到广大网友呼应,在此表示感谢。

  在很多网站系统(如CMS系统,SNS系统等),都有“站内信”的功能。

首先、导入命名空间:

数据库设计:

message【站内信发件箱表】{每次运营人员发送一条站内信(无论是单发或是群发)就会在发件箱表中添加一条记录}

 图片 1

 表字段:ID、SendID、RecID、MessageID、Statue、DateTime

messagetext【站内信发件内容表】{每次运营人员发送站内信的内容就会保存到站内信发件内容表中}

图片 2

表字段:ID、Title、Message、PData

messageuserinfo【站内信接收箱表】{用户站内信收件箱}

图片 3

表字段:ID、SendID、RecID、MessageID、Statue、DateTime

 

  看了网友的留言。发现大家对文中的前两种情况没有什么异议,对第三种方案争议颇多。我在此再把我的第三种情况详细的阐述一下,和大家交流。另外,本文的主体主要放在“群发”(也就是点到面),至于“单发”(点到点),不在本文的讨论之列。

  “站内信”不同于电子邮件,电子邮件通过专门的邮件服务器发送、保存。而“站内信”是系统内的消息,说白了,“站内信”的实现,就是通过数据库插入记录来实现的。

 代码如下 复制代码
using System.Net.Mail;  

业务逻辑:在运营人员发送了一条站内信后,当用户再次登录时就会刷新历史站内信,而那些不活跃的用户就不会更新站内信。

场景:运营人员向某个(单发)或多个(群发)用户发送站内信

添加发件内容:向messagetext站内信发件内容表中添加一条内容记录 {这里先添加messagetext站内信发件内容表产生一条记录,后面message站内信发件箱表中才有MessageID可以关联}

添加发件人发件记录:向message站内信发件箱表中添加一条发送记录 {备注:如果是单发RecID则是指定用户的UserID,如果是群发RecID则是0。(0表示所有用户)}

用户登录时刷新与自己有关的站内信,并将数据添加到messageuserinfo站内信接收箱表

  1. 查询条件:【发件人不是自己】并且【收件人是自己或者收件人是所有人】并且【自己收件表中不存在的记录】

    select m.id from Message as m where (m.recid='所有人' or m.recid='自己的ID') and m.sendid!='自己的ID' and m.MessageID not in (select u.messageid from MessageUserInfo as u  where u.recid='自己的ID')
    

      

  2. 将相关的站内信消息添加到自己的收件表中,并标记未读。

    1.   将上面【查询条件】中查询出来的id信息用做查询message站内信发件箱表的条件

      select * from message  where id=上面的m.id
      

        

    2. 将获取到message站内信发件箱表数据添加到messageuserinfo站内信接收箱表

  3. 查询出自己的站内信记录

    select u.ID,u.RecID,m.Title,m.Message,u.Statue,m.PDate from messageuserinfo as u join messagetext as m on u.MessageID = m.ID where u.RecID='自己的ID'
    

      

     

  先看看,第三种情况。站内的用户是大量级的(上百万)。

  “站内信”有两个基本功能。一:点到点的消息传送。用户给用户发送站内信;管理员给用户发送站内信。二:点到面的消息传送。管理员给用户(指定满足某一条件的用户群)群发消息。点到点的消息传送很容易实现,本文不再详述。下面将根据不同的情况,来说说“站内信”的群发是如何实现的。

定义发送电子邮件的方法[网上很多不同的,可以对比着看一下,WinForm的也适用]:

  经过考虑,表设计修正如下

  第一种情况,站内的用户是少量级别的。(几十到上百)

 代码如下 复制代码
/// <summary>
/// 发送电子邮件
/// </summary>
/// <param name="MessageFrom">发件人邮箱地址</param>
/// <param name="MessageTo">收件人邮箱地址</param>
/// <param name="MessageSubject">邮件主题</param>
/// <param name="MessageBody">邮件内容</param>
/// <returns></returns>
public bool Send(MailAddress MessageFrom, string MessageTo, string MessageSubject, string MessageBody)
{
 MailMessage message = new MailMessage();
 message.From = MessageFrom;
 message.To.Add(MessageTo); //收件人邮箱地址可以是多个以实现群发
 message.Subject = MessageSubject;
 message.Body = MessageBody;
 message.IsBodyHtml = true; //是否为html格式
 message.Priority = MailPriority.Normal; //发送邮件的优先等级
 SmtpClient sc = new SmtpClient();
 sc.Host = "smtp.qq.com"; //指定发送邮件的服务器地址或IP
 sc.Port = 25; //指定发送邮件端口
 //指定登录服务器的用户名和密码(发件人的邮箱登陆密码)
 sc.Credentials = new System.Net.NetworkCredential("【发件箱地址】", "【www.111cn.net发件箱密码】");
 try
 {
  sc.Send(message); //发送邮件
 }
 catch
 {
  return false;
 }
 return true;
}  

 

  这种情况,由于用户的数量非常少,因此,没有必要过多的考虑数据库的优化,采用简单的表格,对系统的设计也来的简单,后期也比较容易维护,是典型的用空间换时间的做法。

义发送电子邮件的方法

  表名:Message

  数据库的设计如下:表名:Message

调用定义的方法,实现发送邮件:

  ID:编号;RecID:接受者编号;MessageID:站内信编号;Statue:站内信的查看状态;

  ID:编号;SendID:发送者编号;RecID:接受者编号(如为0,则接受者为所有人);Message:站内信内容;Statue:站内信的查看状态;PDate:站内信发送时间;

 代码如下 复制代码
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ForMail(string name, string mail)
{
 try
 {
  //string email = txtemail.Text.Trim();
  MailAddress MessageFrom = new MailAddress("【发件箱地址】"); //发件人邮箱地址
                  string MessageTo = mail; //收件人邮箱地址
  string MessageSubject = bs.HtmlEncode(邮件主题);
  //邮件内容 (一般是一个网址链接,生成随机数加验证id参数,点击去网站验证。)";
  string MessageBody = "" + content1.Value.Trim() + "";
  if (Send(MessageFrom, MessageTo, MessageSubject, MessageBody))
  {
   //Response.Write("发送邮件成功");
  }
  else
  {
   //Response.Write("发送邮件失败");
  }
 }
 catch
             {
  //ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>alert('客户信息删除失败')</script>");
 }
}  

  表名:MessageText 

  如果,某一个管理员要给所有人发站内信,则先遍历用户表,再按照用户表中的所有用户依次将站内信插入到Message表中。这样,如果有56个用户,则群发一条站内信要执行56个插入操作。这个理解上比较简单,比较耗损空间。

调用方法发送邮件  

  ID:编号;SendID:发送者编号;Message:站内信的内容;PDate:站内信发送时间;

  某一个用户登陆后,查看站内信的语句则为:

不同邮箱的smtp地址都不一样、需要比如QQ的是smtp.qq.com、163的是smtp.163.com

 

  Select * FROM Message Where RecID=‘ID’ OR RecID=0

更多详细内容请查看:

  这样,管理员(假设ID=1)给所有的用户发一封站内信。就在MessageText表中插入一条记录。例如:

  第二种情况,站内的用户中量级别的(上千到上万)。

  ID:4;SendID=1;Message=Good;PDate:2010-4-9

  如果还是按照第一种情况的思路。那发一条站内信的后果基本上就是后台崩溃了。因为,发一条站内信,得重复上千个插入记录,这还不是最主要的,关键是上千乃至上万条记录,Message字段的内容是一样的,而Message有大量的占用存储空间。比方说,Message字段有100个汉字,占用200个字节,那么5万条,就占用200×50000=10000000个字节=10M。简单的一份站内信,就占用10M,这还让不让人活了。

 

  因此,将原先的表格拆分为两个表,将Message的主体放在一个表内,节省空间的占用

  某个用户(假设ID=7),登陆系统后,发现在MessageText的表中,有ID=4的记录,并且在Message中没有RecID=7且MessageID=4的记录,说明这条记录这个用户没有读过,给个提示信息给用户,提示用户看站内信。注意,此时仍然没有在Message中插入记录。一旦该用户点击查看该站内信的时候,在Message中插入一条记录,如:

  数据库的设计如下:

  ID:55;RecID=7;MessageID=4;Statue=已读

  表名:Message

  如果该用户删除这条站内信,则实际上是修改上面这条记录:

  ID:编号;SendID:发送者编号;RecID:接受者编号(如为0,则接受者为所有人);MessageID:站内信编号;Statue:站内信的查看状态;

  ID:55;RecID=7;MessageID=4;Statue=删除

  表名:MessageText 

  这样一来,这个用户下次登陆的时候,由于Message表中有相应的记录,也不会提示用户看站内信。

  ID:编号;Message:站内信的内容;PDate:站内信发送时间;

 

  在管理员发一封站内信的时候,执行两步操作。先在MessageText表中,插入站内信的内容。然后在Message表中给所有的用户插入一条记录,标识有一封站内信。

  有网友质疑,为何删除的时候,只是标记“删除”,这样,长此以往,不是浪费大量的空间吗?这个网友说的也有道理。不过,我们还是要分析具体的情况。

  这样的设计,将重复的站内信的主体信息(站内信的内容,发送时间)放在一个表内,大量的节省存储空间。不过,在查询的时候,要比第一种情况来的复杂。

  当网站的用户达到百万级的时候,其中的“活跃用户”(参看上文的介绍)可能只占其中的一小部分。

  第三种情况,站内的用户是大量级的(上百万),并且活跃的用户只占其中的一部分。

  假设,网站用户200万,其中活跃用户40万。

  大家都有这样的经历,某日看一个网站比较好,一时心情澎湃,就注册了一个用户。过了一段时间,由于种种原因,就忘记了注册时的用户名和密码,也就不再登陆了。那么这个用户就称为不活跃的。从实际来看,不活跃的用户占着不小的比例。

  一封站内信,在MessageText中有一条记录,40万活跃用户都看了站内信(其实,这也不大可能,有不少的人是不看站内信的)。在Message中插入了40万条记录。以后,不管是阅读或者是删除,在Message中保留了这40万条记录。

  我们以注册用户2百万,其中活跃用户只占其中的10%。

 

  就算是按照第二种的情况,发一封“站内信”,那得执行2百万个插入操作。但是其中的有效操作只有10%,因为另外的90%的用户可能永远都不会再登陆了。

  好,如果不采用这种办法,在群发的时候,往Message中插入200万记录,40万活跃用户都看了信,并且都勤快的删除了站内信(这是不大可能的),Message中还是保留了160万条记录。因为,这些不活跃的用户可能永远都不会登陆了。那40万条记录(最坏的情况,因为如果有人不看站内信,就不会生成记录)和160万条记录(最好的情况,因为不是每个用户都会删除站内信。)相比,那个更加节省空间呢?

  在这种情况下,我们还得把思路换换。

 

  数据库的设计和第二种情况一样:

  站内信的设计,要根据你的受众群的具体情况而定,如果你的受众群活跃度接近100%,并且每人都很勤快,我的设计当然有问题。可实际中这个理想状态几乎是不可能出现的。

  表名:Message

  

  ID:编号;SendID:发送者编号;RecID:接受者编号(如为0,则接受者为所有人);MessageID:站内信编号;Statue:站内信的查看状态;

  有网友提出,如果站内信的对象不是全体而是一部分呢?抱歉,这个也不在本文讨论之列,你可以对我的表进行扩展,以达到你的要求。

  表名:MessageText 

 

  ID:编号;Message:站内信的内容;PDate:站内信发送时间;

  感谢各位网友的交流。我在此想说的是,我们设计一个系统,必须得结合实际情况,根据实际情况来制定,比能达到一个比较理想的状况。

  管理员发站内信的时候,只在MessageText插入站内信的主体内容。Message里不插入记录。

  那么,用户在登录以后,首先查询MessageText中的那些没有在Message中有记录的记录,表示是未读的站内信。在查阅站内信的内容时,再将相关的记录插入到Message中。

  这个方法和第二种的比较起来。如果,活跃用户是100%。两者效率是一样的。而活跃用户的比例越低,越能体现第三种的优越来。只插入有效的记录,那些不活跃的,就不再占用空间了。

  以上,是我对群发“站内信”的实现的想法。也欢迎各位提出自己的建议,大家互相借鉴,共同进步。

本文由金沙棋牌发布于金沙棋牌app手机下载,转载请注明出处:有关站内信的数据库设计,NET中发送电子邮件的

关键词:

上一篇:没有了

下一篇:没有了