Data Connect स्कीमा डिज़ाइन करना

Firebase Data Connect की मदद से, एक GraphQL स्कीमा डिज़ाइन किया जाता है. यह स्कीमा, आपके ऐप्लिकेशन के लिए ज़रूरी डेटा मॉडल को दिखाता है. Data Connect इस स्कीमा को Cloud SQL for PostgreSQL इंस्टेंस में बदलता है, जो आपके ऐप्लिकेशन को बैकअप देता है. इसके बाद, बैकएंड के साथ इंटरफ़ेस करने के लिए क्वेरी और म्यूटेशन लिखे जाते हैं. साथ ही, इन कार्रवाइयों को कनेक्टर में बंडल किया जाता है, ताकि क्लाइंट कोड से आपके डेटा का इस्तेमाल किया जा सके.

Data Connect, एआई टूल उपलब्ध कराता है. इनकी मदद से, स्कीमा डिज़ाइन और लागू किए जा सकते हैं. इस गाइड में, स्कीमा डिज़ाइन के ज़रूरी कॉन्सेप्ट के बारे में बताया गया है. इससे आपको ऐप्लिकेशन डेवलप करना शुरू करते समय और इसके बाद, स्टैंडर्ड और एआई की मदद से किए जाने वाले वर्कफ़्लो को बेहतर बनाने और उनका इस्तेमाल करने में मदद मिलेगी.

शुरू करने के लिए गाइड में, PostgreSQL के लिए फ़िल्म की समीक्षा करने वाले ऐप्लिकेशन के स्कीमा के बारे में बताया गया है.

इस गाइड में, उस स्कीमा को और बेहतर बनाया गया है. साथ ही, इसमें फ़िल्म की समीक्षा करने वाले ऐप्लिकेशन के फ़ाइनल स्कीमा के बराबर SQL लिस्टिंग दी गई है.

फ़िल्म की समीक्षा करने वाले ऐप्लिकेशन का स्कीमा

मान लें कि आपको एक ऐसी सेवा बनानी है जिसकी मदद से लोग फ़िल्मों की समीक्षाएं सबमिट कर सकें और उन्हें देख सकें.

बुनियादी क्वेरी के लिए, आपको ऐसे ऐप्लिकेशन के लिए शुरुआती स्कीमा की ज़रूरत होती है. बाद में, इस स्कीमा को बढ़ाकर मुश्किल रिलेशनल क्वेरी बनाई जा सकती हैं.

Data Connect में, GraphQL टाइप तय किए जाते हैं. इससे, यह तय किया जाता है कि आपके क्लाइंट किस तरह के डेटा को क्वेरी कर सकते हैं और उसमें बदलाव कर सकते हैं. स्कीमा लिखते समय, आपके टाइप को Cloud SQL for PostgreSQL टेबल में बदल दिया जाता है. ज़्यादातर मामलों में, GraphQL टाइप और डेटाबेस टेबल के बीच सीधा संबंध होता है. हालांकि, अन्य मैपिंग भी की जा सकती हैं. इस गाइड में, बुनियादी से लेकर ज़्यादा बेहतर तरीके तक के कुछ उदाहरण दिए गए हैं.

बुनियादी Movie टाइप तय करना

Movie टाइप से शुरुआत की जा सकती है.

Movie के स्कीमा में ये मुख्य डायरेक्टिव शामिल हैं:

  • एसक्यूएल टेबल और कॉलम के नामों को पसंद के मुताबिक बनाने के लिए, @table(name) और @col(name) का इस्तेमाल करें. अगर नाम नहीं दिया जाता है, तो Data Connect snake_case नाम जनरेट करता है.
  • एसक्यूएल कॉलम के टाइप को पसंद के मुताबिक बनाने के लिए @col(dataType).
  • @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 फ़ील्ड, पुष्टि करने की प्रोसेस के दौरान उपयोगकर्ता का आईडी अपने-आप हासिल कर सकता है: इस सैंपल में @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
}

जब किसी टेबल पर फ़ॉरेन की कंस्ट्रेंट के साथ एसक्यूएल संबंध तय किया जाता है, तो 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 फ़ील्ड के साथ क्वेरी

movie फ़ील्ड, Movie टेबल में एक रिकॉर्ड दिखाता है.

इस फ़ील्ड का इस्तेमाल, किसी फ़िल्म की कुंजी के हिसाब से क्वेरी करने के लिए करें.

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 के गिनती वाले टाइप से मैप होते हैं. इनम की मदद से, पहले से तय की गई स्टैटिक वैल्यू की सूची को किसी खास क्रम में तुरंत तय किया जा सकता है.

अपने स्कीमा में कोई enum जोड़ने के लिए, enum और उसकी पहले से तय की गई वैल्यू का एलान करें. इसके बाद, उसे अपने टाइप में रेफ़रंस करें.

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
}

Movie टाइप में, हमने एक एनम फ़ील्ड originalAspectRatio जोड़ा है. यह फ़ील्ड, उस आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) के लिए है जिसमें फ़िल्म बनाई गई थी. साथ ही, हमने एक और फ़ील्ड otherAspectRatios जोड़ा है. यह फ़ील्ड, अन्य उपलब्ध आसपेक्ट रेशियो की सूची के लिए है.

गिनती वाले फ़ील्ड में किए गए बदलावों को मैनेज करना

अपने इनम में नई वैल्यू जोड़ी जा सकती हैं. हालांकि, इनम की सूची का क्रम बहुत मायने रखता है. इसलिए, नई वैल्यू सोच-समझकर डालें. किसी enum में सिर्फ़ एक ऐसा बदलाव किया जा सकता है जो पिछले वर्शन के साथ पूरी तरह से काम करता हो. वह बदलाव यह है कि वैल्यू की सूची के आखिर में नई वैल्यू जोड़ना. ध्यान दें कि पहले से पब्लिश किए गए enum के बीच नई वैल्यू डालने या मौजूदा वैल्यू का क्रम बदलने से, क्वेरी में "इससे कम" जैसे रिलेटिव ऑपरेटर इस्तेमाल करने पर, रिलेटिव ऑर्डर बदल जाता है. वैल्यू को हटाना या उनका नाम बदलना, हमेशा पिछले वर्शन के साथ काम न करने वाला बदलाव होता है.

आपको enum वैल्यू की सूची में वैल्यू का क्रम कभी नहीं बदलना चाहिए. क्रम इसलिए ज़रूरी है, क्योंकि इससे फ़िल्टर करने का तरीका बदल जाता है.

इनम वैल्यू में बदलाव सावधानी से किए जाने चाहिए, ताकि आपके ऑपरेशन या क्लाइंट कोड के पुराने वर्शन काम करना बंद न कर दें. किसी enum वैल्यू को हटाने या उसका नाम बदलने से पहले, पक्का करें कि आपके मौजूदा डेटाबेस में उसके कोई इंस्टेंस मौजूद न हों.

ऑपरेशन और क्लाइंट कोड में अपने enum फ़ील्ड का इस्तेमाल करना

आपने अपने स्कीमा में एक enum फ़ील्ड जोड़ दिया है. अब इस फ़ील्ड का इस्तेमाल, क्वेरी और क्लाइंट कोड में किया जा सकता है.

इनम का इस्तेमाल करके क्वेरी लिखने के बारे में ज़्यादा जानें. साथ ही, क्वेरी गाइड में जाकर, क्लाइंट को अपने इनम में बदलाव करने की अनुमति देने के तरीके के बारे में जानें.

अन्य ऐडवांस कॉन्सेप्ट

बुनियादी लेकिन काम के टाइप और रिलेशनशिप के बारे में ज़्यादा जानने के लिए, रेफ़रंस दस्तावेज़ में दिए गए उदाहरण देखें.

डेटा टाइप, जो इस्तेमाल किए जा सकते हैं

Data Connect इन स्केलर डेटा टाइप के साथ काम करता है. साथ ही, @col(dataType:) का इस्तेमाल करके, PostgreSQL टाइप को असाइनमेंट किए जा सकते हैं.

Data Connect type GraphQL में पहले से मौजूद टाइप या
Data Connect कस्टम टाइप
PostgreSQL का डिफ़ॉल्ट टाइप PostgreSQL के साथ काम करने वाले टाइप
(ब्रैकेट में दिया गया दूसरा नाम)
स्ट्रिंग GraphQL टेक्स्ट text
bit(n), varbit(n)
char(n), varchar(n)
Int GraphQL int Int2 (smallint, smallserial),
int4 (integer, int, serial)
फ़्लोट GraphQL float8 float4 (real)
float8 (double precision)
numeric (decimal)
बूलियन GraphQL बूलियन बूलियन
यूयूआईडी कस्टम uuid uuid
Int64 कस्टम bigint int8 (bigint, bigserial)
numeric (decimal)
तारीख कस्टम date तारीख
टाइमस्टैम्प कस्टम timestamptz

timestamptz

ध्यान दें: स्थानीय समय क्षेत्र की जानकारी सेव नहीं की जाती है.
PostgreSQL, इस तरह के टाइमस्टैंप को यूटीसी में बदलता है और सेव करता है.

इन्यूमरेशन कस्टम enum

enum

वेक्टर कस्टम vector

वेक्टर

Vertex AI की मदद से, वेक्टर के आधार पर मिलती-जुलती जानकारी खोजने की सुविधा इस्तेमाल करना लेख पढ़ें.

  • GraphQL List, एक डाइमेंशन वाले ऐरे पर मैप करता है.
    • उदाहरण के लिए, [Int] को int5[] पर मैप किया जाता है और [Any] को jsonb[] पर मैप किया जाता है.
    • Data Connect में नेस्ट किए गए ऐरे का इस्तेमाल नहीं किया जा सकता.

एसक्यूएल स्कीमा के बराबर

-- 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);

अगले चरण

आपकी इनमें दिलचस्पी हो सकती है: