SQL实践篇(二):为什么微信用SQLite存储聊天记录?

文章目录

  • 简介
  • 什么是SQLite
  • 在python中使用SQLite
  • 通过SQLite查询微信的聊天记录
  • 参考文献

简介

SQLite是一个嵌入式的开源数据库引擎,大小只有3M左右,因此我们可以将整个SQLite嵌入到应用中,而不再需要采用传统的客户端/服务器(CS)架构。这样的好处在于非常轻便,很多智能设备和应用中都可以使用SQLite,比如说微信和QQ就采用了SQLite作为本地聊天记录的存储。

本节将从以下几个方面,深入了解一下SQLite:

  • 什么是SQLite?它有哪些优点和不足?
  • 如何在Python中使用SQLite?
  • 如何编写SQL,来通过SQLite查找微信的聊天记录?

什么是SQLite

SQLite是2000年左右发布的,其采用C语言编写,而不是C++,从而一定程度上尽量提升底层代码的执行效率

它的优势在于非常轻量级,存储数据非常高效,查询和操作也很方便。而且它不需要安装和配置,很方便迁移,也方便嵌入到很多应用程序中。相比需要托管在服务器上的RDBMS,SQLite的约束更加少,更容易操作。

不足也很明显,它不适用高并发的情况,一般常用于小型或者中型的数据存储。比如说在微信本地可以使用SQLite,即时是几百M的数据文件,对SQLite来讲也是信手拈来,但是微信本身的服务器就不能用SQLite了,缺点太明显了,比如说影响最大的一点:SQLite同一时间只允许一个写操作,吞吐量非常有限。

而且,作为一个简化版的数据库,SQLite没有用户管理功能,在语法上也跟常规的SQL有所不同,充斥了一部分的"方言"。

比如说SQLite 不支持right join,仅支持只读视图(只能创建、读取和删除,不能修改)

但总体来讲,基本还是支持SQL标准的。

在python中使用SQLite

在这里插入图片描述

python中集成了SQLite3,直接加载相应的包就可以使用。

import sqlite3

创建数据库连接:

conn = sqlite3.connect("wucai.db")

如果没有这个文件,那么这一步会在相应的工程路径里创建指定的文件,用来存放数据。否则会直接连接现有文件。

然后我们可以使用conn来操作连接,创建游标:

cur = conn.cursor()

得到游标之后,我们就可以通过游标来调用execute()执行各种各样的SQL语句。

比如说创建一个heros数据表:

cur.execute("CREATE TABLE IF NOT EXISTS heros (id int primary key, name text, hp_max real, mp_max real, role_main text)")

再插入一条数据:

cur.execute('insert into heros values(?, ?, ?, ?, ?)', (10000, '夏侯惇', 7350, 1746, '坦克'))

或者使用executemany()来批量插入数据:

cur.executemany('insert into heros values(?, ?, ?, ?, ?)', ((10000, '夏侯惇', 7350, 1746, '坦克'),(10001, '钟无艳', 7000, 1760, '战士'),(10002, '张飞', 8341, 100, '坦克'),(10003, '牛魔', 8476, 1926, '坦克'),(10004, '吕布', 7344, 0, '战士')))

执行查询:

cur.execute("SELECT id, name, hp_max, mp_max, role_main FROM heros")

注意,这时候游标会指向结果集的第一条数据,我们需要通过以下几种方式来获取更多的数据:

  • cur.fetchone():获取一条记录;
  • cur.fetchmany(n):获取n条记录;
  • cur.fetchall():获取全部数据行。

比如说想要获取全部结果集,可以写成:

result = cur.fetchall()

如果我们对事务操作完了,可以执行以下命令来提交事务:

conn.commit()

同样的,如果不再需要使用数据库,也需要关闭游标和数据库连接:

cur.close()
conn.close()

上面过程的完整代码摘录如下:

import sqlite3
# 创建数据库连接
conn = sqlite3.connect("wucai.db")
# 获取游标
cur = conn.cursor()
# 创建数据表
cur.execute("CREATE TABLE IF NOT EXISTS heros (id int primary key, name text, hp_max real, mp_max real, role_main text)")
# 插入英雄数据
cur.executemany('insert into heros values(?, ?, ?, ?, ?)', ((10000, '夏侯惇', 7350, 1746, '坦克'),(10001, '钟无艳', 7000, 1760, '战士'),(10002, '张飞', 8341, 100, '坦克'),(10003, '牛魔', 8476, 1926, '坦克'),(10004, '吕布', 7344, 0, '战士')))
cur.execute("SELECT id, name, hp_max, mp_max, role_main FROM heros")
result = cur.fetchall()
print(result)
# 提交事务 
conn.commit()
# 关闭游标
cur.close()
# 关闭数据库连接
conn.close()

我们也可以通过DBeaver或者navicat等数据库可视化工具,来查看生成的SQLite文件。

通过SQLite查询微信的聊天记录

纯兴趣了解吧。主要是因为教程里讲解本节的时候,是以IPhone为例,我只是个平平无奇的安卓,因此没法仿照做完整的实践,所以就直接把教程里的过程贴出来吧。

第一步,使用 iTunes 备份 iPhone;

第二步,在电脑中查找备份文件。当我们备份好数据之后,需要在本地找到备份的文件,如果是 windows 可以在 C:\Users\XXXX\AppData\Roaming\Apple Computer\MobileSync\Backup 这个路径中找到备份文件夹。

第三步,查找 Manifest.db。在备份文件夹中会存在 Manifest.db 文件,这个文件定义了苹果系统中各种备份所在的文件位置。

第四步,查找 MM.sqlite。Manifest.db 本身是 SQLite 数据文件,通过 SQLite 我们能看到文件中包含了 Files 数据表,这张表中有 fileID、domain 和 relativePath 等字段。

微信的聊天记录文件为 MM.sqlite,我们可以直接通过 SQL 语句来查询下它的位置(也就是 fileID)。

SELECT * FROM Files WHERE relativePath LIKE '%MM.sqlite'

第五步,分析找到的 MM.sqlite。

这里我们需要在备份文件夹中查找相关的 fileID,比如 f71743874d7b858a01e3ddb933ce13a9a01f79aa。

找到这个文件后,我们可以复制一份,取名为 weixin.db,这样就可以使用 navicat 对这个数据库进行可视化管理,如下图所示:

在这里插入图片描述

微信会把你与每一个人的聊天记录都保存成一张数据表,在数据表中会有 MesLocalID、Message、Status 等相应的字段,它们分别代表在当前对话中的 ID、聊天内容和聊天内容的状态).

可以通过以下代码,来查看有多少聊天对象表:

SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'Chat\_%' escape '\'

2023-11-9 15:22:46 注意,看了一下教程里的评论,有人说现在的备份文件是message_1.sqlite,因此可以将第四步里的查询SQL替换成:

SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'Chat\_%' escape '\'

参考文献

  1. 40丨SQLite:为什么微信用SQLite存储聊天记录?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/300115.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《试题与研究》期刊发表投稿方式

《试题与研究》杂志是面向全国公开发行的国家CN级权威教育期刊。创刊以来一直以服务教育服务学生为办刊宗旨,以优秀的内容质量和编校质量深受广大读者好评,其权威性、导向性、针对性、实用性在全国教育期刊中独树一帜。为推动教育科研事业的发展&#xf…

【K8S in Action】服务:让客户端发现pod 并与之通信(2)

一 通过Ingress暴露服务 Ingress (名词) 一一进入或进入的行为;进入的权利;进入的手段或地点;入口。一个重要的原因是每个 LoadBalancer 服务都需要自己的负载均衡器, 以及 独有的公有 IP 地址, 而 Ingres…

CentOS进入单用户模式

一、重启 二、出现内核选项 按“e” 三、编辑这一行 输入 rw init/sysroot/bin/sh 四、进入单用户模式 ctrlx 进入 五、切换目录 chroot /sysroot 六、然后你就操作你的系统了。 修改密码等等

httprunner环境变量

前言 我的上一篇文章讲了httprunner的基本介绍,这篇文章呢主要来给大家介绍httprunner中的环境变量。 一般来说,在进行实际应用的开发过程中,应用会拥有不同的运行环境,通常会有以下环境: 本地开发环境 测试环境 生产…

8 缺失数

无脑蛮力 #include <iostream> #include <vector>using namespace::std; using std::cout; using std::cin; int main() {int num;vector<int> nums;while(cin >> num){nums.push_back(num);if(getchar()\n) {break;}}int t,nnums.size();for(int i0…

MyBatis——MyBatis的动态SQL

MyBatis的动态SQL 创建工程&#xff1a; 1.什么是动态SQL? MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作&#xff0c;并动态拼接成完整的SQL之后再执行&#xff0c;以达到SQL复用、简化编程的效果。 2.if标签 我们根据实体类的不同取值&#xff0c;使用不同的SQL语…

每次maven刷新jdk都要重新设置

pom.xml <java.version>17</java.version> 改为<java.version>1.8</java.version>

linux:下载、网络请求、端口

一&#xff1a;ping命令 可以通过ping命令,检查指定的网络服务器是否是可联通状态 语法: ping [-c num] ip或主机名 1、选项&#xff1a;-c,检查的次数&#xff0c;不使用-c选项&#xff0c;将无限次数持续检查 2、参数&#xff1a;ip或主机名&#xff0c;被检查的服务器的…

个人百度百科词条怎么创建?

什么人可以上百科&#xff1f;个人百度百科词条的创建通常针对公众人物、知名专家、学者、艺术家、企业家等具有一定社会影响力和知名度的人物。所以当你拥有一个百度百科词条的时候&#xff0c;知名度和形象自然会显著提升。个人百度百科词条怎么创建&#xff1f;接下来伯乐网…

Ensp dhcp全局地址池(配置命令 + 实例)

使用DHCP的好处&#xff1a;减少管理员的工作量、避免输入错误的可能、避免ip冲突 DHCP报文类型&#xff1a; DHCP DISCOVER:客户端用来寻找DHCP服务器 DHCP OFFER:DHCP服务器用来响应DHCP DISCOVER报文&#xff0c;此报文携带了各种配置信息 DHCP REQUEST:客户端配置请求确…

ArcGIS基础:便捷查看外业照片及识别举证照片方位角

打开工具&#xff1a;【地理标记照片转点】。 打开工具后&#xff0c;输入文件夹&#xff0c;并对相应的参数进行勾选。 右键&#xff0c;图层属性&#xff0c;打开【显示】&#xff0c;对【超链接】设置等参数进行勾选。 找到【符号系统】&#xff0c;点击【高级】&#xff…

关于合同能源管理

合同能源管理模式&#xff1a;我投资、你节能、收益共享 合同能源管理&#xff08;EPC——Energy Performance Contracting&#xff09;&#xff1a;节能服务公司与用能单位以契约形式约定节能项目的节能目标&#xff0c;节能服务公司为实现节能目标向用能单位提供必要的服务&…