设计 Data Connect 架构

借助 Firebase Data Connect,您可以设计一个表示应用所需数据模型的 GraphQL 架构。Data Connect 将此架构转换为支持应用的 Cloud SQL for PostgreSQL 实例。然后,您编写查询和突变来与后端交互,并将这些操作捆绑到连接器中,以便从客户端代码中使用数据。

Data Connect 提供 AI 工具,帮助您设计和实现架构。本指南介绍了架构设计的重要概念,以便在您开始开发应用时以及之后支持和补充您的标准工作流和 AI 辅助工作流。

使用入门指南介绍了 PostgreSQL 的电影评论应用架构。

本指南将进一步开发该架构,并提供与最终电影评论应用架构等效的 SQL 列表

电影影评应用的架构

假设您想构建一项服务,让用户可以提交和查看电影影评。

您需要为这类应用提供初始架构,以支持基本查询。您稍后将扩展此架构,以创建复杂的关系型查询。

Data Connect 中,您将定义 GraphQL 类型,以定义客户端可以查询和操纵的数据的形状。编写架构时,您的类型会转换为 Cloud SQL for PostgreSQL 表,GraphQL 类型与数据库表之间通常存在直接关系,但也可以进行其他映射。本指南展示了一些示例,从基本示例到更高级的示例。

定义基本 Movie 类型

您可以从 Movie 类型开始。

Movie 的架构包含以下核心指令:

  • @table(name)@col(name) 可自定义 SQL 表和列名称。 如果未指定,Data Connect 会生成 snake_case 名称。
  • @col(dataType) 来自定义 SQL 列类型。
  • @default 在插入期间配置 SQL 列默认值。

如需了解详情,请参阅 @table@col@default 的参考文档。

# Movies
type Movie @table(name: "movie", key: "id") {
  id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
  title: String!
  releaseYear: Int
  genre: String @col(dataType: "varchar(20)")
  rating: Int
  description: String
}

自动将重要用户数据存储在 User 类型中

您的应用将跟踪用户,因此需要 User 类型。

在这种情况下,@default 指令尤其有用。此处的 id 字段可以自动从身份验证中获取用户 ID:请注意以下示例中 @default(expr: "auth.uid") 的用法。

# Users
# Suppose a user can leave reviews for movies
type User @table {
  id: String! @default(expr: "auth.uid")
  username: String! @col(dataType: "varchar(50)")
}

关键标量和服务器值

在深入了解电影评价应用之前,我们有必要先介绍一下 Data Connect 关键标量服务器值

键标量是简洁的对象标识符,Data Connect 会根据架构中的关键字段自动组装这些标识符。关键标量与效率有关,可让您通过一次调用即可找到有关数据身份和结构的信息。当您想对新记录执行一系列操作,需要一个唯一标识符来传递给后续操作时,以及当您想访问关系型键以执行其他更复杂的操作时,它们尤其有用。

借助服务器值,您可以让服务器根据 expr 实参中的特定服务器端 CEL 表达式,使用存储的值或可轻松计算的值动态填充表中的字段。例如,您可以定义一个字段,该字段在被访问时会应用时间戳,时间戳使用存储在操作请求 updatedAt: Timestamp! @default(expr: "request.time") 中的时间。

处理 ActorMovieActor 类型中的多对多关系

处理完用户后,您可以继续对电影数据进行建模。

接下来,您希望有演员出演您的电影。

Actor 表格非常简单。

# Actors
# Suppose an actor can participate in multiple movies and movies can have multiple actors
# Movie - Actors (or vice versa) is a many to many relationship
type Actor @table {
  id: UUID! @default(expr: "uuidV4()")
  name: String! @col(dataType: "varchar(30)")
}

如果您希望演员参演多部电影,并且电影有多位演员,则需要一个“联接表”。

MovieActor 表处理多对多关系,其主键是 [movie, actor](来自 movieactor 的外键字段)的组合。

# Join table for many-to-many relationship for movies and actors
# The 'key' param signifies the primary keys of this table
# In this case, the keys are [movieId, actorId], the foreign key fields of the reference fields [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
  movie: Movie!
  # movieId: UUID! <- implicitly added foreign key field
  actor: Actor!
  # actorId: UUID! <- implicitly added foreign key field
  role: String! # "main" or "supporting"
  # optional other fields
}

当您在具有外键限制条件的表上定义 SQL 关系时,Data Connect 会自动在另一侧生成相应的字段。您无需定义反向映射字段(例如,从 Actor 反向映射到 MovieActor)。

处理 MovieMetadata 类型中的一对一关系

现在,您可以跟踪电影导演,并与 Movie 建立一对一关系。

您可以使用 @ref 指令自定义外键限制条件:

  • @ref(fields) 用于指定要使用的外键字段。
  • @ref(references) 指定目标表中引用的字段(默认为主键,但 @unique 字段也适用)。这是一个更高级的选项;Data Connect 通常可以为您推断出此值。

如需了解详情,请参阅 @ref 的参考文档。

# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
  # @unique ensures that each Movie only has one MovieMetadata.
  movie: Movie! @unique
  # Since it references to another table type, it adds a foreign key constraint.
  #  movie: Movie! @unique @ref(fields: "movieId", references: "id")
  #  movieId: UUID! <- implicitly added foreign key field
  director: String
}

使用根据架构生成的字段来构建操作

您的 Data Connect 操作将扩展一组根据架构中的类型和类型关系自动生成的 Data Connect。每当您修改架构时,本地工具都会生成这些字段。

假设您的架构包含 Movie 类型和关联的 Actor 类型。Data Connect 会生成 moviemoviesactors_on_movies 字段等。

使用
movie 字段进行查询

movie 字段表示 Movie 表中的单条记录。

使用此字段按键查询单个电影。

query GetMovie($myKey: Movie_Key!) {
  movie(key: $myKey) { title }
}

使用
movies 字段进行查询

movies 字段表示 Movie 表中的记录列表。

使用此字段可查询多部电影,例如指定年份的所有电影。

query GetMovies($myYear: Int!) {
  movies(where: { year: { eq: $myYear } }) { title }
}

使用
actors_on_movies 字段进行查询

actors_on_movies 字段表示连接 ActorMovie 表的记录列表。使用此字段可查询与指定电影关联的所有演员。

使用此字段可查询与指定电影关联的所有演员。

  query GetActorsOnMovie($myKey: Movie_Key!) {
    actors_on_movies(where: { movie: { key: { eq: $myKey } } }) {
      actor { name }
    }
  }

考虑到这一点,您可以参阅查询实现指南突变实现指南,了解如何使用这些字段来实现操作。

更高级的架构概念

如需了解更多实用类型和关系,请参阅参考文档中的示例。

支持的数据类型

Data Connect 支持以下标量数据类型,并使用 @col(dataType:) 将其分配给 PostgreSQL 类型。

Data Connect type GraphQL 内置类型或
Data Connect 自定义类型
默认 PostgreSQL 类型 支持的 PostgreSQL 类型
(括号中为别名)
字符串 GraphQL text text
bit(n)、varbit(n)
char(n)、varchar(n)
整数 GraphQL 整数 Int2(smallint、smallserial)、
int4(integer、int、serial)
浮点数 GraphQL float8 float4(实数)
float8(双精度)
numeric(十进制)
布尔值 GraphQL 布尔值 布尔值
UUID 自定义 uuid uuid
Int64 自定义 bigint int8(bigint、bigserial)
numeric(十进制)
日期 自定义 date 日期
时间戳 自定义 timestamptz

timestamptz

注意:系统不会存储本地时区信息。
PostgreSQL 会将此类时间戳转换为世界协调时间 (UTC) 并存储。

向量 自定义 vector

向量

请参阅使用 Vertex AI 执行向量相似度搜索

  • GraphQL List 映射到一维数组。
    • 例如,[Int] 映射到 int5[][Any] 映射到 jsonb[]
    • Data Connect 不支持嵌套数组。

等效 SQL 架构

-- Movies Table
CREATE TABLE Movies (
    movie_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    release_year INT,
    genre VARCHAR(30),
    rating INT,
    description TEXT,
    tags TEXT[]
);
-- Movie Metadata Table
CREATE TABLE MovieMetadata (
    movie_id UUID REFERENCES Movies(movie_id) UNIQUE,
    director VARCHAR(255) NOT NULL,
    PRIMARY KEY (movie_id)
);
-- Actors Table
CREATE TABLE Actors (
    actor_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    name VARCHAR(30) NOT NULL
);
-- MovieActor Join Table for Many-to-Many Relationship
CREATE TABLE MovieActor (
    movie_id UUID REFERENCES Movies(movie_id),
    actor_id UUID REFERENCES Actors(actor_id),
    role VARCHAR(50) NOT NULL, # "main" or "supporting"
    PRIMARY KEY (movie_id, actor_id),
    FOREIGN KEY (movie_id) REFERENCES Movies(movie_id),
    FOREIGN KEY (actor_id) REFERENCES Actors(actor_id)
);
-- Users Table
CREATE TABLE Users (
    user_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    user_auth VARCHAR(255) NOT NULL
    username VARCHAR(30) NOT NULL
);
-- Reviews Table
CREATE TABLE Reviews (
    review_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    user_id UUID REFERENCES Users(user_id),
    movie_id UUID REFERENCES Movies(movie_id),
    rating INT,
    review_text TEXT,
    review_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE (movie_id, user_id)
    FOREIGN KEY (user_id) REFERENCES Users(user_id),
    FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
-- Self Join Example for Movie Sequel Relationship
ALTER TABLE Movies
ADD COLUMN sequel_to UUID REFERENCES Movies(movie_id);

后续步骤

您可能感兴趣的内容: