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存储聊天记录?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22.04 下载路径

ftp下载路径 csdn下载 ubuntu22.04下载路径ubuntu-22.04-desktop-amd64.7z.001资源-CSDN文库 ubuntu22.04下载路径ubuntu-22.04-desktop-amd64.7z.002资源-CSDN文库 【免费】ubuntu-22.04-desktop-amd64.7z.003资源-CSDN文库 【免费】ubuntu-22.04-desktop-amd64.7z.004资源-…

Jave EE 网络原理之网络层与数据链路层

文章目录 1. 网络层1.1 IP 协议1.1.1 协议头格式1.1.2 地址管理1.1.2.1 认识 IP 地址 1.1.3 路由选择 2. 数据链路层2.1 认识以太网2.1.1 以太网帧格式2.1.2 DNS 应用层协议 1. 网络层 网络层要做的事情,主要是两个方面 地址管理 (制定一系列的规则&am…

数字化协同在服装行业:监狱服装生产的量身解决方案

内容来自演讲:苗子实 | 北京宜通华瑞科技有限公司 | 产品经理 摘要 这篇文章介绍了宜通世纪子公司北京宜通华瑞在服装行业智能制造方面的业务,以及明道云提供的业务支持。文章提到了服装行业的痛点及解决方案,并详细介绍了优化监狱服装企业的…

算法练习Day20 (Leetcode/Python-回溯算法)

虽然看似进入了一个新章节,但其实还是前几天二叉树章节的延续。。 回溯算法 (以下内容摘抄自代码随想录): 回溯法解决的问题都可以抽象为树形结构,是的,我指的是所有回溯法的问题都可以抽象为树形结构&…

C#获取企业微信《会话内容存档》

因为公司某些原因需要使用企业微信的会话内容存档内容,看微信的文档踩了一些坑,现在将项目代码记录下来,以备各位码农同行查阅。 项目使用 .NET8.0架构,节本结构如下图: 项目中的Lib是下载的微信SDK,项目地…

9道软件测试面试题,刷掉90%的测试程序员

经历了“金9银10”,转眼2024年招聘季就要来了,没点真本事真技术,没点面试经验,不了解点职场套路,如何过五关斩六将?如何打败面试官?如何拿下那梦寐以求的offer? 如果你的跳槽意向已…

[C/C++]数据结构 希尔排序

🥦前言: 希尔排序也称 “缩小增量排序”,它也是一种插入类排序的方法,在学习希尔排序之前我们首先了解一下直接插入排序. 一: 🚩直接插入排序 1.1 🌟排序思路 直接插入排序的基本原理是将一条记录插入到已排好的有序表中&#x…

EDSR训练及测试教程

EDSR训练及测试教程 超分重建经典算法EDSR开源代码使用教程。 论文名称:Enhanced Deep Residual Networks for Single Image Super-Resolution,CVPR2017。 训练自己的数据集 由于EDSR开源代码只针对DIV2K数据集,在数据集加载时很多代码已经固定,因此在这里使用固定的文…

Android Studio 如何实现软件英文变中文教程

目录 前言 一、确认版本号 二、下载汉化包 三、汉化包安装 四、如何实现中英文切换 五、更多资源 前言 Android Studio是一款功能强大的集成开发环境(IDE),用于开发Android应用程序。默认情况下,Android Studio的界面和…

STM32实战之深入理解I²C通信协议

目录 IC的物理层 IC的协议层 IC特点 IC 总线时序图 软件模拟IC时序分享 例程简介 例程分享 STM32的IC外设 IIC(Inter-Integrated Circuit),也称为IC或TWI(Two-Wire Interface),是一种广泛使用的串行…

数据仓库【1】:简介

数据仓库【1】:简介 1、诞生背景1.1、数据仓库诞生原因1.2、历史数据积存1.3、企业数据分析需要 2、基本概述2.1、数据仓库(Data Warehouse,DW)2.2、数据仓库特点2.3、数据仓库 VS 数据库 3、技术实现3.1、数据仓库建设方案3.2、传…

『CVE』简析CVE-2023-48795:SSH协议前缀截断攻击(Terrapin攻击)

文章目录 OpenSSH 9.6更新公告Terrapin攻击 (CVE-2023-48795)基本信息利用手段利用路径利用条件利用原理及示意图危害Terrapin-Scanner 基于Terrapin的潜在风险:CVE-2023-46445 & 46446参考完 OpenSSH 9.6更新公告 *ssh(1), sshd(8): implement protocol extens…

第十六节TypeScript 类

1、简介 TypeScript是面向对象的JavaScript。 类描述了所创建的对象共同的属性与方法。 2、类的定义 class class_name { // 类作用域 } 定义类的关键字是class,后面紧跟类名,类可以包含以下几个模块: 字段 – 字段是类里面声明的变量。字…

java练习之abstract (抽象) final(最终) static(静态) 练习

1:分析总结:写出private、abstract、static、final之间能否联动使用,并写出分析原因 private static final 之间可以任意结合 abstract 不可以与private static final 结合使用 2:关于三个修饰符描述不正确的是(AD) A. static …

实习知识整理8:如何实现将商品加入购物车

情景分析:当我们进入商品详情页面时,一般会有两个按钮,一个是加入购物车,另一个是直接购买的按钮,我们先来看看加入购物车是如何实现的 1. 数据库表分析 需要3个表:商品表item、用户表user、购物车表cart 需…

基于JAVA的医院门诊预约挂号系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2 科室医生档案模块2.1.3 预约挂号模块2.1.4 医院时政模块 2.2 可行性分析2.2.1 可靠性2.2.2 易用性2.2.3 维护性 三、数据库设计3.1 用户表3.2 科室档案表3.3 医生档案表3.4 医生放号…

Autosar CAN开发05(从实际应用认识CAN波特率)

建议同时阅读本专栏的: Autosar CAN开发03(从实际应用认识CAN总线的物理层) Autosar CAN开发04(从实际应用认识CAN报文) Autosar CAN开发05(从实际应用认识CAN波特率) 前言 当知道了CAN的物…

STM32MP157D-DK1开发板Qt镜像构建

上篇介绍了STM32MP57-DK1开发板官方系统的烧录。那个系统包含Linux系统的基础功能,如果要进行Qt开发,还需要重新构建带有Qt功能的镜像 本篇就来介绍如何构建带有Qt功能的系统镜像,并在开发板中烧录构建的镜像。 1 Distribution包的构建 ST…

优化模型:MATLAB整数规划

一、整数规划介绍 1.1 整数规划的定义 若规划模型的所有决策变量只能取整数时,称为整数规划。若在线性规划模型中,变量限制为整数,则称为整数线性规划。 1.2 整数规划的分类 整数规划模型大致可分为两类: (1&…

HAL库的常用库函数(根据学习而更新)

目录 一、常用的GPIO相关HAL库函数 1、GPIO的初始化 2、配置GPIO引脚输出电平 3、切换指定引脚的电平,电平的翻转 4、读取指定GPIO引脚的电平 5、结构体 GPIO_InitTypeDef (引脚)定义: 6、高低电平的表示 7、延时函数&…