借助 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")
中的时间。
处理 Actor
和 MovieActor
类型中的多对多关系
处理完用户后,您可以继续对电影数据进行建模。
接下来,您希望有演员出演您的电影。
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]
(来自 movie
和 actor
的外键字段)的组合。
# 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 会生成 movie
、movies
、actors_on_movies
字段等。
使用
movie
字段进行查询
|
使用此字段按键查询单个电影。 query GetMovie($myKey: Movie_Key!) { movie(key: $myKey) { title } } |
使用
movies
字段进行查询
|
使用此字段可查询多部电影,例如指定年份的所有电影。 query GetMovies($myYear: Int!) { movies(where: { year: { eq: $myYear } }) { title } } |
使用
actors_on_movies
字段进行查询
|
使用此字段可查询与指定电影关联的所有演员。 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 注意:系统不会存储本地时区信息。 |
向量 | 自定义 | vector | 向量 |
- 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);
后续步骤
您可能感兴趣的内容: