AI 与向量

结构化与非结构化数据

Supabase 足够灵活,可以将结构化和非结构化元数据与向量嵌入关联。


大多数向量存储将嵌入(embeddings)关联的元数据视为NoSQL非结构化数据。Supabase足够灵活,可以同时存储结构化和非结构化元数据。

结构化存储

1
2
3
4
5
6
7
8
9
10
11
create table docs ( id uuid primary key, embedding vector(3), content text, url text);insert into docs (id, embedding, content, url)values ('79409372-7556-4ccc-ab8f-5786a6cfa4f7', array[0.1, 0.2, 0.3], 'Hello world', '/hello-world');

注意我们为嵌入关联了两个元数据字段:contenturl。这些字段可以使用SQL的全部功能进行过滤、约束、索引和操作。结构化元数据与传统Supabase应用自然契合,可以通过数据库迁移来管理。

非结构化存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table docs ( id uuid primary key, embedding vector(3), meta jsonb);insert into docs (id, embedding, meta)values ( '79409372-7556-4ccc-ab8f-5786a6cfa4f7', array[0.1, 0.2, 0.3], '{"content": "Hello world", "url": "/hello-world"}' );

非结构化方法不预先定义元数据字段,而是将所有元数据存储在灵活的json/jsonb列中。代价是这种无模式数据类型的查询/过滤能力不如每个字段都有专用列时灵活。同时它也将元数据完整性的负担转移到了应用代码上,这比在数据库中强制约束更容易出错。

推荐在以下场景使用非结构化方法:

  • 临时/交互式工作负载,如数据科学或科学研究
  • 当元数据字段由用户定义或未知时
  • 快速原型开发阶段

像Python的vecs这样的客户端库就使用这种结构。例如运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3import vecs# 实际应用中,请不要硬编码密码。使用环境变量DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"# 创建向量存储客户端vx = vecs.create_client(DB_CONNECTION)docs = vx.get_or_create_collection(name="docs", dimension=1536)docs.upsert(vectors=[ ('79409372-7556-4ccc-ab8f-5786a6cfa4f7', [100, 200, 300], { url: '/hello-world' })])

在调用 get_or_create_collection 时会自动创建非结构化的 SQL 表。

请注意,当使用会生成 SQL DDL(如 create table ...)的客户端库时,在迁移到生产环境时应将该 SQL 添加到您的迁移文件中,以维护数据库模式的单一事实来源。

混合模式

当需要跟踪的字段已知时,推荐使用结构化元数据风格。如果您同时存在已知和未知的元数据字段,可以通过在表中添加 json/jsonb 列来容纳未知字段。在这种情况下,已知字段应继续使用专用列以获得最佳查询性能和吞吐量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create table docs ( id uuid primary key, embedding vector(3), content text, url string, meta jsonb);insert into docs (id, embedding, content, url, meta)values ( '79409372-7556-4ccc-ab8f-5786a6cfa4f7', array[0.1, 0.2, 0.3], 'Hello world', '/hello-world', '{"key": "value"}' );

选择合适的模型

两种方法都会创建一个用于存储嵌入向量和元数据的表。您应该根据具体用例选择最佳方法。总结如下:

  • 结构化元数据最适合字段已知或查询模式可预测的情况,例如生产环境的 Supabase 应用
  • 非结构化元数据最适合字段未知/用户定义或交互式处理数据的情况,例如探索性研究

两种方法都有效,具体选择取决于您的使用场景。