7 个版本

0.2.2-alpha.12023年10月6日
0.2.1 2023年7月24日
0.2.1-alpha.152023年7月19日
0.2.1-alpha.142023年6月10日

#738数据库接口

Download history 44/week @ 2024-03-23 5/week @ 2024-03-30

每月64次下载

MIT/Apache

39KB
601

sqlite-ulid

SQLite 扩展,用于生成和使用 ULID。基于 sqlite-loadable-rsulid-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 PyPI
Datasette datasette 安装 datasette-sqlite-ulid Datasette
Node.js npm 安装 sqlite-ulid npm
Deno deno.land/x/sqlite_ulid deno.land/x release
Ruby gem 安装 sqlite-ulid Gem
Rust cargo添加 sqlite-ulid Crates.io
Github 发布 GitHub tag (latest SemVer pre-release)

发布页面 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环境中。

注意: 文件名中的0ulid0.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

支持

(亚历克斯 👋🏼)我为这个项目投入了大量的时间和精力,以及许多其他开源项目。如果您的公司或组织使用这个库(或者您很慷慨),那么请考虑支持我的工作,或者与朋友分享这个项目!

另请参阅

依赖关系

~14MB
~260K SLoC