生成列

存储型(或持久化)生成列:这些列会在行插入或更新时计算其值,并将结果存储在数据库中。这使它们可以被索引,并且由于每次查询时不需要重新计算这些值,因此可以提升查询性能。

数据库端

类型:仅 STORED

工作原理

能力

限制

更多信息请查看 PostgreSQL 文档

Drizzle 端

在 Drizzle 中,你可以在任何列类型上指定 .generatedAlwaysAs() 函数,并添加受支持的 SQL 查询, 这样就会为你生成该列的数据。

功能

此函数可以通过两种方式接受生成表达式:

sql 标签 - 如果你希望 drizzle 帮你转义某些值

export const test = pgTable("test", {
    generatedName: text("gen_name").generatedAlwaysAs(sql`'hello "world"!'`),
});
CREATE TABLE "test" (
    "gen_name" text GENERATED ALWAYS AS ('hello "world"!') STORED
);

callback - 如果你需要引用表中的列

export const test = pgTable("test", {
    name: text("first_name"),
    generatedName: text("gen_name").generatedAlwaysAs(
      (): SQL => sql`'hi, ' || ${test.name} || '!'`
    ),
});
CREATE TABLE "test" (
    "first_name" text,
    "gen_name" text GENERATED ALWAYS AS ('hi, ' || "test"."first_name" || '!') STORED
);

示例 带全文搜索的生成列

schema.ts
import { SQL, sql } from "drizzle-orm";
import { customType, index, integer, pgTable, text } from "drizzle-orm/pg-core";

const tsVector = customType<{ data: string }>({
  dataType() {
    return "tsvector";
  },
});

export const test = pgTable(
  "test",
  {
    id: integer("id").primaryKey().generatedAlwaysAsIdentity(),
    content: text("content"),
    contentSearch: tsVector("content_search", {
      dimensions: 3,
    }).generatedAlwaysAs(
      (): SQL => sql`to_tsvector('english', ${test.content})`
    ),
  },
  (t) => [
    index("idx_content_search").using("gin", t.contentSearch)
  ]
);
CREATE TABLE "test" (
	"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "test_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
	"content" text,
	"content_search" tsvector GENERATED ALWAYS AS (to_tsvector('english', "test"."content")) STORED
);

CREATE INDEX "idx_content_search" ON "test" USING gin ("content_search");