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

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

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

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

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

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

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

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

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

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

Movie टाइप से शुरू किया जा सकता है.

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

  • @table(name) और @col(name), ताकि SQL टेबल और कॉलम के नामों को पसंद के मुताबिक बनाया जा सके. अगर नाम नहीं दिया जाता है, तो 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 आर्ग्युमेंट में मौजूद सर्वर-साइड सीईएल एक्सप्रेशन के हिसाब से, सेव की गई या आसानी से कैलकुलेट की जा सकने वाली वैल्यू का इस्तेमाल किया जाता है. उदाहरण के लिए, किसी फ़ील्ड को ऐक्सेस करने पर लागू होने वाले टाइमस्टैंप के साथ फ़ील्ड तय किया जा सकता है. इसके लिए, ऑपरेशन अनुरोध, 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
}

जब किसी टेबल पर फ़ॉरेन-की की पाबंदी के साथ SQL संबंध तय किया जाता है, तो 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, यहां दिए गए स्केलर डेटा टाइप के साथ काम करता है. साथ ही, @col(dataType:) का इस्तेमाल करके PostgreSQL टाइप को असाइन करता है.

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

timestamptz

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

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

वेक्टर

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

अगले चरण

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