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 がスキーマのキー フィールドから自動的に組み立てる簡潔なオブジェクト識別子です。キー スカラーは効率性に関するもので、1 回の呼び出しでデータの ID と構造に関する情報を見つけることができます。これらは、新しいレコードに対して順次アクションを実行し、今後のオペレーションに渡す一意の識別子が必要な場合や、リレーショナル キーにアクセスしてより複雑なオペレーションを実行する場合に特に便利です。

サーバー値を使用すると、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]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 型で 1 対 1 の関係を処理する

次に、映画監督を追跡し、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 テーブル内の 1 つのレコードを表します。

このフィールドを使用して、キーで 1 つの映画をクエリします。

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 フィールドは、Actor テーブルと Movie テーブルを接続するレコードのリストを表します。このフィールドを使用して、特定の映画に関連付けられているすべての俳優をクエリします。

このフィールドを使用して、特定の映画に関連付けられているすべての俳優をクエリします。

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

これらのフィールドを使用してオペレーションを実装する方法については、クエリの実装ガイドミューテーションの実装ガイドをご覧ください。

より高度なスキーマのコンセプト

基本的なタイプと関係を超えて、より有用なタイプと関係を使用するには、リファレンス ドキュメントの例をご覧ください。

サポートされるデータ型

Data Connect は、次のスカラー データ型をサポートしています。PostgreSQL 型への割り当てには @col(dataType:) を使用します。

Data Connect GraphQL 組み込み型または
Data Connect カスタム型
デフォルトの PostgreSQL タイプ サポートされている PostgreSQL の型
(エイリアスはかっこで囲まれています)
文字列 GraphQL テキスト text
bit(n)、varbit(n)
char(n)、varchar(n)
Int GraphQL 整数 Int2(smallint、smallserial)、
int4(integer、int、serial)
浮動小数点数 GraphQL float8 float4(実数)
float8(倍精度)
numeric(10 進数)
ブール値 GraphQL ブール値 ブール値
UUID カスタム uuid uuid
Int64 カスタム bigint int8(bigint、bigserial)
numeric(decimal)
日付 カスタム date 日付
タイムスタンプ カスタム timestamptz

timestamptz

注: ローカル タイムゾーン情報は保存されません。
PostgreSQL は、このようなタイムスタンプを変換して UTC として保存します。

ベクトル カスタム vector

ベクトル

Vertex AI でベクトル類似度検索を行うをご覧ください。

  • GraphQL の List は 1 次元配列にマッピングされます。
    • たとえば、[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);

次のステップ

関連情報: