数据存储使用文件还是数据库,哪个更合适?

简介: 数据库和文件系统各有优劣:数据库读写性能较低、结构 rigid,但具备计算能力和数据一致性保障;文件系统灵活易管理、读写高效,但缺乏计算能力且无法保证一致性。针对仅需高效存储与灵活管理的场景,文件系统更优,但其计算短板可通过开源工具 SPL(Structured Process Language)弥补。SPL 提供独立计算语法及高性能文件格式(如集文件、组表),支持复杂计算与多源混合查询,甚至可替代数据仓库。此外,SPL 易集成、支持热切换,大幅提升开发运维效率,是后数据库时代文件存储的理想补充方案。

使用数据库存储数据很常见,数据库不仅提供了多种存储策略,还可以满足数据一致性的要求,基于数据库还能很方便完成数据计算,但使用数据库存储数据也有一些缺点,在一些场景下并非最佳选择。与数据库相对的是使用文件存储数据,文件系统更加开放,使用起来也很灵活,但文件本身没有计算能力,也无法保证数据一致性,不过,一些场景使用文件存储数据却更加适合。

我们从以下方面来对比一下数据库与文件系统,看看在哪些场景下使用何种技术更合适?

关注点

读写性能
数据存储的目的是使用并创造价值,这里的读写是指应用在使用数据时需要通过文件系统或数据库将数据取出或写入的过程。我们知道,数据库数据出库要通过数据库访问接口,通常是 JDBC 和 ODBC,数据出库的效率与数据库接口密切相关。实测表明,一个 3000 万行(物理大小约为 4.9G)的表 MySQL 首次读取需要 518 秒,而同样的文本读取则只需要 42 秒,相差 12 倍多。数据写入也同样存在差异,数据库写入时间要比文本慢 50 倍。

因此,单纯从读写性能的角度来看,文件要比数据库快得多。

灵活性和易管理性
数据库的结构是扁平的,表建立以后都在同一级(线性结构),最多有个模式勉强算做两层,当表数量较多时就比较难以管理。要区分这些表就要使用严格的命名规则,比如按项目、模块、年代、版本命名,这样的命名规范需要强管理机制,但实际情况是往往由于项目急需上线,表命名规范就顾不上那么多了,时间久了数据库管理非常混乱,有时想删除都不容易,数据表建完经常永久存在(因为不知道那个程序还在用也不敢删)。

而文件可以借助文件系统的树状目录进行管理,不同项目、模块按照树形结构存储,管理和使用都很方便,如果项目下线可以放心大胆地删除对应目录,不用担心跟其他程序紧耦合。

另外,数据库有约束,不仅需要先建表再存储数据,数据类型也很死板,不满足条件的数据就存不进去,灵活性很差,有时一些临时性计算要折腾到数据库再使用就很不方便了;而文件不存在这样的问题,什么样的数据都能存储,灵活性很强,使用也很方便。

可计算性
文件不管是读写还是管理都占优,但是在计算方面就不一样了。前面说过,数据是要使用才能产生价值,从广义上来讲就是计算。数据库不仅能存储,还能计算,不仅能算还挺方便,使用 SQL 这种专门的数据库计算语言处理数据很方便,分组汇总、关联计算简单一句就能搞定。 而文件却不具备这样的能力,要计算文件数据还要借助其他编程语言完成,不同语言的实现难度不同,但大部分都要比 SQL 复杂一些。

数据修改能力
有些业务场景还会涉及数据修改,修改数据库数据相对简单,使用 SQL 语句就可以轻松完成,但文件修改要麻烦得多,无论是查找要修改的记录还是更新数据都不轻松,大多时候还不如重写文件的效率高。不过,像数据分析型(OLAP)场景面对的大多是不再变化的历史数据,不涉及数据修改删除(更多只是追加)使用文件是可行的。

另外,诸如交易系统还会要求数据一致性,数据库有事务管理机制可以满足一致性要求,但文件却不行。不过像 OLAP 等一些场景并没有数据一致性要求,在这类场景下使用文件也是可以的。

总体来看,如果对数据有频繁的修改需求,特别还对一致性有要求的场景(如交易系统),使用数据库更合适;而对于没有数据一致性要求的场景(如分析系统)就可以使用文件存储数据,只是文件没有计算能力,使用传统硬编码方式会比较复杂,如果在计算能力方面有所增强,再借助文件的高效读写能力和灵活易管理特性,那么文件存储将更有优势。

那么有没有办法增强文件的计算能力呢?

使用开源集算器 SPL 可以实现这个目标。

开源数据计算引擎 SPL

SPL 是一款专业的开源数据计算引擎,提供了独立的计算语法,计算能力不依赖数据库。可以基于文件进行计算,让文件拥有计算能力,这样就可以有效弥补文件计算能力不足的问题,同时支持多种数据源进行混合计算。

文件计算能力
SPL 提供了独立的计算语法和丰富的计算类库,可以快速完成结构化数据计算。下面是一些常规运算:
image.png

除了原生 SPL 语法,SPL 还提供了相当 SQL92 标准的 SQL 支持,对于熟悉使用 SQL 的人员可以直接使用 SQL 查询文件。

$select * from d:/Orders.csv where Client in ('TAS','KBRO','PNS')
AI 代码解读

复杂些的 with 都支持:

$with t as (select Client ,sum(amount) s from d:/Orders.csv group by Client)
select t.Client, t.s, ct.Name, ct.address from t
left join ClientTable ct on t.Client=ct.Client
AI 代码解读

SPL 在处理 JSON/XML 等多层数据(文件)方面也很有优势,如:根据员工订单信息(json)完成计算。
image.png
可以看到,相对其他JSON 库(如 JsonPath)SPL 的实现更简洁。

同样,使用 SQL 也可以查询 JSON 数据:

$select * from {
   json(file("/data/EO.json").read())}
where Amount>=100 and Client like 'bro' or OrderDate is null
AI 代码解读

SPL 的敏捷语法和过程计算还非常适合完成复杂计算,比如基于股票记录(txt)计算某只股票最长连涨天数 可以这样写:
image.png
再比如,根据用户登录记录(csv)列出每个用户最近一次登录间隔:
image.png
这类计算即使基于数据库使用SQL 也很难写,SPL 实现却很方便。

高性能文件格式
文本是很常见的数据存储形式,它具有通用性易读性等优点而被广泛使用。但是,文本的性能却非常差!

文本字符不能直接运算,需要转换成整数、实数、日期、字符串等内存数据类型才可以进一步处理,而文本的解析是个非常复杂的任务,CPU 耗时很严重。一般来讲,外存数据访问的主要时间是在硬盘本身的读取上,而文本文件的性能瓶颈却经常发生在 CPU 环节。因为解析的复杂性,CPU 耗时很可能超过硬盘耗时(特别是采用高性能固态硬盘时)。需要高性能处理较大数据量时通常不会使用文本。

SPL 提供了两种高性能数据存储格式,集文件和组表。集文件是 SPL 提供的二进制数据格式,不仅采用了压缩技术(占用空间更小读取更快),存储了数据类型(无需解析数据类型读取更快),还支持可追加数据的倍增分段机制,利用分段策略很容易实现并行计算,进一步提升计算性能。

组表是 SPL 提供列存、索引机制的文件存储格式,在参与计算的列数(字段)较少时列存会有巨大优势。组表除了支持列存,实现了 minmax 索引外,还支持倍增分段机制,这样不仅能享受到列存的优势,也更容易并行提升计算性能。

SPL 存储的使用也很方便,与文本使用基本一致,比如读取集文件并计算:
image.png
如果数据量较大,还支持游标分批读取以及多 CPU 并行计算:

=file("/data/scores.btx").cursor@bm()
在使用文件作为数据存储方式时,无论原始数据是何种格式,最后都至少要转存成二进制(如集文件)格式,这样无论在空间占用还是计算性能上都会更有优势。

SPL 完备的计算能力加高性能存储就提供了与数据仓库相当(或超越)的能力,在很多场景下甚至可以替代数据仓库。

多源混合计算
SPL 不仅支持文件计算,还支持其他多种数据源,想到想不到的数据源都能支持。

941589629474f1a10a49895c2da62c21_1645713831733100.png
这样,SPL 就可以进行多源混合计算,特别适合完成 T+0 查询。前面我们提过,文件适合存储不再修改的大量历史数据,而少量实时可能修改的热数据仍然存储在数据库中,如果要全量查询就要跨文件和数据库查询,这时就可以利用 SPL 的跨源计算能力和数据路由功能,根据计算需求选择对应的数据源以及跨数据源混合计算。如冷热数据分离后,基于 SPL 进行冷热数据混查,同时对上层应用透明,实现 T+0 查询。
image.png
易集成
SPL 提供了标准 JDBC 和 ODBC 接口供应用调用。特别地,对于 Java 应用可以将 SPL 作为嵌入引擎集成到应用中,使得应用本身就具备基于文件的强计算能力。

JDBC 调用 SPL 代码示例:

...
Class.forName("com.esproc.jdbc.InternalDriver");

Connection conn =DriverManager.getConnection("jdbc:esproc:local://");

CallableStatement st = conn.prepareCall("{call splscript(?, ?)}");

st.setObject(1, 3000);

st.setObject(2, 5000);

ResultSet result=st.execute();
...
AI 代码解读

SPL 是解释执行的,天然支持热切换,这对 Java 体系下的应用是重大利好。基于 SPL 的数据计算逻辑编写、修改和运维都不需要重启,实时生效,开发运维更加便捷

易集成与热切换特性还很方便与主流的微服务框架结合,实现服务内的数据处理工作,这样还可以有效减轻原来 Java 实施数据计算的负担。
f6ea218dbb1c8e71587a001298427f54_1646635446566100.png
除了以上优点,SPL 提供的简洁易用的开发环境也可圈可点,单步执行、设置断点,所见即所得的结果预览窗口…,开发效率也更高。

366b6cba88a7a89c40e29888454a19e4_ad3c5b633ef84e829c7296fd550107ec_1.png
在 SPL 文件计算、高开发效率和高计算性能的支持下,使用文件存储数据可以获得更优的体验(不需要数据一致性时),同时还能结合其他数据源完成混合计算,是后数据库时代很好的选择。
SPL是开源免费的,欢迎前往乾学院了解更多~~

目录
打赏
0
0
1
0
82
分享
相关文章
数据库数据删除策略:硬删除vs软删除的最佳实践指南
在项目开发中,“删除”操作常见但方式多样,主要分为硬删除与软删除。硬删除直接从数据库移除数据,操作简单、高效,但不可恢复;适用于临时或敏感数据。软删除通过标记字段保留数据,支持恢复和审计,但增加查询复杂度与数据量;适合需追踪历史或可恢复的场景。两者各有优劣,实际开发中常结合使用以满足不同需求。
227 4
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
305 75
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
让数据与AI贴得更近,阿里云瑶池数据库系列产品焕新升级
4月9日阿里云AI势能大会上,阿里云瑶池数据库发布重磅新品及一系列产品能力升级。「推理加速服务」Tair KVCache全新上线,实现KVCache动态分层存储,显著提高内存资源利用率,为大模型推理降本提速。
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
Hutool创建数据源工厂动态查询不同数据库不同数据表的数据
Hutool创建数据源工厂动态查询不同数据库不同数据表的数据
105 2
数据库数据恢复—MongoDB数据库迁移过程中丢失文件的数据恢复案例
某单位一台MongoDB数据库由于业务需求进行了数据迁移,数据库迁移后提示:“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”
flink 向doris 数据库写入数据时出现背压如何排查?
本文介绍了如何确定和解决Flink任务向Doris数据库写入数据时遇到的背压问题。首先通过Flink Web UI和性能指标监控识别背压,然后从Doris数据库性能、网络连接稳定性、Flink任务数据处理逻辑及资源配置等方面排查原因,并通过分析相关日志进一步定位问题。
590 61

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等