2025-08-04 08:00:00
如果用一个词来总结我在字节的日子,我想我会用成长。用这个词也很自然吧,毕竟初入职场后最重要的十年待在字节,并且还是一家成长这么快的公司,经常我还会反思自己的成长速度远远没有跟上公司的需要。对于字节我只有感恩,他不仅给了我超预期的工资回报,更重要的是给我有挑战的项目帮助我成长和证明自己,也给了我很多可以联系一辈子的朋友。
我要感谢我在字节的 leader 们,谢谢你们对我的指导和信任,特别是早期的 leader 容忍了我很多不成熟的做法;对一起合作过的同学,过往如果有沟通方式或者做事方式不对的地方,这里说一声抱歉;对于我之前指导过或者帮助过的同学,你们都有一个美好的未来,而且其中有不少已经做到了比我更重要的岗位。
字节依旧是一家伟大的公司,依旧会有很好的发展,祝福在字节奋斗的小伙伴们!
2023-07-26 08:00:00
DuckDB 是一个 C++ 编写的单机版嵌入式分析型数据库。它刚开源的时候是对标 SQLite 的列存数据库,并提供与 SQLite 一样的易用性,编译成一个头文件和一个 cpp 文件就可以在程序中使用,甚至提供与 SQLite 兼容的接口,因此受到了很多人的关注。
我很久之前就开始关注 DuckDB,并在 2021-06-07 开始写第一行 duckdb-rs 的代码,在 一个多月后写了一篇博客介绍了构建这个库的过程,算是实现了第一个版本。到今天差不多2年的时间,前后发布了19个版本,收获了 200 多个star。
最近一年其实还有很多需求和想法去做优化,但是发现自己并没有那么多时间,收到的 issue 也越来越多。经过沟通,我会把这个库转给 DuckDB 官方来维护,相信 duckdb-rs 一定会发展得越来越好。同时也非常感谢 Mark 和 Hannes 愿意接手这个仓库并把它作为官方的 rust 客户端。
这篇博客总结下我维护的这段时间主要做的事,以及我认为可以改善的点,算是对过去的总结和对未来的憧憬。
这个库是 duckdb 的 rust 客户端,所以关注这个库的群体首先是认可 duckdb 的用户,其次因为他们是 rust 技术栈。下面我列举一些我认为是让这个库“成功”的一些关键点。
下面我挑选几个我认为比较关键的,并且不是我贡献的 MR:
2023-07-26 08:00:00
DuckDB is an in-process SQL OLAP database management system implemented in C++. When it was first open-sourced, it was positioned as a columnar database comparable to SQLite, providing the same ease of use. With just a header file and a cpp file, it could be easily embeded in any program, even offering a SQLite-compatible interface, which caught the attention of many people source.
I started paying attention to DuckDB a long time ago and began writing the first line of duckdb-rs code on June 7, 2021. About a month later, I wrote a blog post introducing the process of building this library, marking the completion of the initial version. Over the past two years, I have released approximately 19 versions, get more than 200 stars in GitHub.
2021-07-27 08:00:00
duckdb 是一个 C++ 编写的单机版嵌入式分析型数据库。它刚开源的时候是对标 SQLite 的列存数据库,并提供与 SQLite 一样的易用性,编译成一个头文件和一个 cpp 文件就可以在程序中使用,甚至提供与 SQLite 兼容的接口,因此受到了很多人的关注。
本文介绍笔者近期开发的 duckdb-rs 库,让大家可以很方便地在 rust 代码库中使用 duckdb 的功能。
了解过 rust 的同学可能知道,rust 提供了 ffi 的方式与其他语言互通。因为 duckdb 本身是 C++ 编写的,想要在 rust 里面使用 duckdb,就需要考虑 ffi 的问题。而基于 ffi 对其他语言程序封装的基础库,一般会被命名为 libxxx-sys,这也就是 libduckdb-sys 的由来。
为了方便大家使用,duckdb 提供了 C++ 原生接口,C 接口,以及与 SQLite3 兼容的 C 接口。我在做 libduckdb-sys 的时候对这三种接口都尝试过,相关的讨论可以参见 Rust Support,我这里介绍一下当时的情况。
最开始我使用的是 SQLite3 的接口,原因主要有三个:
尝试之后确实发现很快能把程序跑起来,基本的功能也能使用。但是随着进一步的深入以及对 duckdb 更多的了解,发现了一些弊端:
2021-02-21 08:00:00
一年前开发 simple 分词器,实现了微信在两篇文章中描述的,基于 SQLite 支持中文和拼音的搜索方案。具体背景参见这篇文章。项目发布后受到了一些朋友的关注,后续也发布了一些改进,提升了项目易用性。
最近重新体验微信客户端搜索功能,发现对于中文的搜索已经不是基于单字命中,而是更精准的基于词组。比如搜索“法国”,之前如果句子中有“法”和“国”两个字时也会命中,所以如果一句话里包含“国法”就会被命中,但是这跟“法国”没有任何关系。
本文描述对 simple 分词器添加的基于词组命中的实现,从而实现更好的查找效果。另外本文也会基于之前在 issue 中大家提到的问题,提供一个怎么使用 SQLite FTS 表的建议。
先简单回顾一下之前的实现,因为结巴分词只跟中文有关,所以本文会略去拼音的部分。
搜索主要分为两部分,建立索引和命中索引。为了实现中文的搜索,我们先把句子按照单字拆分,按照单字建立索引;然后对于用户的输入,也同样按照单字拆分,这样 query 就能命中索引了。为了支持词组搜索,再按照单字拆分就很难满足需求了,所以可以考虑的方案是要么改索引,要么改 query。如果改索引的话会有一些问题,比如如果用户就输入了一个字比如“国”,但是我们建索引的时候把“法国”放到了一起,那“国”字就命中不了了,所以最好是保持单字索引不变,通过改写 query 来达到检索词组的效果。
simple 分词器之前提供了一个 simple_query() 函数来帮助用户生成 query,我们也可以加一个新的函数来实现词组的功能。经过简单的调研,我们发现 cppjieba 用 C++ 实现了结巴分词的功能,很适用与我们的需求。
所以我实现了一个新的函数叫做 jieba_query() ,它的使用方式跟 simple_query() 一样,内部实现时,我们会先使用 cppjieba 对输入进行分词,再根据分词的结果构建 SQLite3 能理解的 query ,从而实现了词组匹配的功能。具体的逻辑可以参考 这里 。对于不需要结巴分词功能的用户,可以在编译的时候使用 -DSIMPLE_WITH_JIEBA=OFF
关闭结巴分词的功能,这样能减少编译文件的大小,方便客户端对文件大小敏感的场景使用。
本文想着重介绍一下 SQLite3 FTS5 功能使用的问题,这些问题都是有朋友在项目的 issue 中提到过的,都是非常好的问题,但是也说明有不少人对怎么使用 FTS 表不太清楚,希望本文能解决一些疑惑。
首先第一点,FTS5 表虽然是一个虚拟表,提供了全文搜索的功能,但是它整体还是跳不出 SQL 的范畴,所以其实很多用法和其他 SQL 表是一样的,当然它也跳不出 SQL 的限制。比如有一个 issue 问如果表中有多列的时候,能不能检索全表,但是只返回命中的那些列?答案是不行的,因为按照 SQL 的语法规则,SELECT 语句后面必须显示说明你想要 SELECT 哪些列,所以结果列是必须用户指定的,如果我们像知道哪些列命中了,只能通过其他一些手段,感兴趣的朋友可以看这个 issue36。
另外 simple 分词器提供了不少额外的功能,比如 simple_query() 和 simple_highlight() 等辅助函数,但是它并不影响我们使用原有 FTS5 的功能,比如如果想按照相关度排序,FTS5 自带的 order by rank
功能还是可以继续可以使用,也就是说 FTS5 页面 提供的所有功能都是可以和 simple 分词器一起使用的。
2020-06-28 08:00:00
在科学计算领域,Jupyter 是一个使用非常广泛的集成开发环境,它支持多种主流的编程语言比如 Python, C++, R 或者 Julia。同时,数据科学最重要的还是数据,而 SQL 是操作数据最直观的语言。前段时间看到一篇文章,有人给 sqlite 做了一个 jupyter 的内核,感觉很有意思。所以我尝试给 ClickHouse 做了一个 jupyter 的内核,目前已经有了一个可以试用的版本,下面做一个简单介绍。
新内核允许用户用 ClickHouse SQL 的语法直接操作远程 CH 数据库,通过一些扩展操作比如 %CONNECT
支持与 ch cli 一样的连接参数,后续也有计划使用 jupyter magics 支持更多的数据可视化操作。
项目参考了 jupyter sqlite 内核的实现方式,是基于 xeus 框架来实现的。xeus 是一个 c++ 的 lib 库,它对 jupyter 的内核做了很好的封装,我们只需要专注于内核相关的功能就可以了。目前对于 ch 的操作基于 clickhouse-cpp 来实现,它是 ch 的 cpp 客户端。
目前实现处于早期阶段,但是基础功能已经可用。它支持了几乎 CH 所有 SQL 语法,具体例子可以参考 clickhouse.ipynb。xeus-clickhouse 在 jupyter notebook 和 jupyter lab 中以 HTML 表格的形式展示数据;在 jupyter console 中,我们使用 tabulate 库只做纯文本的表格。