clickhouse-js-node-rowbinary
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseClickHouse JS RowBinary Codec Generator for Node.js
Node.js 版 ClickHouse JS RowBinary 编解码器生成工具
This skill generates both directions of the wire format: readers (decode
bytes → values) and writers (encode values → bytes, the mirror). A given
task normally needs only one side. This file is the shared entry point — the
format gate plus the principles common to both directions; the per-direction
decisions, guidance, and the per-type reference tables live in two sibling files.
Pick your side — read only the one you need:
- Decoding a response from ClickHouse into JS values → reader.md. Streaming vs whole-buffer, row-objects vs columnar, fixed vs runtime schema, and the per-type reader reference.
RowBinary* - Encoding JS values into a payload to send to ClickHouse → writer.md. The
RowBinary/Sinkbuilding blocks,writeXstreaming, and the per-type writer reference.writeRows
The per-type code is real, split by direction under and
.
src/readers/src/writers/此技能可生成双向的有线格式处理代码:读取器(将字节解码为值)和写入器(将值编码为字节,与读取器互为镜像)。通常一项任务只需要其中一方。本文件是共享入口点——包含格式网关以及双向通用的原则;各方向的决策、指南和按类型划分的参考表则位于两个同级文件中。
选择你需要的方向——仅阅读对应内容即可:
- 将ClickHouse返回的响应解码为JS值 → reader.md。涵盖流式处理与全缓冲、行对象与列存储、固定模式与运行时模式,以及按类型划分的读取器参考。
RowBinary* - 将JS值编码为负载以发送至ClickHouse → writer.md。包含
RowBinary/Sink构建块、writeX流式处理,以及按类型划分的写入器参考。writeRows
按类型划分的代码是真实可用的,按方向分别存放在和目录下。
src/readers/src/writers/First: is RowBinary even the right format?
首先:RowBinary 是合适的格式吗?
RowBinary exists for throughput, but it is not automatically the fastest
path — match the format to the shape of the data before committing to a
bespoke parser.
Prefer a format (e.g. ) when the result is mostly
strings / JSON-like values that you consume wholesale — randomly accessing
essentially every field, running string/regexp methods on them, treating values
as text. V8's native is heavily optimized C++ and builds JS strings
and objects faster than a JS-level RowBinary decoder can; pair it with HTTP
response compression ( / , which crushes JSON's repetitive keys) and
the wire cost shrinks too.
JSON*JSONEachRowJSON.parsegzipzstdRowBinary clearly wins when the result is dominated by:
- Wide numerics — /
Int128/Int256/UInt128,UInt256/Decimal128.Decimal256 - Binary / fixed-width blobs — ,
IPv4,IPv6,UUID.FixedString - High-volume fixed-width numeric columns generally, where each value is a
single read.
DataView
Prefer the format when columnar load and client-side analytics are
the main goal (fold/scan/filter columns, feed typed arrays to a Worker or WASM).
is column-major, so it loads straight into one typed array per column
with no transpose.
NativeNativeFor help choosing and consuming a format (or CSV / TSV) instead, use the
skill.
JSON*clickhouse-js-node-codingRowBinary专为吞吐量设计,但它并非自动是最快的路径——在决定定制解析器之前,要让格式与数据形态相匹配。
当结果主要是字符串/类JSON值且你需要整体消费时,优先选择格式(如)——比如需要随机访问几乎每个字段、对其执行字符串/正则表达式方法、将值视为文本处理。V8原生的是经过高度优化的C++实现,构建JS字符串和对象的速度比JS层面的RowBinary解码器更快;搭配HTTP响应压缩(/,可大幅压缩JSON重复的键),还能降低网络传输成本。
JSON*JSONEachRowJSON.parsegzipzstd当结果主要包含以下内容时,RowBinary 明显更具优势:
- 宽数值类型——/
Int128/Int256/UInt128、UInt256/Decimal128。Decimal256 - 二进制/固定宽度二进制大对象——、
IPv4、IPv6、UUID。FixedString - 高容量固定宽度数值列,通常每个值只需一次读取操作。
DataView
当列加载和客户端分析是主要目标时,优先选择格式(对列进行折叠/扫描/过滤,将类型化数组传入Worker或WASM)。是列优先的格式,因此可以直接加载到每列对应的类型化数组中,无需转置。
NativeNative如果需要帮助选择和使用格式(或CSV/TSV),请使用****技能。
JSON*clickhouse-js-node-codingCore guidance (both directions)
核心指南(双向通用)
These principles apply whether you are generating a reader or a writer; the
side-specific operational guidance is in reader.md /
writer.md.
-
Little-endian only. RowBinary is little-endian; target x86/ARM. Read and write every multi-byte number withaccessors passing a literal
DataViewfor thetrueflag.littleEndian -
Correct first, then optimize. First emit a correct codec built from the plain per-type API. Only after it's correct (and tested) specialize it. Don't bake performance assumptions in before correctness.
-
Monomorphize generic/composite types. Emit specialized, inlined code per type combination instead of passing functions as arguments where the type is known ahead of time.
-
Inline the leaf ops. The per-type/
readXfunctions are the correct, composable reference; the generated codec should INLINE their bodies, not call them, so the row loop is straight-line with no per-field indirection (and so the fixed-width coalescing can fold the offset arithmetic together).writeX -
Annotate the type per column. Inlining erases the type structure, so put a short comment above each column's encode/decode block naming the ClickHouse type it handles.
-
Shared scratch is not reentrant. Some hot methods reuse a module-level scratch buffer as a write-then-read pair — correct only because the access is fully synchronous. An/
asyncboundary between populating and reading it corrupts the value.yield -
TypeScript by default. Generate TypeScript code and helpers unless the user explicitly asks for plain JavaScript.
这些原则适用于生成读取器或写入器的场景;各方向的操作指南请查看reader.md/writer.md。
- 仅支持小端序。RowBinary采用小端序;目标平台为x86/ARM。读取和写入每个多字节数字时,使用访问器并为
DataView参数传入字面量littleEndian。true - 先保证正确性,再优化。首先基于简单的按类型API生成正确的编解码器。只有在确保正确(并经过测试)之后,再进行优化。不要在确保正确性之前就加入性能假设。
- 单态化泛型/复合类型。针对每种类型组合生成专门的内联代码,而不是在类型提前已知的情况下将函数作为参数传递。
- 内联叶子操作。按类型划分的/
readX函数是正确、可组合的参考实现;生成的编解码器应内联它们的主体代码,而非调用它们,这样行循环就是直线执行的,没有每个字段的间接调用(并且固定宽度合并可以将偏移量运算合并在一起)。writeX - 为每列标注类型。内联会擦除类型结构,因此在每列的编码/解码块上方添加简短注释,说明它处理的ClickHouse类型。
- 共享临时缓冲区不可重入。一些高频方法会复用模块级别的临时缓冲区作为写入-读取对——这仅在访问完全同步时才正确。如果在填充和读取之间存在/
async边界,会导致值损坏。yield - 默认使用TypeScript。生成TypeScript代码及辅助工具,除非用户明确要求纯JavaScript。
Worked examples
实战示例
Six end-to-end examples with real speedup are catalogued in EXAMPLES.md.
EXAMPLES.md中收录了六个端到端的示例,均实现了实际的性能提升。
Out of scope
超出范围的内容
- JSON / CSV / TSV / Parquet parsing → use .
clickhouse-js-node-coding - Connection errors, hangs, type mismatches → use
.
clickhouse-js-node-troubleshooting - Browser / Web Worker / Edge → .
@clickhouse/client-web
- JSON/CSV/TSV/Parquet解析 → 使用技能。
clickhouse-js-node-coding - 连接错误、挂起、类型不匹配 → 使用技能。
clickhouse-js-node-troubleshooting - 浏览器/Web Worker/Edge环境 → 使用。
@clickhouse/client-web