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/[email protected]/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