Firebase Data Connect, Google Cloud SQL ile yönetilen PostgreSQL örnekleriniz için bağlayıcılar oluşturmanıza olanak tanır. Bu bağlayıcılar, verilerinizi kullanmak için şema, sorgu ve mutasyon kombinasyonlarıdır.
Başlangıç kılavuzunda PostgreSQL için bir e-posta uygulaması şeması tanıtılmıştı. Bu kılavuzda ise artık motive edici örnek olarak bir film incelemesi veritabanı kullanılarak PostgreSQL için Data Connect şemalarının nasıl tasarlanacağı daha ayrıntılı bir şekilde ele alınıyor.
Bu kılavuzda Data Connect sorguları ve mutasyonları şema örnekleriyle birlikte verilmiştir. Data Connect şemalarıyla ilgili bir rehberde neden sorgular (ve mutasyonlar) ele alınıyor? Diğer GraphQL tabanlı platformlar gibi, Firebase Data Connect sorgu öncelikli bir geliştirme platformudur. Bu nedenle, geliştirici olarak veri modellemenizde müşterilerinizin ihtiyaç duyduğu verileri göz önünde bulundurursunuz. Bu da projeniz için geliştirdiğiniz veri şemasını büyük ölçüde etkiler.
Bu kılavuz, film incelemeleri için yeni bir şemayla başlıyor, ardından bu şemadan türetilen sorguları ve değişiklikleri ele alıyor ve son olarak temel Data Connect şemasına eşdeğer bir SQL listesi sunuyor.
Film inceleme uygulaması şeması
Kullanıcıların film yorumları göndermesine ve görüntülemesine olanak tanıyan bir hizmet oluşturmak istediğinizi düşünün.
Bu tür bir uygulama için başlangıç şemasına ihtiyacınız vardır. Daha sonra karmaşık ilişkisel sorgular oluşturmak için bu şemayı genişleteceksiniz.
Film tablosu
Filmler şeması aşağıdaki gibi temel yönergeleri içerir:
@table,singularvepluralbağımsız değişkenlerini kullanarak işlem adları ayarlamamıza olanak tanır.@colile sütun adlarını açıkça ayarlayabilirsiniz.@defaultadlı çocuğun varsayılanları ayarlamasına izin verin.
# Movies
type Movie
@table(name: "Movies", singular: "movie", plural: "movies", key: ["id"]) {
id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
title: String!
releaseYear: Int @col(name: "release_year")
genre: String
rating: Int @col(name: "rating")
description: String @col(name: "description")
}
Sunucu değerleri ve anahtar skalerleri
Film inceleme uygulamasına bakmadan önce Data Connect sunucu değerlerini ve anahtar ölçeklerini tanıtalım.
Sunucu değerlerini kullanarak, belirli sunucu tarafı ifadelerine göre depolanmış veya kolayca hesaplanabilen değerleri kullanarak sunucunun tablolarınızdaki alanları dinamik olarak doldurmasına etkili bir şekilde izin verebilirsiniz. Örneğin, updatedAt: Timestamp! @default(expr: "request.time") ifadesini kullanarak alana erişildiğinde uygulanan bir zaman damgasıyla alanı tanımlayabilirsiniz.
Anahtar ölçekler, şemalarınızdaki anahtar alanlardan Data Connect otomatik olarak oluşturulan kısa nesne tanımlayıcılarıdır. Önemli ölçekler, verilerinizin kimliği ve yapısı hakkında tek bir çağrıda bilgi bulmanıza olanak tanıyarak verimlilik sağlar. Bu işlevler, özellikle yeni kayıtlarda sıralı işlemler gerçekleştirmek istediğinizde ve yaklaşan işlemlere aktarılacak benzersiz bir tanımlayıcıya ihtiyaç duyduğunuzda, ayrıca ek ve daha karmaşık işlemler gerçekleştirmek için ilişkisel anahtarlara erişmek istediğinizde yararlıdır.
Kimlik türü
GraphQL'de ID türü, String olarak serileştirilen opak bir tür olarak tanımlanır. GraphQL, kimlik biçiminden bağımsızdır ancak girişten gelen dizeleri ve tam sayıları zorunlu olarak dönüştürür.
PostgreSQL anahtarları genellikle tam sayılardır veya UUID'lerdir, dizeler değildir.
Data Connect bu tür anahtarları şemanızdan otomatik olarak oluşturur. @default yönergesiyle anahtar oluşturma işlemini özelleştirebilirsiniz. Bu işlem, İşlemi Gerçekleştiren Kullanıcı tablosunun id alan tanımında gösterilmiştir: id: ID! … @default(generate: "UUID").
Film meta verileri tablosu
Şimdi de film yönetmenlerini takip edelim ve Movie ile bire bir ilişki kuralım.
İlişkileri tanımlamak için @ref yönergesini ekleyin.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata
@table(
name: "MovieMetadata"
) {
# @ref creates a field in the current table (MovieMetadata) that holds the
# primary key of the referenced type
# In this case, @ref(fields: "id") is implied
movie: Movie! @ref
# movieId: UUID <- this is created by the above @ref
director: String @col(name: "director")
}
Actor ve MovieActor
Ardından, filmlerinizde rol alacak aktörler istersiniz. Filmler ve aktörler arasında çoka-çok ilişki olduğundan bir birleştirme tablosu oluşturun.
# 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(name: "Actors", singular: "actor", plural: "actors") {
id: UUID! @col(name: "actor_id") @default(expr: "uuidV4()")
name: String! @col(name: "name", dataType: "varchar(30)")
}
# Join table for many-to-many relationship for movies and actors
# The 'key' param signifies the primary key(s) of this table
# In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
# @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
# In this case, @ref(fields: "id") is implied
movie: Movie! @ref
# movieId: UUID! <- this is created by the above @ref, see: implicit.gql
actor: Actor! @ref
# actorId: UUID! <- this is created by the above @ref, see: implicit.gql
role: String! @col(name: "role") # "main" or "supporting"
# optional other fields
}
Kullanıcı
Son olarak, uygulamanızın kullanıcıları.
# Users
# Suppose a user can leave reviews for movies
# user:reviews is a one to many relationship, movie:reviews is a one to many relationship, movie:user is a many to many relationship
type User
@table(name: "Users", singular: "user", plural: "users", key: ["id"]) {
id: UUID! @col(name: "user_id") @default(expr: "uuidV4()")
auth: String @col(name: "user_auth") @default(expr: "auth.uid")
username: String! @col(name: "username", dataType: "varchar(30)")
# The following are generated from the @ref in the Review table
# reviews_on_user
# movies_via_Review
}
Desteklenen veri türleri
Data Connect, @col(dataType:) kullanılarak PostgreSQL türlerine atamalarla birlikte aşağıdaki skaler veri türlerini destekler.
| Data Connect type | Yerleşik GraphQL türü veya Data Connect özel tür |
Varsayılan PostgreSQL türü | Desteklenen PostgreSQL türleri (parantez içindeki diğer ad) |
|---|---|---|---|
| Dize | GraphQL | metin | text bit(n), varbit(n) char(n), varchar(n) |
| Int | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
| Kayan | GraphQL | float8 | float4 (real) float8 (double precision) numeric (decimal) |
| Boole | GraphQL | boolean | boolean |
| UUID | Özel | uuid | uuid |
| Int64 | Özel | bigint | int8 (bigint, bigserial) numeric (decimal) |
| Tarih | Özel | date | tarih |
| Zaman damgası | Özel | timestamptz | timestamptz Not: Yerel saat dilimi bilgileri depolanmaz. |
| Numaralandırma | Özel | enum | enum |
| Vector | Özel | vector | vektör Vertex AI ile vektör benzerliği araması yapma başlıklı makaleyi inceleyin. |
- GraphQL
Listtek boyutlu bir diziyle eşlenir.- Örneğin,
[Int],int5[]ile,[Any]isejsonb[]ile eşlenir. - Data Connect iç içe dizileri desteklemez.
- Örneğin,
Örtülü ve önceden tanımlanmış sorgular ve mutasyonlar
Data Connect sorgularınız ve mutasyonlarınız, Data Connect tarafından şemanızdaki türlere ve tür ilişkilerine göre oluşturulan bir dizi örtülü sorguyu ve örtülü mutasyonu genişletir. Şemanızı her düzenlediğinizde yerel araçlar tarafından örtülü sorgular ve mutasyonlar oluşturulur.
Geliştirme sürecinizde, bu örtülü işlemlere dayalı olarak önceden tanımlanmış sorgular ve önceden tanımlanmış mutasyonlar uygulayacaksınız.
Örtülü sorgu ve mutasyon adlandırması
Data Connect, şema türü bildirimlerinizden yola çıkarak örtülü sorgular ve mutasyonlar için uygun adlar çıkarır. Örneğin, PostgreSQL kaynağıyla çalışırken Movie adlı bir tablo tanımlarsanız sunucu şu örtülü işlemleri gerçekleştirir:
- Tek tablolu kullanım alanları için
movie(tekil,eqgibi bağımsız değişkenleri ileterek ayrı sonuçları almak için) vemovies(çoğul,gtgibi bağımsız değişkenleri ileterek veorderbygibi işlemleri yaparak sonuç listelerini almak için) kolay adlarıyla sorgular. Data Connect ayrıcaactors_on_moviesveyaactors_via_actormoviegibi açık adlarla çok tablolu, ilişkisel işlemler için de sorgular oluşturur. movie_insert,movie_upsert... adlı mutasyonlar
Şema tanımı dili, singular ve plural yönerge bağımsız değişkenlerini kullanarak işlemler için adları açıkça ayarlamanıza da olanak tanır.
Film eleştirisi veritabanı için sorgular
Data Connect sorgusunu; sorgu işlemi türü bildirimi, işlem adı, sıfır veya daha fazla işlem bağımsız değişkeni ve sıfır ya da daha fazla yönerge ile bağımsız değişkenler kullanarak tanımlarsınız.
Hızlı başlangıç kılavuzundaki örnek listEmails sorgusu parametre içermiyordu. Elbette, birçok durumda sorgu alanlarına iletilen veriler dinamik olacaktır. Değişkenlerle sorgu tanımının bileşenlerinden biri olarak çalışmak için $variableName söz dizimini kullanabilirsiniz.
Bu nedenle, aşağıdaki sorguda:
querytürü tanımıListMoviesByGenreişlemi (sorgu) adı- Tek değişkenli
$genreişlem bağımsız değişkeni - Tek bir yönerge,
@auth.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
Her sorgu bağımsız değişkeni için bir tür bildirimi, yerleşik bir tür (ör. String) veya özel, şemada tanımlanmış bir tür (ör. Movie) gerekir.
Giderek karmaşıklaşan sorguların imzasını inceleyelim. Önceden tanımlanmış sorgularınızda kullanabileceğiniz, güçlü ve kısa ilişki ifadelerini tanıtarak bitireceksiniz.
Sorgulardaki temel skalerler
Ancak öncelikle önemli ölçekler hakkında bir not.
Data Connect, _Key ile tanımlanan anahtar skalerleri için özel bir tür tanımlar. Örneğin, Movie tablomuz için anahtar skalerinin türü Movie_Key'dir.
Çoğu örtülü mutasyon tarafından döndürülen bir yanıt olarak veya tabii ki skaler anahtarı oluşturmak için gereken tüm alanları aldığınız sorgulardan önemli skalerleri alırsınız.
Çalışan örneğimizdeki movie gibi tekil otomatik sorgular, bir anahtar skalerini kabul eden bir anahtar bağımsız değişkenini destekler.
Bir anahtar ölçeğini değişmez değer olarak iletebilirsiniz. Ancak, geçiş anahtarı skalerlerini giriş olarak iletmek için değişkenler tanımlayabilirsiniz.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
Bunlar, istek JSON'ında aşağıdaki gibi (veya diğer serileştirme biçimlerinde) sağlanabilir:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
Özel skaler ayrıştırma sayesinde, değişkenler içerebilen nesne söz dizimi kullanılarak da Movie_Key oluşturulabilir. Bu özellik, genellikle tek tek bileşenleri bir nedenden dolayı farklı değişkenlere ayırmak istediğinizde yararlıdır.
Sorgularda diğer ad kullanma
Data Connect, sorgularda GraphQL takma adını destekler. Diğer adlar sayesinde, bir sorgunun sonuçlarında döndürülen verileri yeniden adlandırabilirsiniz. Tek bir Data Connect sorgusu, sunucuya tek bir verimli istekte birden fazla filtre veya başka sorgu işlemi uygulayabilir ve aynı anda etkili bir şekilde birkaç "alt sorgu" yayınlayabilir. Döndürülen veri kümesinde ad çakışmalarını önlemek için alt sorguları ayırt etmek üzere takma adlar kullanırsınız.
Aşağıda, bir ifadenin mostPopular takma adını kullandığı bir sorgu verilmiştir.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
Filtre içeren basit sorgular
Data Connect sorguları, tüm yaygın SQL filtreleri ve sıralama işlemleriyle eşlenir.
where ve orderBy operatörleri (tekil ve çoğul sorgular)
Tablodaki (ve iç içe yerleştirilmiş ilişkilerdeki) tüm eşleşen satırları döndürür. Filtreyle eşleşen kayıt yoksa boş bir dizi döndürür.
query MovieByTopRating($genre: String) {
mostPopular: movies(
where: { genre: { eq: $genre } }, orderBy: { rating: DESC }
) {
# graphql: list the fields from the results to return
id
title
genre
description
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
limit ve offset operatörleri (tekil ve çoğul sorgular)
Sonuçlarda sayfalara ayırma işlemi yapabilirsiniz. Bu bağımsız değişkenler kabul edilir ancak sonuçlarda döndürülmez.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
dizi alanları için içerir
Bir dizi alanının belirtilen öğeyi içerip içermediğini test edebilirsiniz.
# Filter using arrays and embedded fields.
query ListMoviesByTag($tag: String!) {
movies(where: { tags: { includes: $tag }}) {
# graphql: list the fields from the results to return
id
title
}
}
Dize işlemleri ve normal ifadeler
Sorgularınızda normal ifadeler de dahil olmak üzere normal dize arama ve karşılaştırma işlemleri kullanılabilir. Verimlilik için burada birkaç işlemi paketlediğinizi ve bunları takma adlarla netleştirdiğinizi unutmayın.
query MoviesTitleSearch($prefix: String, $suffix: String, $contained: String, $regex: String) {
prefixed: movies(where: {title: {startsWith: $prefix}}) {...}
suffixed: movies(where: {title: {endsWith: $suffix}}) {...}
contained: movies(where: {title: {contains: $contained}}) {...}
matchRegex: movies(where: {title: {pattern: {regex: $regex}}}) {...}
}
or ve and birleştirilmiş filtreler için
Daha karmaşık mantık için or ve and işlevlerini kullanın.
query ListMoviesByGenreAndGenre($minRating: Int!, $genre: String) {
movies(
where: { _or: [{ rating: { ge: $minRating } }, { genre: { eq: $genre } }] }
) {
# graphql: list the fields from the results to return
title
}
}
Karmaşık sorgular
Data Connect sorguları, tablolar arasındaki ilişkilere göre verilere erişebilir. Şemanızda tanımlanan nesne (bire bir) veya dizi (bire çok) ilişkilerini kullanarak iç içe yerleştirilmiş sorgular oluşturabilir, yani bir türdeki verileri iç içe yerleştirilmiş veya ilişkili bir türdeki verilerle birlikte getirebilirsiniz.
Bu tür sorgular, oluşturulan örtülü sorgularda sihirli Data Connect _on_ ve _via söz dizimini kullanır.
İlk sürümümüzdeki şemada değişiklikler yapacaksınız.
Çoktan bire
Review tablosu ve User üzerinde değişiklikler yaparak uygulamamıza yorum ekleyelim.
# Users
# Suppose a user can leave reviews for movies
# user:reviews is a one to many relationship,
# movie:reviews is a one to many relationship,
# movie:user is a many to many relationship
type User
@table(name: "Users", singular: "user", plural: "users", key: ["id"]) {
id: UUID! @col(name: "user_id") @default(expr: "uuidV4()")
auth: String @col(name: "user_auth") @default(expr: "auth.uid")
username: String! @col(name: "username", dataType: "varchar(30)")
# The following are generated from the @ref in the Review table
# reviews_on_user
# movies_via_Review
}
# Reviews
type Review @table(name: "Reviews", key: ["movie", "user"]) {
id: UUID! @col(name: "review_id") @default(expr: "uuidV4()")
user: User! @ref
movie: Movie! @ref
rating: Int
reviewText: String
reviewDate: Date! @default(expr: "request.time")
}
Çoktan bire sorgu
Şimdi de _via_ söz dizimini göstermek için diğer adlandırma içeren bir sorguya bakalım.
query UserMoviePreferences($username: String!) @auth(level: USER) {
users(where: { username: { eq: $username } }) {
likedMovies: movies_via_review(where: { rating: { ge: 4 } }) {
title
genre
description
}
dislikedMovies: movies_via_review(where: { rating: { le: 2 } }) {
title
genre
description
}
}
}
Bire bir
Deseni görebilirsiniz. Aşağıda, şema açıklama amacıyla değiştirilmiştir.
# Movies
type Movie
@table(name: "Movies", singular: "movie", plural: "movies", key: ["id"]) {
id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
title: String!
releaseYear: Int @col(name: "release_year")
genre: String
rating: Int @col(name: "rating")
description: String @col(name: "description")
tags: [String] @col(name: "tags")
}
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata
@table(
name: "MovieMetadata"
) {
# @ref creates a field in the current table (MovieMetadata) that holds the primary key of the referenced type
# In this case, @ref(fields: "id") is implied
movie: Movie! @ref
# movieId: UUID <- this is created by the above @ref
director: String @col(name: "director")
}
extend type MovieMetadata {
movieId: UUID! # matches primary key of referenced type
...
}
extend type Movie {
movieMetadata: MovieMetadata # can only be non-nullable on ref side
# conflict-free name, always generated
movieMetadatas_on_movie: MovieMetadata
}
Bire bir sorgu
_on_ söz dizimini kullanarak sorgu oluşturabilirsiniz.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
Çoka çok
Filmlerin oyunculara, oyuncuların da filmlere ihtiyacı vardır. Aralarında, MovieActors birleştirme tablosuyla modelleyebileceğiniz çoka çok ilişki vardır.
# MovieActors Join Table Definition
type MovieActors @table(
key: ["movie", "actor"] # join key triggers many-to-many generation
) {
movie: Movie!
actor: Actor!
}
# generated extensions for the MovieActors join table
extend type MovieActors {
movieId: UUID!
actorId: UUID!
}
# Extensions for Actor and Movie to handle many-to-many relationships
extend type Movie {
movieActors: [MovieActors!]! # standard many-to-one relation to join table
actors: [Actor!]! # many-to-many via join table
movieActors_on_actor: [MovieActors!]!
# since MovieActors joins distinct types, type name alone is sufficiently precise
actors_via_MovieActors: [Actor!]!
}
extend type Actor {
movieActors: [MovieActors!]! # standard many-to-one relation to join table
movies: [Movie!]! # many-to-many via join table
movieActors_on_movie: [MovieActors!]!
movies_via_MovieActors: [Movie!]!
}
Çoka çok sorgusu
_via_ söz dizimini göstermek için diğer adlandırma içeren bir sorguya bakalım.
query GetMovieCast($movieId: UUID!, $actorId: UUID!) @auth(level: PUBLIC) {
movie(id: $movieId) {
mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) {
name
}
supportingActors: actors_via_MovieActor(
where: { role: { eq: "supporting" } }
) {
name
}
}
actor(id: $actorId) {
mainRoles: movies_via_MovieActor(where: { role: { eq: "main" } }) {
title
}
supportingRoles: movies_via_MovieActor(
where: { role: { eq: "supporting" } }
) {
title
}
}
}
Film eleştirisi veritabanı için değişiklikler
Belirtildiği gibi, şemanızda bir tablo tanımladığınızda Data Connect, her tablo için temel örtülü mutasyonlar oluşturur.
type Movie @table { ... }
extend type Mutation {
# Insert a row into the movie table.
movie_insert(...): Movie_Key!
# Upsert a row into movie."
movie_upsert(...): Movie_Key!
# Update a row in Movie. Returns null if a row with the specified id/key does not exist
movie_update(...): Movie_Key
# Update rows based on a filter in Movie.
movie_updateMany(...): Int!
# Delete a single row in Movie. Returns null if a row with the specified id/key does not exist
movie_delete(...): Movie_Key
# Delete rows based on a filter in Movie.
movie_deleteMany(...): Int!
}
Bu yöntemlerle, giderek daha karmaşık hale gelen temel CRUD işlemlerini uygulayabilirsiniz. Bunu beş kez hızlıca söyleyin.
Oluştur
Temel oluşturma işlemlerini yapalım.
# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
movie_insert(data: {
title: $title
releaseYear: $releaseYear
genre: $genre
rating: $rating
})
}
# Create a movie with default values
mutation CreateMovie2 {
movie_insert(data: {
title: "Sherlock Holmes"
releaseYear: 2009
genre: "Mystery"
rating: 5
})
}
Veya upsert işlemi.
# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
movie_upsert(data: {
title: $title
releaseYear: 2009
genre: "Mystery"
rating: 5
genre: "Mystery/Thriller"
})
}
Güncellemeleri gerçekleştirme
Güncellemeler Yapımcılar ve yönetmenler, ortalama puanların bu trende uygun olmasını umar.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id, data: {
genre: $genre
rating: $rating
description: $description
})
}
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $ratingIncrement: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
update: { rating: { inc: $ratingIncrement } }
)
}
Silme işlemlerini gerçekleştirme
Elbette film verilerini silebilirsiniz. Film koruma uzmanları, fiziksel filmlerin mümkün olduğunca uzun süre korunmasını ister.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
Burada _deleteMany kullanabilirsiniz.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
İlişkilerde değişiklik yazma
Bir ilişkide örtülü _upsert mutasyonunun nasıl kullanılacağını inceleyin.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
Eşdeğer SQL şeması
-- 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);
Sırada ne var?
- Otomatik olarak oluşturulan web SDK, Android SDK, iOS SDK ve Flutter SDK'dan sorgularınızı ve mutasyonlarınızı nasıl çağıracağınızı öğrenin.