SQL实践篇(二):为什么微信用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存储聊天记录?
  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答您的问题。 问题1:搭建VC++操作SQLite的环境 1. 下载SQLite的预编译库文件,包括sqlite3.dll、sqlite3.lib和sqlite3.h文件。 2. 创建VC++项目,将sqlite3.h和sqlite3.lib文件添加到项目中。 3. 在项目属性中配置库文件和头文件路径。 4. 在代码中包含sqlite3.h头文件,并使用sqlite3_open函数打开SQLite数据库。 问题2:sqlite3.exe和sqlite3.dll的作用分别是什么,怎么使用? sqlite3.exe是SQLite的命令行工具,它可以在没有编程环境的情况下使用SQLite数据库。sqlite3.dll是SQLite的动态链接库,它可以在编程中使用SQLite数据库。 如果您想在命令行中使用SQLite数据库,可以将sqlite3.exe和数据库文件放在同一目录下,打开命令行窗口,进入到该目录下,然后输入sqlite3命令即可进入SQLite的命令行界面。 如果您想在编程中使用SQLite数据库,需要将sqlite3.dll文件添加到项目中,并在代码中调用sqlite3_open函数打开数据库。在使用完毕后,需要调用sqlite3_close函数关闭数据库。 问题3:sqlite的数据库文件路径怎么配置? sqlite的数据库文件路径可以通过在打开数据库时传递一个文件路径参数来配置。例如,如果您想打开名为test.db的数据库文件,可以使用如下代码: ``` sqlite3 *db; int rc = sqlite3_open("test.db", &db); ``` 在这里,test.db文件将被创建在当前工作目录下。如果您想将数据库文件保存在其他目录下,可以传递一个完整的文件路径作为参数。 另外,如果您想在SQLite的命令行工具中打开一个数据库文件,可以使用如下命令: ``` sqlite3 test.db ``` 其中test.db是数据库文件的名称。如果数据库文件不存在,则会自动创建该文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值