Con Firebase Data Connect, progetti uno schema GraphQL che rappresenta il modello di dati richiesto per la tua applicazione. Data Connect converte questo schema nell'istanza Cloud SQL per PostgreSQL che supporta la tua app. Poi crei query e mutazioni per interfacciarti con il backend e raggruppi queste operazioni in connettori per utilizzare i dati dal codice client.
Data Connect offre strumenti di AI per aiutarti a progettare e implementare gli schemi. Questa guida introduce concetti importanti di progettazione dello schema per supportare e integrare i tuoi workflow standard e assistiti dall'AI quando inizi a sviluppare un'app e oltre.
La Guida introduttiva ha introdotto uno schema di app di recensioni di film per PostgreSQL.
Questa guida sviluppa ulteriormente lo schema e fornisce un elenco SQL equivalente allo schema finale dell'app di recensioni di film.
Lo schema per un'app di recensioni di film
Immagina di voler creare un servizio che consenta agli utenti di inviare e visualizzare recensioni di film.
Per supportare le query di base, devi disporre di uno schema iniziale per l'app. In seguito estenderai questo schema per creare query relazionali complesse.
In Data Connect, definirai i tipi GraphQL per definire la forma dei dati che i tuoi client possono interrogare e manipolare. Quando scrivi lo schema, i tipi vengono tradotti in tabelle Cloud SQL per PostgreSQL, il più delle volte in una relazione diretta tra i tipi GraphQL e le tabelle del database, anche se sono possibili altre mappature. Questa guida mostra alcuni esempi di base e più avanzati.
Definisci un tipo Movie
di base
Puoi iniziare con un tipo di Movie
.
Lo schema per Movie
contiene direttive di base come:
@table(name)
e@col(name)
per personalizzare i nomi di tabelle e colonne SQL. Se non specificati, Data Connect genera nomi in formato snake_case.@col(dataType)
per personalizzare i tipi di colonne SQL.@default
per configurare i valori predefiniti delle colonne SQL durante l'inserimento.
Per ulteriori dettagli, consulta la documentazione di riferimento per @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
}
Archivia automaticamente i dati utente importanti in un tipo User
La tua app monitorerà gli utenti, quindi hai bisogno di un tipo User
.
La direttiva @default
è particolarmente utile in questo caso. Il campo id
qui
può recuperare automaticamente l'ID utente dall'autenticazione: nota l'utilizzo di @default(expr: "auth.uid")
nell'esempio seguente.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
Scalari chiave e valori del server
Prima di esaminare più da vicino l'app di recensioni di film, è importante introdurre gli Data Connect scalari chiave e i valori del server.
Gli scalari chiave sono identificatori di oggetti concisi che Data Connect vengono assemblati automaticamente dai campi chiave negli schemi. Gli scalari chiave riguardano l'efficienza, in quanto ti consentono di trovare in una singola chiamata informazioni sull'identità e sulla struttura dei tuoi dati. Sono particolarmente utili quando vuoi eseguire azioni sequenziali sui nuovi record e hai bisogno di un identificatore univoco da passare alle operazioni imminenti, nonché quando vuoi accedere alle chiavi relazionali per eseguire operazioni aggiuntive più complesse.
Utilizzando i valori del server, puoi consentire al server di compilare dinamicamente
i campi delle tabelle utilizzando valori archiviati o facilmente calcolabili in base
a particolari espressioni CEL lato server nell'argomento expr
. Ad esempio, puoi definire un campo con un timestamp applicato quando si accede al campo utilizzando l'ora memorizzata in una richiesta di operazione, updatedAt: Timestamp!
@default(expr: "request.time")
.
Gestire le relazioni molti-a-molti nei tipi Actor
e MovieActor
Ora che hai gestito gli utenti, puoi tornare alla modellazione dei dati dei film.
Poi, vuoi che gli attori recitino nei tuoi film.
La tabella Actor
è piuttosto semplice.
# 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)")
}
Se vuoi che gli attori partecipino a più film e che i film abbiano più attori, ti servirà una "tabella di unione".
La tabella MovieActor
gestisce la relazione molti-a-molti e la sua chiave primaria è una combinazione di [movie, actor]
(i campi di chiave esterna di movie
e 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
}
Quando definisci una relazione SQL nella tabella con un vincolo di chiave esterna,
Data Connect genera automaticamente il campo corrispondente sull'altro lato. Non è necessario definire il campo di mapping inverso (ad es. da
Actor
a MovieActor
).
Gestire le relazioni one-to-one in un tipo MovieMetadata
Ora puoi monitorare i registi dei film e configurare una relazione uno a uno con Movie
.
Puoi utilizzare la direttiva @ref
per personalizzare i vincoli di chiave esterna:
@ref(fields)
specifica quali campi di chiave esterna utilizzare.@ref(references)
specifica i campi a cui viene fatto riferimento nella tabella di destinazione (il valore predefinito è la chiave primaria, ma funzionano anche i campi@unique
). Questa è un'opzione più avanzata; Data Connect spesso può dedurlo per te.
Per ulteriori dettagli, consulta la documentazione di riferimento per @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
}
Utilizzare i campi generati dallo schema per creare operazioni
Le operazioni Data Connect estenderanno un insieme di campi generati automaticamente Data Connect in base ai tipi e alle relazioni tra i tipi nello schema. Questi campi vengono generati dagli strumenti locali ogni volta che modifichi lo schema.
Supponiamo che lo schema contenga un tipo Movie
e un tipo Actor
associato.
Data Connect genera i campi movie
, movies
,
actors_on_movies
e altri ancora.
Query con il campo
movie
Il campo |
Utilizza questo campo per eseguire query su un singolo film in base alla relativa chiave. query GetMovie($myKey: Movie_Key!) { movie(key: $myKey) { title } } |
Query con il campo
movies
Il campo |
Utilizza questo campo per eseguire query su più film, ad esempio tutti i film di un determinato anno. query GetMovies($myYear: Int!) { movies(where: { year: { eq: $myYear } }) { title } } |
Query con il campo
actors_on_movies
Il campo |
Utilizza questo campo per eseguire query su tutti gli attori associati a un determinato film. query GetActorsOnMovie($myKey: Movie_Key!) { actors_on_movies(where: { movie: { key: { eq: $myKey } } }) { actor { name } } } |
Tenendo presente questo, puoi leggere come implementare le operazioni utilizzando questi campi nella guida all'implementazione delle query e nella guida all'implementazione delle mutazioni.
Concetti più avanzati dello schema
Per andare oltre i tipi e le relazioni di base ma utili, consulta gli esempi nella documentazione di riferimento.
Tipi di dati supportati
Data Connect supporta i seguenti tipi di dati scalari, con
assegnazioni ai tipi PostgreSQL utilizzando @col(dataType:)
.
Data Connect type | Tipo incorporato GraphQL o tipo personalizzatoData Connect |
Tipo PostgreSQL predefinito | Tipi PostgreSQL supportati (alias tra parentesi) |
---|---|---|---|
Stringa | GraphQL | testo | text bit(n), varbit(n) char(n), varchar(n) |
Int | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
In virgola mobile | GraphQL | float8 | float4 (real) float8 (double precision) numeric (decimal) |
Booleano | GraphQL | booleano | booleano |
UUID | Personalizzato | uuid | uuid |
Int64 | Personalizzato | bigint | int8 (bigint, bigserial) numeric (decimal) |
Data | Personalizzato | date | data |
Timestamp | Personalizzato | timestamptz | timestamptz Nota:le informazioni sul fuso orario locale non vengono memorizzate. |
Vettoriale | Personalizzato | vector | vettore Consulta Eseguire la ricerca di similarità vettoriale con Vertex AI. |
- GraphQL
List
viene mappato a un array unidimensionale.- Ad esempio,
[Int]
corrisponde aint5[]
,[Any]
corrisponde ajsonb[]
. - Data Connect non supporta gli array nidificati.
- Ad esempio,
Schema SQL equivalente
-- 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);
Passaggi successivi
Potrebbe interessarti:
- Generare schemi per le tue app utilizzando gli strumenti di assistenza AI
- Consultando la documentazione di riferimento per la sintassi.