android短彩信数据库设计源码解析(一)

本文详细介绍了短信和彩信数据库的设计思路,包括如何通过触发器更新会话信息、检查未读消息状态及统计消息数量等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.youkuaiyun.com/droyon/article/details/8724403

维护短彩信很长时间了,终于想写点什么了,那就从数据库开始吧!不当之处,欢迎指正。

关于LEFT_JOIN,INNER_JOIN等数据库知识,大家可以访问W3SCHOOL。

MmsSmsDatabaseHelper.java

1、首先看一下私有静态常量。这些静态常量在构建数据库触发器,构建数据表时会用到。

private static final String SMS_UPDATE_THREAD_READ_BODY =
                        "  UPDATE threads SET read = " +
                        "    CASE (SELECT COUNT(*)" +
                        "          FROM sms" +
                        "          WHERE " + Sms.READ + " = 0" +
                        "            AND " + Sms.THREAD_ID + " = threads._id)" +
                        "      WHEN 0 THEN 1" +
                        "      ELSE 0" +
                        "    END" +
                        "  WHERE threads._id = new." + Sms.THREAD_ID + "; ";
大体是这样,里面内嵌了一个函数,函数内容是,首先查询sms数据表中Sms.THREAD_ID的值为threads._id的所有行,再次找出这些行中Sms.READ的值为0的行,统计其行数目。如果行数目为0,则输出1,否则输出0.将输出的值赋给threads数据表_id值为new.Sms.THREAD_ID所对应的行中的read字段。

说白了就是检查短信数据库中是否存在未读短信。

2、

private static final String UPDATE_THREAD_COUNT_ON_NEW =
                        "  UPDATE threads SET message_count = " +
                        "     (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
                        "      ON threads._id = " + Sms.THREAD_ID +
                        "      WHERE " + Sms.THREAD_ID + " = new.thread_id" +
                        "        AND sms." + Sms.TYPE + " != 3) + " +
                        "     (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
                        "      ON threads._id = " + Mms.THREAD_ID +
                        "      WHERE " + Mms.THREAD_ID + " = new.thread_id" +
                        "        AND (m_type=132 OR m_type=130 OR m_type=128)" +
                        "        AND " + Mms.MESSAGE_BOX + " != 3) " +
                        "  WHERE threads._id = new.thread_id; ";

内嵌了一个搜索体。搜索体的作用是找出sms数据表中,特定thread_id值对应的,并且Sms.TYPE 不等于3(草稿信息的类型)的信息数目。然后加上      彩信数据表pdu表中,特定thread_id对应的信息,并且信息类型等于132(接收的彩信,已下载彩信内容的类型)和130(接收的彩信,没下载前的类型),以及128(发送的彩信)。并且message_box不等于3(草稿信息的类型)。

说白了,就是将短信和彩信中信息的数据加在一起,存到threads数据表的message_count字段中。

3、

private static final String UPDATE_THREAD_COUNT_ON_OLD =
                        "  UPDATE threads SET message_count = " +
                        "     (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
                        "      ON threads._id = " + Sms.THREAD_ID +
                        "      WHERE " + Sms.THREAD_ID + " = old.thread_id" +
                        "        AND sms." + Sms.TYPE + " != 3) + " +
                        "     (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
                        "      ON threads._id = " + Mms.THREAD_ID +
                        "      WHERE " + Mms.THREAD_ID + " = old.thread_id" +
                        "        AND (m_type=132 OR m_type=130 OR m_type=128)" +
                        "        AND " + Mms.MESSAGE_BOX + " != 3) " +
                        "  WHERE threads._id = old.thread_id; ";
和上面基本类似,不同在最后的where判断条件上
WHERE threads._id = new.thread_id;
WHERE threads._id = old.thread_id;

一个new,一个old很能说明问题,也就是说,这两个常量,一个用在处理新插入信息,一个处理旧的信息。

4、

private static final String SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
                        "BEGIN" +
                        "  UPDATE threads SET" +
                        "    date = (strftime('%s','now') * 1000), " +
                        "    snippet = new." + Sms.BODY + ", " +
                        "    snippet_cs = 0" +
                        "  WHERE threads._id = new." + Sms.THREAD_ID + "; " +
                        UPDATE_THREAD_COUNT_ON_NEW +
                        SMS_UPDATE_THREAD_READ_BODY +
                        "END;";

这个常量用在处理那些新更新的数据,更新threads数据表的date字段、snippet字段(信息会话列表中,显示最新信息的部分提示),snippet_cs字段。然后使用我们前面介绍的两个静态常量。

说白了,在更新sms数据表时,触发更新threads数据表。

5、

private static final String PDU_UPDATE_THREAD_CONSTRAINTS =
                        "  WHEN new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF +
                        "    OR new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND +
                        "    OR new." + Mms.MESSAGE_TYPE + "=" +
                        PduHeaders.MESSAGE_TYPE_SEND_REQ + " ";
这个静态常量字符串的意思是说,信息类型是发送的彩信或者接收的彩信类型,或者接收的彩信、但数据未下载的信息三种类型。

6、

private static final String PDU_UPDATE_THREAD_READ_BODY =
                        "  UPDATE threads SET read = " +
                        "    CASE (SELECT COUNT(*)" +
                        "          FROM " + MmsProvider.TABLE_PDU +
                        "          WHERE " + Mms.READ + " = 0" +
                        "            AND " + Mms.THREAD_ID + " = threads._id " +
                        "            AND (m_type=132 OR m_type=130 OR m_type=128)) " +
                        "      WHEN 0 THEN 1" +
                        "      ELSE 0" +
                        "    END" +
                        "  WHERE threads._id = new." + Mms.THREAD_ID + "; ";
和短信一样,计算彩信中是否存在未读信息,如果存在在threads数据表中置标志为。检索的彩信仅仅是发送或者接收也就是5中所描述的三种彩信。

7、

private static final String PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
                        "BEGIN" +
                        "  UPDATE threads SET" +
                        "    date = (strftime('%s','now') * 1000), " +
                        "    snippet = new." + Mms.SUBJECT + ", " +
                        "    snippet_cs = new." + Mms.SUBJECT_CHARSET +
                        "  WHERE threads._id = new." + Mms.THREAD_ID + "; " +
                        UPDATE_THREAD_COUNT_ON_NEW +
                        PDU_UPDATE_THREAD_READ_BODY +
                        "END;";
和短信一样,在更新pdu表时,触发更新threads表,其中更新date,snippet,snippet_cs字段,同时用到了前面定义的静态常量。

8、

private static final String UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE =
                        "  UPDATE threads SET snippet = " +
                        "   (SELECT snippet FROM" +
                        "     (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" +
                        "      UNION SELECT date, body AS snippet, thread_id FROM sms)" +
                        "    WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
                        "  WHERE threads._id = OLD.thread_id; " +
                        "  UPDATE threads SET snippet_cs = " +
                        "   (SELECT snippet_cs FROM" +
                        "     (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" +
                        "      UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" +
                        "    WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
                        "  WHERE threads._id = OLD.thread_id; ";
在彩信或者短信数据库删除信息条目时,更新会话信息数据库threads中的snippet以及snippet_cs字段。

9、

private static final String PART_UPDATE_THREADS_ON_INSERT_TRIGGER =
                        "CREATE TRIGGER update_threads_on_insert_part " +
                        " AFTER INSERT ON part " +
                        " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " +
                        "     WHERE part._id=new._id LIMIT 1); " +
                        " END";
这个常量字符串是用于创建触发器,在向part表内插入一条信息时,并且其CONTENT_TYPE(ct)不等于“text/plain”或者“application/smil”时,开始更新会话表threads,设置表内字段has_attachment为1,如果thread_id存在。

10、

private static final String PART_UPDATE_THREADS_ON_UPDATE_TRIGGER =
                        "CREATE TRIGGER update_threads_on_update_part " +
                        " AFTER UPDATE of " + Part.MSG_ID + " ON part " +
                        " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " +
                        "     WHERE part._id=new._id LIMIT 1); " +
                        " END";
这个常量字段用于创建触发器,内容是:当更新了part数据表中的Part.MSG_ID字段时,并且CONTENT_TYPE不等于text/plain或者application/smil时,开始更新数据库threads数据表,设置表内字段has_attachment = 1,并且当_id存在时。

11、

private static final String PART_UPDATE_THREADS_ON_DELETE_TRIGGER =
                        "CREATE TRIGGER update_threads_on_delete_part " +
                        " AFTER DELETE ON part " +
                        " WHEN old.ct != 'text/plain' AND old.ct != 'application/smil' " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment = " +
                        "   CASE " +
                        "    (SELECT COUNT(*) FROM part JOIN pdu " +
                        "     WHERE pdu.thread_id = threads._id " +
                        "     AND part.ct != 'text/plain' AND part.ct != 'application/smil' " +
                        "     AND part.mid = pdu._id)" +
                        "   WHEN 0 THEN 0 " +
                        "   ELSE 1 " +
                        "   END; " +
                        " END";
用户创建触发器,在删除part表内的数据时,如果ct也就是CONTENT_TYPE不等于text/plain或者application/smail时,开始更新threads数据表,它没有where限制,也就是设置表内 所有数据的has_attachment字段等于下面函数的输出值。

函数作用:查询part表内特定的part.mid所对应的行的数量,如果为0,输出0,如果不为0,那么输出1.

12、

private static final String PDU_UPDATE_THREADS_ON_UPDATE_TRIGGER =
                        "CREATE TRIGGER update_threads_on_update_pdu " +
                        " AFTER UPDATE of thread_id ON pdu " +
                        " BEGIN " +
                        "  UPDATE threads SET has_attachment=1 WHERE _id IN " +
                        "   (SELECT pdu.thread_id FROM part JOIN pdu " +
                        "     WHERE part.ct != 'text/plain' AND part.ct != 'application/smil' " +
                        "     AND part.mid = pdu._id);" +
                        " END";
创建一个触发器,在更新了pdu数据表内的thread_id字段,开始更新thread数据表,设置has_attchment字段等于1,并且特定的thread_id存在,这个特定thread_id来自于更新的pdu表行中的_id所对应的thread_id.


这是数据库设计会用的静态常量字符串,后面会介绍数据库创建等。

彩翼通WEB信平台基于C#3.5 + MSSQL2005 R2平台开发,前端采用jQuery1.4.1 + DIV +CSS展示,系统CS源码采用3层架构(数据层+逻辑层+表现层),系统采用存储过程的设计,方便改动及二次开发。 1、【彩翼通信平台系统】具有以下特点: 1)采用3层安全认证机制,安全性超强。层:用户授权访问;二层:动态安全码、用户ID和用户角色MD5加密验证机制,防止用户篡改COOKIE,每个页面进行用户权限验证;三层:系统统过滤危险SQL代码,防止注入式攻击。 2)管理员后台配置信接口,动态获取信接口余额,可以设置当前默认信发送接口,多个信接口灵活切换。绝大多数接口通过直接进行配置就能使用。支持HTTP的GET、POST接口配置。支持爱迪生数据库接口。 3)系统基于系统管理员,代理商和最终客户的商业模式。支持无限极代理 4)群发信时系统自动扣量,设置起始扣量号码数及扣量比例。 5)人工审核发送功能,系统可以设置用户是否需要审核发送,超过起始号码数的会自动拦截,并信提醒管理员客户已提交群发信,由管理员通过系统自动发送或通过卡发设备(信猫)发送。 6)智能白名单功能,管理员可以设置每个客户的白名单号码,设置的白名单号码不会参与扣量(白名单号码为客户可能用来测试群发的手机号码)。用户发送号码少于5个、自动进入白名单。 7)财务管理功能,管理员充值和群发信消费目了然,财务统计功能。在线充值功能. 8)常用群发簿和个性信息管理功能。方便客户管理、维护信。 9)接口容错报警功能,信接口异常,系统自动发送错误日志,信接口余额不足系统自动信通知管理员。 10)系统公告功能,管理员可以指定发送给代理商、客户或全部。 11)对外API接口,支持10万号码次性提交。 12)号码分流:设置移动、联通和电信通道,不同的运营号码自动分流发送。(多通道版支持) 13)长信功能:支持500个字信,系统自动拆分多条发送。 14)强大稳定的后台服务器端发送信程序,支持多线程,详细发送日志,错误报警。 15)自动+手动批量清理数据功能。 2、【彩翼通信平台系统】其它特色功能 1、卡发信回复功能,管理员后台增加回复,客户在后台可以看到回复信 2、扩展扣量,扣量规则分为按比例扣量和最高发送信数量,可针对每个客户设置不同的扣量规则 3、重新定义信接口,准确获取信接口余额,满足90%信接口直接在后台配置就能使用。 4、通讯录管理,支持批量上传。 5、提供对外webservice、http接口支持,支持10万号码! 6、优化信发送。 7、系统操作日志记录 8、直接在页面上设置系统参数 9、重新定义审核流程为:审核—发送—生成报告。 10、重新定义报告生成流程,大大提高报告的生成效率和真实程度。 11、升级服务端软件,记录错误日志,提供容错能力。 12、记录错误日志 13、限制个账号只能同时在台电脑登录 14、全部重构服务端软件,发送信效率大大增加 主要功能: 1.自定义网关接口. 2.移动,联通,电信,小灵通,白名单号码。各自使用个单独的接口。(需要接受系统支持) 3.可以设置10条以下自动发送,10条以上审核后发送。(需要接受系统支持) 4.可以设置在需要审核的时候,有信通知,通知您审核信。 5.可以定时发送信。(需要接受系统支持) 6.可以让用户通过快钱支付,直接在网上通过网上银行支付。 7.自动过滤非法字符,让客户在发送信之前就过滤非法字符。 8.无限级开代理商账号。代理商可以再开代理商账号。 9.用户自己可以给公司内部其他用户在线划账。 10.通讯录通过Excel文件导入\导出功能。 11.提供接口给用户或是代理商使用。 12.可以接爱迪生6.0/7.0网络版软件。(需要卡发接受系统支持) 13.信发送速度快。提交十万条号码到服务器,只需要分钟。 14.客户发送的号码可以随意打包下载。 15.设置信发送时间,可以设置周日到周六中的任天可以发送。也可以设置发送的具体时间,例如:星期日到星期六的07:00到20:30.可以发送信。 16.可以设置A类信和B类信,两种充值方式。A类信是网关信,B类信是虚拟信,客户在发送的时候可以选择信类别 17.可以手工添加上行的号码,也可以导入。就是用户回复的内容,可以手工添加,从爱迪生中导出,经过处理批量导入到系统中。 18.增加用户优先级选项,数值为:1到7.数字越小,级别越高。并且在没有发送的情况下,可以将需要先发的信移到最上面去发。(需要接受系统支持) 19.增加信投票功能,客户可以自己建议信投票,然后根据用户的回复内容统计出来。收集客户投票的方法有两种,第种是接上个能回复的网关接口,从网关接口上直接读取客户回复的内容。第二种,管理员直接在后台人工添加客户回复的内容,可以批量导入。 20.增加报表功能,可以统计出,每个用户的每天发送情况,生成Excel文件方便结算。 21.有网关回复系统,可以发生日信,可以定制信。 22.增加信投票功能。 各系统简要说明: 1、WEB客户端:客户通过网址,直接输入用户名和密码登录,进行发送信。 2、WEB代理商:代理商平台,代理商通过此平台可以开用户,和给用户充值等操作。 3、WEB管理员:总管理员后台,管理员的切操作在此平台。 4、卡发接收系统:此系统的主要目的是将客户提交的号码,接收下来,通过信猫发出去。其原理是:软件可以设置多长时间从数据库中取次数据,当有数据时,会自动下载号码文件,将手机号码和信内容,写进爱迪生6.0/7.0网络版的数据库中,信便可自动发送。 5、网关接收系统:本系统的功能也是将号码接收下来,只不过是通过管理员设置好的网关接口发出去的。此系统的主要目的是让客户端感觉不到发送信很慢。客户端只需要提交号码,由此系统接收号码发出去,从而减轻客户端的压力。 6、网关回复系统: 本系统的功能是将对接上的回复信内容给接受过来,存到用户的收件箱中的。(解决多个用户使用个接口,回复内容要指定到用户的收件箱) 7、软件版客户端:客户通过安装此软件,直接登录平台发送信。客户有两个登录方式,个是WEB的登录方式,个是软件版的登录方式。也就是登录方式的不同,登录后的功能及数据都是相同的。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hailushijie

您的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值