7 个版本
| 0.2.2-alpha.1 | 2023年10月6日 |
|---|---|
| 0.2.1 | 2023年7月24日 |
| 0.2.1-alpha.15 | 2023年7月19日 |
| 0.2.1-alpha.14 | 2023年6月10日 |
#738 在 数据库接口
每月64次下载
39KB
601 行
sqlite-ulid
SQLite 扩展,用于生成和使用 ULID。基于 sqlite-loadable-rs 和 ulid-rs 构建。
如果您的公司或组织认为这个库很有用,请考虑 支持我的工作!
用法
.load ./ulid0
select ulid(); -- '01gqr4j69cc7w1xdbarkcbpq17'
select ulid_bytes(); -- X'0185310899dd7662b8f1e5adf9a5e7c0'
select ulid_with_prefix('invoice'); -- 'invoice_01gqr4jmhxhc92x1kqkpxb8j16'
select ulid_with_datetime('2023-01-26 22:53:20.556); -- '01gqr4j69cc7w1xdbarkcbpq17'
select ulid_datetime('01gqr4j69cc7w1xdbarkcbpq17') -- '2023-01-26 22:53:20.556'
用作表的 PRIMARY KEY。
create table log_events(
id ulid primary key,
data any
);
insert into log_events(id, data) values (ulid(), 1);
insert into log_events(id, data) values (ulid(), 2);
insert into log_events(id, data) values (ulid(), 3);
select * from log_events;
/*
┌────────────────────────────┬──────┐
│ id │ data │
├────────────────────────────┼──────┤
│ 01gqr4vr487bytsf10ktfmheg4 │ 1 │
│ 01gqr4vr4dfcfk80m2yp6j866z │ 2 │
│ 01gqr4vrjxg0yex9jr0f100v1c │ 3 │
└────────────────────────────┴──────┘
*/
考虑使用 ulid_bytes() 以提高速度和减小 ID 的大小。它们生成的速度比 ulid() 快约 1.6 倍,占用 16 字节而不是 26 字节。您可以使用 ulid() 创建 BLOB ULID 的文本表示形式。
create table log_events(
id ulid primary key,
data any
);
insert into log_events(id, data) values (ulid_bytes(), 1);
insert into log_events(id, data) values (ulid_bytes(), 2);
insert into log_events(id, data) values (ulid_bytes(), 3);
select hex(id), ulid(id), data from log_events;
/*
┌──────────────────────────────────┬────────────────────────────┬──────┐
│ hex(id) │ ulid(id) │ data │
├──────────────────────────────────┼────────────────────────────┼──────┤
│ 0185F0539EBF286DA9F56BA4D9981783 │ 01gqr577nz51ptkxbbmkcsg5w3 │ 1 │
│ 0185F0539EC54F85745C1ECB64DF3A97 │ 01gqr577p59y2q8q0ysdjdyemq │ 2 │
│ 0185F0539ED48113F6F67BF3F6A4BFF7 │ 01gqr577pmg49zdxkvyfva9fzq │ 3 │
└──────────────────────────────────┴────────────────────────────┴──────┘
*/
使用 ulid_datetime() 提取 ULID 的时间戳组件。
select ulid_datetime(ulid()); -- '2023-01-26 23:07:36.508'
select unixepoch(ulid_datetime(ulid())); -- 1674774499
select strftime('%Y-%m-%d', ulid_datetime(ulid())); -- '2023-01-26''
考虑使用 ulid_with_prefix() 生成具有给定前缀的文本 ULID,以区分不同类型的 ID。
select ulid_with_prefix('customer'); -- 'customer_01gqr5j1ebk31wv30wgp8ebehj'
select ulid_with_prefix('product'); -- 'product_01gqr5prjgsa77dhrxf2dt1dgv'
select ulid_with_prefix('order'); -- 'order_01gqr5q35n68jk0sycy1ntr083'
快速基准测试
非决定性,在 Macbook 上匆忙运行,不代表实际使用案例。SQL 函数 uuid() 来自于 官方 uuid.c 扩展。
| 测试案例 | 时间 |
|---|---|
generate_series() 生成 100 万行 |
28.5 毫秒 ± 0.8 毫秒 (1x) |
调用 ulid_bytes() 一百万次 |
88.4 毫秒 ± 2.8 毫秒,慢 3.10 ± 0.13 |
调用 uuid() 一百万次 |
141.6 毫秒 ± 1.5 毫秒,或者慢 4.97 ± 0.15 |
调用 ulid() 一百万次 |
344.3 毫秒 ± 11.9 毫秒,或者慢 12.07 ± 0.53 |
所以 ulid_bytes() 相当快,但它返回的是一个不可读的blob,而不是一个格式良好的文本ID。这是由 ulid() 函数完成的,但它的速度比 uuid() 函数慢两倍以上。
然而,在 ~350ms 内生成一百万个 ulid() ID,对于大多数 SQLite 用例来说可能是“足够好”的。
与...
| 语言 | 安装 | |
|---|---|---|
| Python | pip 安装 sqlite-ulid |
|
| Datasette | datasette 安装 datasette-sqlite-ulid |
|
| Node.js | npm 安装 sqlite-ulid |
|
| Deno | deno.land/x/sqlite_ulid |
|
| Ruby | gem 安装 sqlite-ulid |
|
| Rust | cargo添加 sqlite-ulid |
|
| Github 发布 |
发布页面 Releases page 包含 Linux x86_64、MacOS 和 Windows 的预构建二进制文件。
Python
对于 Python 开发者,使用以下命令安装 sqlite-ulid 软件包
pip install sqlite-ulid
import sqlite3
import sqlite_ulid
db = sqlite3.connect(':memory:')
db.enable_load_extension(True)
sqlite_ulid.load(db)
db.execute('select ulid()').fetchone()
# ('01gr7gwc5aq22ycea6j8kxq4s9',)
有关更多信息,请参阅 python/sqlite_ulid
Node.js
对于 Node.js 开发者,使用以下命令安装 sqlite-ulid npm 软件包
npm install sqlite-ulid
import Database from "better-sqlite3";
import * as sqlite_ulid from "sqlite-ulid";
const db = new Database(":memory:");
db.loadExtension(sqlite_ulid.getLoadablePath());
有关更多信息,请参阅 npm/sqlite-ulid/README.md
Deno
对于 Deno 开发者,使用 deno.land/x/sqlite_ulid 模块
import { Database } from "https://deno.land/x/sqlite3@0.8.0/mod.ts";
import * as sqlite_ulid from "https://deno.land/x/sqlite_ulid@v${VERSION}/mod.ts";
const db = new Database(":memory:");
db.enableLoadExtension = true;
sqlite_ulid.load(db);
const [version] = db.prepare("select ulid_version()").value<[string]>()!;
console.log(version);
Datasette
对于 Datasette,使用以下命令安装 datasette-sqlite-ulid 插件
datasette install datasette-sqlite-ulid
有关更多详细信息,请参阅python/datasette_sqlite_ulid。
作为可加载扩展
如果您想将sqlite-ulid用作运行时加载的扩展,请下载ulid0.dylib(适用于MacOS),ulid0.so(Linux)或ulid0.dll(Windows)文件从发行版,并将其加载到您的SQLite环境中。
注意: 文件名中的
0(ulid0.dylib/ulid0.so/ulid0.dll)表示sqlite-ulid的主版本。目前sqlite-ulid是预v1版本,因此预计未来版本会有破坏性更改。
例如,如果您使用的是SQLite CLI,您可以按如下方式加载库
.load ./ulid0
select ulid_version();
-- v0.1.0
在Python中,您应该首选sqlite-ulid Python包。但是,您可以使用内置的sqlite3模块手动加载预编译的扩展
import sqlite3
con = sqlite3.connect(":memory:")
con.enable_load_extension(True)
con.load_extension("./ulid0")
print(con.execute("select ulid_version()").fetchone())
# ('v0.1.0',)
或者在Node.js中使用better-sqlite3
const Database = require("better-sqlite3");
const db = new Database(":memory:");
db.loadExtension("./ulid0");
console.log(db.prepare("select ulid_version()").get());
// { 'ulid_version()': 'v0.1.0' }
使用Datasette,您应该首选datasette-sqlite-ulid Datasette插件。但是,您可以手动将预编译的扩展加载到Datasette实例中,如下所示
datasette data.db --load-extension ./ulid0
支持
(亚历克斯 👋🏼)我为这个项目投入了大量的时间和精力,以及许多其他开源项目。如果您的公司或组织使用这个库(或者您很慷慨),那么请考虑支持我的工作,或者与朋友分享这个项目!
另请参阅
- sqlite-xsv,用于处理CSV的SQLite扩展
- sqlite-loadable,用于在Rust中编写SQLite扩展的框架
- sqlite-http,用于发送HTTP请求的SQLite扩展
依赖关系
~14MB
~260K SLoC