当前位置: 首页 > 工具软件 > Tinydb > 使用案例 >

python tinyDB存储方案设计

马祺
2023-12-01

TinyDB 是一个紧凑、轻量级的数据库,并且是面向文档的。它是 100% 用 Python 编写的,没有外部依赖。最适合 TinyDB 的应用程序是小型应用程序。TinyDB 的主要功能如下:

  1.     顾名思义,TinyDB 非常小。完整的源代码只有1200行。
  2.     TinyDB 基于面向文档的存储。MongoDB 等流行工具采用了这种类型的存储。
  3.     TinyDB 的 API 非常简单和干净。首先,TinyDB 的设计考虑到了易用性。
  4.     TinyDB 的另一个令人喜欢的特性是非依赖性。此外,TinyDB 支持所有最新版本的 Python。
  5.     可扩展性是 TinyDB 的另一个主要特性。在中间件的帮助下,可以扩展 TinyDB 行为以满足特定需求。

尽管 TinyDB 具有多种优势,但它有一些限制,如下所列:

  1.     TinyDB 不适合那些以高速数据检索为关键的场景。
  2.     如果您需要从多个进程或线程访问数据库,那么 TinyDB 将不是最佳选择。同样,基于 HTTP 服务器的访问是另一种不适合的场景。

经过研究tinydb的源代码,发现他的存储机制是,每次添加或更新数据,则合并完数据将完整数据一次性写入数据文件。这种方式存储肯定性能有问题。因此考虑3个方式调优

一、根据日志追加的技术,设计单条数据追加的方案。

官方方案是将原来完整的数据作为一个对象转换为json格式,一次性写入文件,添加或修改时完全重新写数据文件。格式如: {“tablename”: { "doc_id": {object},  "doc_id": {object} } }

因此简化数据存储格式,"doc_id": {object},  "doc_id": {object},这样每次只追加 "doc_id": {object},即可。测试5W条数据,官方存储方案耗时11229.0964569 ,追加方案耗时 4968.6888719,性能提升非常明显。

数据删除时,追加一条"doc_id": {object,“__del”:"1"},读取时再将包含此属性的数据过滤掉。

数据更新时,同样追加一条最终状态的数据。读取时,json解析后保留最后一条数据的值,不需要重写json解析程序。

但是有一个问题,此方式只能单对象。

二、多表方式的数据追加存储方案

有2中方式,一是单数据文件,多表追加数据。因为方案一的格式,不能区分table,因此设计文件头信息,存储表名称和相应的数据量,每个表分配固定的存储空间,根据表的存储空间分别追加数据。 这样就造成了随机读写的缺点,没有日志追加的性能优势了。 二是,每张表一个数据文件,这样就可以利用日志追加的技术优势。

三、单条数据也是完整table对象,冗余存储方案

一个文件,每条数据添加表名信息,每条数据一行存储。先判断是哪个表,利用字典对象的update方法。可能产生更多的计算。

数据例如
{"tablename":{ "1": {"a": 1} } }
{"tablename":{ "2": {"a": 1} } }
{"tablename":{ "3": {"a": 9} } }
读取时合并
val["tablename"].update( json.loads( val2)["tablename"] )

单条记录格式实验后,确定如下

{"T":"tablename","V":{ "1": {"a": 1} } }
数据根据table,合并数据,即合并属性
val = json.loads( val2 )
tables[val["T"] ].update( val["V"] )

但是,根据1W条数据测试,官方方案655.742566,本方案733.623031。估计是数据量少,官方方案就简单直接够用了。原因是,底层存储是亿页为单位来存取的,数据量少,写性能可看做固定值。

代码见GitHub - jahson88/tinydb: TinyDB is a lightweight document oriented database optimized for your happiness :)

 类似资料: