تصميم مخطّطات 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) لتخصيص أسماء جداول وأعمدة SQL. تنشئ أداة Data Connect أسماء snake_case إذا لم يتم تحديدها.
  • @col(dataType) لتخصيص أنواع أعمدة SQL
  • @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 تلقائيًا على تجميعها من الحقول الرئيسية في المخططات. تتعلّق المقاييس الأساسية بالكفاءة، ما يتيح لك العثور في مكالمة واحدة على معلومات حول هوية بياناتك وبنيتها. وتكون هذه المعرّفات مفيدة بشكل خاص عندما تريد تنفيذ إجراءات متسلسلة على سجلات جديدة وتحتاج إلى معرّف فريد لتمريره إلى العمليات القادمة، وكذلك عندما تريد الوصول إلى المفاتيح العلائقية لتنفيذ عمليات إضافية أكثر تعقيدًا.

باستخدام قيم الخادم، يمكنك السماح للخادم بملء الحقول في جداولك بشكل ديناميكي باستخدام القيم المخزّنة أو التي يمكن حسابها بسهولة وفقًا لتعبيرات CEL معيّنة من جهة الخادم في الوسيطة 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 مع أنواع البيانات العددية التالية، مع عمليات التعيين لأنواع PostgreSQL باستخدام @col(dataType:).

Data Connect النوع نوع 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 (عدد حقيقي)
‫float8 (دقة مزدوجة)
numeric (عدد عشري)
قيمة منطقية GraphQL قيمة منطقية قيمة منطقية
معرِّف فريد عالمي (UUID) مخصص uuid uuid
Int64 مخصص bigint int8 (bigint, bigserial)
numeric (decimal)
تاريخ مخصص date التاريخ
الطابع الزمني مخصص timestamptz

timestamptz

ملاحظة: لا يتم تخزين معلومات المنطقة الزمنية المحلية.
تحوّل PostgreSQL هذه الطوابع الزمنية وتخزّنها بالتوقيت العالمي المنسَّق.

المتّجه مخصص vector

المتّجه

اطّلِع على إجراء بحث عن التشابه بين المتّجهات باستخدام Vertex AI.

  • تتم مطابقة GraphQL List مع صفيف أحادي البُعد.
    • على سبيل المثال، يتم ربط [Int] بـ int5[]، ويتم ربط [Any] بـ jsonb[].
    • لا يتيح Data Connect استخدام المصفوفات المتداخلة.

مخطط SQL المكافئ

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

الخطوات التالية

قد يهمّك الاطّلاع على ما يلي: