Mit Firebase SQL Connect entwerfen Sie ein GraphQL-Schema, das das für Ihre Anwendung erforderliche Datenmodell darstellt. SQL Connect konvertiert dieses Schema in die Cloud SQL for PostgreSQL-Instanz, die Ihre Anwendung unterstützt. Anschließend erstellen Sie Abfragen und Mutationen, um mit dem Backend zu interagieren, und bündeln diese Vorgänge in Connectors, um Ihre Daten aus dem Clientcode zu verwenden.
SQL Connect bietet KI-Tools, mit denen Sie Ihre Schemas entwerfen und implementieren können. In diesem Leitfaden werden wichtige Konzepte des Schemadesigns vorgestellt, die Ihre Standard- und KI-gestützten Workflows unterstützen und ergänzen, wenn Sie mit der Entwicklung einer Anwendung beginnen und darüber hinaus.
Im Startleitfaden wurde ein Schema für eine Filmrezensions-App für PostgreSQL vorgestellt.
In diesem Leitfaden wird dieses Schema weiterentwickelt und eine SQL-Auflistung bereitgestellt, die dem endgültigen Schema der Filmrezensions-App entspricht.
Das Schema für eine Filmkritik-App
Stellen Sie sich vor, Sie möchten einen Dienst erstellen, mit dem Nutzer Filmrezensionen einreichen und ansehen können.
Sie benötigen ein erstes Schema für eine solche Anwendung, um einfache Abfragen zu unterstützen. Sie werden dieses Schema später erweitern, um komplexe relationale Abfragen zu erstellen.
In SQL Connect definieren Sie GraphQL-Typen, um die Form der Daten zu definieren, die Ihre Clients abfragen und bearbeiten können. Wenn Sie Ihr Schema schreiben, werden Ihre Typen in Cloud SQL für PostgreSQL-Tabellen übersetzt, meist in einer direkten Beziehung zwischen GraphQL-Typen und Datenbanktabellen, obwohl auch andere Zuordnungen möglich sind. In diesem Leitfaden finden Sie einige Beispiele, von einfach bis fortgeschritten.
Einfachen Movie-Typ definieren
Sie können mit einem Movie-Typ beginnen.
Das Schema für Movie enthält wichtige Anweisungen wie:
@table(name)und@col(name), um die SQL-Tabellen- und Spaltennamen anzupassen. SQL Connect generiert snake_case-Namen, wenn nichts angegeben ist.@col(dataType), um SQL-Spaltentypen anzupassen.@default, um SQL-Spaltenstandardwerte beim Einfügen zu konfigurieren.
Weitere Informationen finden Sie in den Referenzdokumenten für @table, @col und @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
}
Wichtige Nutzerdaten automatisch in einem User-Typ speichern
Ihre App muss Nutzer im Blick behalten, daher benötigen Sie einen User-Typ.
Die Anweisung @default ist in diesem Fall besonders nützlich. Das Feld id kann die ID des Nutzers automatisch aus der Authentifizierung abrufen. Beachten Sie die Verwendung von @default(expr: "auth.uid") im folgenden Beispiel.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
Wichtige Skalare und Serverwerte
Bevor wir uns die Filmrezensions-App genauer ansehen, ist es wichtig, SQL Connect Schlüsselskalare und Serverwerte vorzustellen.
Schlüsselskalare sind prägnante Objektkennungen, die SQL Connect automatisch aus Schlüsselfeldern in Ihren Schemas zusammenstellt. Schlüsselskalare sind effizient, da Sie mit einem einzigen Aufruf Informationen zur Identität und Struktur Ihrer Daten abrufen können. Sie sind besonders nützlich, wenn Sie sequenzielle Aktionen für neue Datensätze ausführen möchten und eine eindeutige Kennung benötigen, die an anstehende Vorgänge übergeben werden soll, und wenn Sie auf relationale Schlüssel zugreifen möchten, um zusätzliche komplexere Vorgänge auszuführen.
Mit Serverwerten können Sie den Server Felder in Ihren Tabellen dynamisch mit gespeicherten oder leicht berechenbaren Werten füllen lassen, die bestimmten serverseitigen CEL-Ausdrücken im Argument expr entsprechen. Sie können beispielsweise ein Feld mit einem Zeitstempel definieren, der angewendet wird, wenn auf das Feld mit der in einer Vorgangsanfrage gespeicherten Zeit updatedAt: Timestamp!
@default(expr: "request.time") zugegriffen wird.
N:N-Beziehungen in Actor- und MovieActor-Typen verarbeiten
Nachdem Sie die Nutzerdaten verarbeitet haben, können Sie sich wieder der Modellierung von Filmdaten widmen.
Als Nächstes brauchen Sie Schauspieler für Ihre Filme.
Die Tabelle Actor ist ziemlich einfach.
# 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)")
}
Wenn Schauspieler in mehreren Filmen mitspielen und Filme mehrere Schauspieler haben sollen, benötigen Sie eine „Join-Tabelle“.
Die Tabelle MovieActor verarbeitet die n:m-Beziehung und ihr Primärschlüssel ist eine Kombination aus [movie, actor] (den Fremdschlüsselfeldern aus movie und 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
}
Wenn Sie eine SQL-Beziehung für die Tabelle mit einer Fremdschlüsseleinschränkung definieren, generiert SQL Connect automatisch das entsprechende Feld auf der anderen Seite. Sie müssen das Feld für die umgekehrte Zuordnung (z.B. von Actor zurück zu MovieActor) nicht definieren.
1-zu-1-Beziehungen in einem MovieMetadata-Typ verarbeiten
Jetzt können Sie die Regisseure der Filme im Blick behalten und eine 1:1-Beziehung mit Movie einrichten.
Mit der Anweisung @ref können Sie Fremdschlüsseleinschränkungen anpassen:
@ref(fields)gibt an, welche Fremdschlüsselfelder verwendet werden sollen.@ref(references)gibt die Felder an, auf die in der Zieltabelle verwiesen wird (standardmäßig der Primärschlüssel, aber@unique-Felder funktionieren auch). Dies ist eine erweiterte Option. SQL Connect kann dies oft für Sie ableiten.
Weitere Informationen finden Sie in der Referenzdokumentation zu @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
}
Vorgänge mit Feldern erstellen, die aus Ihrem Schema generiert wurden
Ihre SQL Connect-Vorgänge erweitern eine Reihe von Feldern, die automatisch von SQL Connect basierend auf den Typen und Typbeziehungen in Ihrem Schema generiert werden. Diese Felder werden von lokalen Tools generiert, wenn Sie Ihr Schema bearbeiten.
Angenommen, Ihr Schema enthält einen Movie-Typ und einen zugehörigen Actor-Typ.
SQL Connect generiert unter anderem die Felder movie, movies und actors_on_movies.
Mit dem Feld
movie abfragen
|
Das Feld |
Verwenden Sie dieses Feld, um einen einzelnen Film anhand seines Schlüssels abzufragen. query GetMovie($myKey: Movie_Key!) { movie(key: $myKey) { title } } |
Mit dem Feld
movies abfragen
|
Das Feld |
Verwenden Sie dieses Feld, um mehrere Filme abzufragen, z. B. alle Filme eines bestimmten Jahres. query GetMovies($myYear: Int!) { movies(where: { year: { eq: $myYear } }) { title } } |
Mit dem Feld
actors_on_movies abfragen
|
Das Feld |
Mit diesem Feld können Sie alle Schauspieler abfragen, die mit einem bestimmten Film verknüpft sind. query GetActorsOnMovie($myKey: Movie_Key!) { actors_on_movies(where: { movie: { key: { eq: $myKey } } }) { actor { name } } } |
In diesem Sinne können Sie im Leitfaden zur Implementierung von Abfragen und im Leitfaden zur Implementierung von Mutationen nachlesen, wie Sie Vorgänge mit diesen Feldern implementieren.
Erweiterte Schemakonzepte
Aufzählungsfelder
SQL Connect unterstützt Aufzählungsfelder, die PostgreSQL-Aufzählungstypen zugeordnet sind. Mit Enums können Sie schnell eine Liste statischer, vordefinierter Werte mit einer bestimmten Reihenfolge definieren.
Wenn Sie Ihrem Schema ein Enum hinzufügen möchten, deklarieren Sie das Enum und seine vordefinierten Werte und verweisen Sie dann in Ihrem Typ darauf.
enum AspectRatio {
ACADEMY
WIDESCREEN
ANAMORPHIC
IMAX
"No information available on aspect ratio"
UNAVAILABLE
}
type Movie
@table {
title: String!
genre: String
description: String
originalAspectRatio: AspectRatio! @default(value: WIDESCREEN)
otherAspectRatios: [AspectRatio!]
tags: [String]
rating: Float
imageUrl: String!
releaseYear: Int
}
Im Typ Movie haben wir ein Enum-Feld originalAspectRatio für das Seitenverhältnis, in dem der Film gedreht wurde, und ein weiteres Feld otherAspectRatios für eine Liste anderer verfügbarer Seitenverhältnisse hinzugefügt.
Änderungen an Aufzählungsfeldern verwalten
Sie können Ihrem Enum neue Werte hinzufügen. Die Reihenfolge der Enum-Liste ist jedoch sehr wichtig. Fügen Sie Ihre neuen Werte daher mit Bedacht ein. Die einzige vollständig abwärtskompatible Änderung an einem Enum ist das Hinzufügen eines neuen Werts am Ende der Werteliste. Insbesondere das Einfügen eines neuen Werts zwischen zuvor veröffentlichten Enums oder das Neuanordnen vorhandener Werte ändert die relative Reihenfolge, wenn relative Operatoren wie „kleiner als“ in Abfragen verwendet werden. Das Entfernen oder Umbenennen von Werten ist immer eine abwärtsinkompatible Änderung.
Sie sollten die Werte in der Liste der Enum-Werte niemals neu anordnen. Die Reihenfolge ist wichtig, da sie sich auf die Anwendung der Filterung auswirkt.
Anpassungen an Enum-Werten sollten sorgfältig vorgenommen werden, damit ältere Versionen Ihres Vorgangs- oder Clientcodes nicht beschädigt werden. Wenn Sie einen enum-Wert entfernen oder umbenennen, achten Sie darauf, dass in Ihrer aktuellen Datenbank keine Instanzen mehr vorhanden sind.
Enum-Felder in Vorgängen und im Clientcode verwenden
Nachdem Sie Ihrem Schema ein Enum-Feld hinzugefügt haben, können Sie dieses Feld in Abfragen und Clientcode verwenden.
Weitere Informationen zum Schreiben von Abfragen mit Enums und zum Schreiben von Clients, um Anpassungen an Ihren Enums zuzulassen, finden Sie im Leitfaden zu Abfragen.
Weitere erweiterte Konzepte
Wenn Sie über grundlegende, aber nützliche Typen und Beziehungen hinausgehen möchten, finden Sie Beispiele in der Referenzdokumentation.
Unterstützte Datentypen
SQL Connect unterstützt die folgenden skalaren Datentypen, wobei die Zuweisung zu PostgreSQL-Typen mit @col(dataType:) erfolgt.
| SQL Connect-Typ | Integrierter GraphQL-Typ oder benutzerdefinierter -Typ von SQL Connect |
PostgreSQL-Standardtyp | Unterstützte PostgreSQL-Typen (Alias in Klammern) |
|---|---|---|---|
| String | GraphQL | Text | text bit(n), varbit(n) char(n), varchar(n) |
| Integer | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
| Float | GraphQL | float8 | float4 (real) float8 (double precision) numeric (decimal) |
| Boolesch | GraphQL | boolean | boolean |
| UUID | Benutzerdefiniert | uuid | uuid |
| Int64 | Benutzerdefiniert | bigint | int8 (bigint, bigserial) numeric (decimal) |
| Datum | Benutzerdefiniert | date | Datum |
| Zeitstempel | Benutzerdefiniert | timestamptz | timestamptz Hinweis: Informationen zur lokalen Zeitzone werden nicht gespeichert. |
| Aufzählung | Benutzerdefiniert | enum | enum |
| Vektor | Benutzerdefiniert | vector | Vektor |
- GraphQL-
Listwird einem eindimensionalen Array zugeordnet.- Beispiel:
[Int]wirdint5[]zugeordnet,[Any]wirdjsonb[]zugeordnet. - SQL Connect unterstützt keine verschachtelten Arrays.
- Beispiel:
Äquivalentes SQL-Schema
-- 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);
Nächste Schritte
Folgendes könnte Sie auch interessieren:
- Schemas für Ihre Anwendungen mit KI-Unterstützungstools generieren
- Referenzdokumentation zur Syntax lesen