图片

前言

我曾经在 DuckDB与PostgreSQL结合一下,PostgreSQL会如虎添翼 一文中简要提过DuckDB与SQLite两者之间的关系。在嵌入式开源数据库里头,SQLite是绝对的OLTP的王者,而DuckDB则是或者将是OLAP的王者。

图片

本文就简单聊聊SQLite数据库。

SQLite概览

SQLite项目发起于2000年5月9日。SQLite虽说是开源,但是它的代码控制的非常好。测试完全充分是它的显著特色。100%的分支覆盖率,让人叹为观止。它与PostgreSQL不一样,它由一支国际开发人员小组“全职”进行开发。代码可以自由使用,但是它也提供专业的支持。现在的承诺是能至少支持到2050年,并且保持策略不变。

闪光的地方,就不多说了,直接看下图:

图片

关于代码

SQLite的代码控制的非常好。SQLite 的作者是 D. Richard Hipp(理查德希普),作者非常的有个性,用到的软件工具都是自己写,他写了不少工具,比如 SQLite、Bug 追踪系统 CVSTrac、版本管理系统 Fossil。

作者 Richard 最开始在一艘军舰上做 contractor(就是我们说的[外包])。他们程序跑在军舰安装的电脑上,电脑上装的是 informix。Richard 的工作就是把 informix 的数据拿出来进行计算然后展示到电脑屏幕上(这和我们今天的 CRUD 工作类似)。比较令人恼火的是 informix 很不稳定,经常崩溃连不上。部队里的铁拳长官可不懂啥 TCP/IP 或者数据库系统知识。他们只看到软件的报错 dialog(对话框) 经常弹出来,而这个 dialog 又是 SQLite 的作者 Richard 写的软件画出来的,锅自然从天而降。于是 Richard 决定自己从头写一个无需外部连接的数据库来解决这个问题。(参考:https://globalcoding.blog.csdn.net/article/details/126184412: SQLite 历史故事)。作者本身擅长编译,对数据库本身反而不是很擅长,但是他一步步走过来了。

  • public domain

    任何人都可以自由地复制、修改、发布、使用、编译、销售或分发原始SQLite代码,无论是以源代码形式还是以编译后的二进制文件形式,用于任何目的,商业或非商业,以任何方式。

    这是它的承诺。差不多是最自由的。

  • Open-Source, not Open-Contribution

    开放源码,但不是开放贡献。为了将SQLite保持在public domain,并确保代码不会受到专有或许可内容的污染,该项目不接受没有在public domain上宣誓的人提交的任何补丁。确保它的每一行代码都是干净的。

  • 贡献代码?

    如果我们想贡献代码,基本上很难。你可以向他们提供补丁建议,但最后他们会重写你的代码(如果真有可能被采纳的话)。这与作者要掌控所有代码的纯洁干净有关。

解析器

众所周知,开源的解析器,大都使用bison或者yacc。PostgreSQL不就是如此吗?可是SQLite不一样,它为了保证代码简洁安全可控,自己搞了一个lemon解析器。详情可见:The Lemon Parser Generator (sqlite.org) :https://sqlite.org/src/doc/trunk/doc/lemon.html

其实,学习编译原理的,完全可以单独将它拿出来做一些实验验证。

如何盈利?

  • 金牌赞助

    它有一些类似于金牌会员一样的赞助机制,那些会员每年都对SQLite进行赞助,这些能覆盖到相当大一部分费用

  • 专业支持

    使用SQLite的公司或个人,如果是重度使用,自然会有一些地方需要得到专业的支持,那么SQLite自然会提供既深且广的支持,这个不是免费的。也是很大一部分收入来源。

  • 非开源部分的代码

    还有一部分,就是安全加密部分。这部分代码不是开源的。只有SQLite的客户才可以拿到SEE (The SQLite Encryption Extension (SEE))的源码。详见:SQLite Encryption Extension:https://sqlite.org/com/see.html 一份订单:2000刀。想想,全世界会有多少要用或正用的SEE的客户吧。当然也有一些开源的加密库,但是使用的安全等级远不如SQLite官方提供的。要看实际需求。

    ➜  SQLite_Encryption_Extension-4573df349a ls
    LICENSE.md                     shell.c                        sqlite3-see-aes256-ofb.c       sqlite3-see-xor.c              test-dbs
    build.sh                       sqlite3-see-aes128-ccm.c       sqlite3-see-aes256-openssl.c   sqlite3-see.c                  www
    dotnet                         sqlite3-see-aes128-ofb.c       sqlite3-see-cccrypt.c          sqlite3.c
    msvc                           sqlite3-see-aes256-cryptoapi.c sqlite3-see-rc4.c              sqlite3.h
    ➜  SQLite_Encryption_Extension-4573df349a vi build.sh
    ➜  SQLite_Encryption_Extension-4573df349a sh build.sh
    gcc -Os -g -Wall -DSQLITE_THREADSAFE=0 -I. -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB -o bld/see-cccrypt -DCCCRYPT256 sqlite3-see-cccrypt.c shell.c -ldl
    ......
    

    简单命令行说明:

    The SQLite Command-Line Interface (CLI) is enhanced with two additional command-line options, 
    "-key" and "-hexkey", that are used to
    specify the encryption key. The -key option takes an argument which is the encryption key in ASCII text. 
    The -hexkey option takes an argument 
    which is the binary encryption key represented in hexadecimal. The CLI
    also includes a new dot-command called ".rekey" that invokes the 
    sqlite3_rekey() interface in order to change the encryption key on a 
    database.
    

    试用:

    将a.sqlite加密,然后再尝试打开:

    ➜  bld ./see-rc4 a.sqlite
    SQLite version 3.44.0 2023-11-01 13:38:45 with the Encryption (see-rc4)
    Copyright 2016 Hipp, Wyrick & Company, Inc.
    Enter ".help" for usage hints.
    sqlite> .rekey '' 'changeit' 'changeit'
    sqlite> create table t(id int);
    sqlite> insert into t values(1), (2);
    

    尝试打开:

    ➜  bld ./see-rc4 a.sqlite
    SQLite version 3.44.0 2023-11-01 13:38:45 with the Encryption (see-rc4)
    Copyright 2016 Hipp, Wyrick & Company, Inc.
    Enter ".help" for usage hints.
    sqlite> select * from t;
    Parse error: file is not a database (26)
    sqlite> .key changeit
    Error: unknown command or invalid arguments:  "key". Enter ".help" for help
    
    sqlite> .quit
    ➜  bld ./see-rc4 -key changeit a.sqlite
    SQLite version 3.44.0 2023-11-01 13:38:45 with the Encryption (see-rc4)
    Copyright 2016 Hipp, Wyrick & Company, Inc.
    Enter ".help" for usage hints.
    sqlite> select * from t;
    1
    2
    

使用经历

回忆起来,我也曾经是SQLite的重度使用用户。并且是早期SEE代码的用户。2006-2009-2011年左右,有大量的Windows Mobile应用,需要用到嵌入式数据库,当时除了Sybase的ASA (Ultralite, 曾经也是绝对的王者),剩下的也就是SQLite了。基于ADO.net,SQLite也有相关的开源的库。Windows Mobile/WinCE的进程内存使用有一些限制,必须对SQLite代码进行改写(customize),才能支持大一点内存的加载与运行(不改写的话,只会导致OOM,实际上物理内存是足够的)。于是连同SEE库集成到sqlite ado.net for CE里,加上改写的大内存blob读写。当时由于太忙,也忘了申请相关专利了。

再后来SQLite发展太猛了,Android设备上几乎全装的是它。iOS设备自不必说。基本上就真的垄断了。要说在Windows Mobile/BlackBerry还有诺基亚的Symbian,sqlite当时还没有被完全侵入,后边都没他们什么事了。

总结

SQLite的代码质量非常高,一个重要的保证是它的测试覆盖率几乎100%。这种要求尽乎苛刻。盈利思路也非常明确。以它目前的财务状况,很容易支撑到20年后。但是有很重要的一点是,它的专业服务与支持是它生存的亮点。同时把开放的与不开放的分的很清楚。

要明白:“安全”这一块的源码,不是你想开放就可以开放的。具体到具体国家与地区,它就会受到各方便审查。所以,这一点也是非常明确清晰的。你要想得到相关源码,除了审核相关进出口限制以外,支付2000$即可。不过,也许将来,这种策略会发生改变,比如基于Cloud的销售策略?它现在的策略明显还是直接售卖源码的拷贝的方式。

再回到PG本身,无论是所谓的“套壳”也好,或者重写或重大改写也好,用户其实并不是很关心,他们关心的是你能不能提供专业的贴心的服务与支持。

也许再经过5到10年,江湖混战的模式该逐渐统一了,希望到时候不是一些“寡头”搞内部垄断,不思进取。那就不是PostgreSQL发展的初衷了。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐