TinyDB 是一个紧凑、轻量级的数据库,并且是面向文档的。它是 100% 用 Python 编写的,没有外部依赖。最适合 TinyDB 的应用程序是小型应用程序。TinyDB 的主要功能如下:
尽管 TinyDB 具有多种优势,但它有一些限制,如下所列:
经过研究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,因此设计文件头信息,存储表名称和相应的数据量,每个表分配固定的存储空间,根据表的存储空间分别追加数据。 这样就造成了随机读写的缺点,没有日志追加的性能优势了。 二是,每张表一个数据文件,这样就可以利用日志追加的技术优势。
一个文件,每条数据添加表名信息,每条数据一行存储。先判断是哪个表,利用字典对象的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。估计是数据量少,官方方案就简单直接够用了。原因是,底层存储是亿页为单位来存取的,数据量少,写性能可看做固定值。