Skip to content
AI & Vectors

结构化与非结构化

Supabase is flexible enough to associate structured and unstructured metadata with embeddings.

大多数向量存储将与嵌入相关的元数据视为类似 NoSQL 的非结构化数据。Supabase 足够灵活,可以存储非结构化和结构化的元数据。

🌐 Most vector stores treat metadata associated with embeddings like NoSQL, unstructured data. Supabase is flexible enough to store unstructured and structured metadata.

有条理的 #

🌐 Structured

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

注意,我们已经将两个元数据字段 contenturl 关联到这个嵌入中。这些字段可以使用 SQL 的全部功能进行过滤、限制、索引以及其他操作。结构化元数据与传统的 Supabase 应用天然契合,并且可以通过数据库 迁移 来管理。

🌐 Notice that we've associated two pieces of metadata, content and url, with the embedding. Those fields can be filtered, constrained, indexed, and generally operated on using the full power of SQL. Structured metadata fits naturally with a traditional Supabase application, and can be managed via database migrations.

无结构的 #

🌐 Unstructured

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

非结构化方法不会指定预期的元数据字段。它将所有元数据存储在灵活的 json/jsonb 列中。这样做的代价是,无模式数据类型的查询/过滤能力不如每个字段都有专用列时灵活。同时,这也把元数据完整性的责任推给了应用代码,而这比在数据库中强制约束更容易出错。

🌐 An unstructured approach does not specify the metadata fields that are expected. It stores all metadata in a flexible json/jsonb column. The tradeoff is that the querying/filtering capabilities of a schemaless data type are less flexible than when each field has a dedicated column. It also pushes the burden of metadata data integrity onto application code, which is more error prone than enforcing constraints in the database.

建议采用非结构化的方法:

🌐 The unstructured approach is recommended:

  • 用于短暂/交互式工作负载,例如数据科学或科学研究
  • 当元数据字段是用户自定义或未知时
  • 在快速原型制作期间

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

🌐 Client libraries like python's vecs use this structure. For example, running:

1
#!/usr/bin/env python3
2
import vecs
3
4
# In practice, do not hard-code your password. Use environment variables.
5
DB_CONNECTION = "postgresql://<user>:<password>@<host>:<port>/<db_name>"
6
7
# create vector store client
8
vx = vecs.create_client(DB_CONNECTION)
9
10
docs = vx.get_or_create_collection(name="docs", dimension=1536)
11
12
docs.upsert(vectors=[
13
('79409372-7556-4ccc-ab8f-5786a6cfa4f7', [100, 200, 300], { url: '/hello-world' })
14
])

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

🌐 automatically creates the unstructured SQL table during the call to get_or_create_collection.

请注意,当使用像 create table ... 这样的客户端库生成 SQL DDL 时,你应该在迁移到生产环境时将这些 SQL 添加到迁移文件中,以保持数据库模式的单一可信来源。

🌐 Note that when working with client libraries that emit SQL DDL, like create table ..., you should add that SQL to your migrations when moving to production to maintain a single source of truth for your database's schema.

混合 #

🌐 Hybrid

当要跟踪的字段是已知时,建议使用结构化元数据样式。如果你有已知和未知元数据字段的组合,可以通过在表中添加 json/jsonb 列来容纳未知字段。在这种情况下,已知字段应继续使用专用列,以获得最佳的查询性能和吞吐量。

🌐 The structured metadata style is recommended when the fields being tracked are known in advance. If you have a combination of known and unknown metadata fields, you can accommodate the unknown fields by adding a json/jsonb column to the table. In that situation, known fields should continue to use dedicated columns for best query performance and throughput.

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

选择合适的模型 #

🌐 Choosing the right model

这两种方法都会创建一个表格,让你可以存储嵌入和一些元数据。你应该根据自己的使用情况选择最合适的方法。总之:

🌐 Both approaches create a table where you can store your embeddings and some metadata. You should choose the best approach for your use-case. In summary:

  • 当字段事先已知或查询模式可预测时,结构化元数据是最好的,例如一个正在运行的 Supabase 应用。
  • 当字段未知/用户自定义,或者在互动式处理数据时(例如探索性研究),非结构化元数据是最好的选择

两种方法都是可行的,你选择哪一种取决于你的使用场景。

🌐 Both approaches are valid, and the one you should choose depends on your use-case.