تصميم مخططات SQL Connect

باستخدام Firebase SQL Connect، يمكنك تصميم مخطط GraphQL يمثّل نموذج البيانات المطلوب لتطبيقك. يحوّل SQL Connect هذا المخطط إلى مثيل Cloud SQL لـ PostgreSQL الذي يدعم تطبيقك. بعد ذلك، يمكنك إنشاء طلبات بحث وعمليات تحويل للتفاعل مع الخلفية وتجميع هذه العمليات في موصلات لاستخدام بياناتك من رمز العميل.

يوفّر SQL Connect أدوات ذكاء اصطناعي لمساعدتك في تصميم المخططات وتنفيذها. يقدّم هذا الدليل مفاهيم مهمة حول تصميم المخططات لدعم مهام سير العمل العادية وتلك المستندة إلى الذكاء الاصطناعي وتكملتها عند بدء تطوير تطبيق، و غير ذلك.

قدّم دليل البدء مخطّطًا لتطبيق مراجعات الأفلام في PostgreSQL.

يقدّم هذا الدليل مزيدًا من التفاصيل حول هذا المخطّط، كما يوفّر قائمة SQL مكافئة للمخطّط النهائي لتطبيق مراجعات الأفلام.

مخطّط تطبيق لمراجعة الأفلام

لنفترض أنّك تريد إنشاء خدمة تتيح للمستخدمين إرسال مراجعات الأفلام وعرضها.

أنت بحاجة إلى مخطط أولي لمثل هذا التطبيق لدعم الاستعلامات الأساسية. ستقوم بتوسيع هذا المخطط لاحقًا لإنشاء استعلامات علائقية معقدة.

في SQL Connect، ستحدّد أنواع GraphQL لتحديد شكل البيانات التي يمكن لعملائك طلبها ومعالجتها. عند كتابة المخطط، تتم ترجمة الأنواع إلى Cloud SQL لجداول PostgreSQL، وغالبًا ما تكون هناك علاقة مباشرة بين أنواع GraphQL وجداول قاعدة البيانات، على الرغم من إمكانية إجراء عمليات ربط أخرى. يعرض هذا الدليل بعض الأمثلة من الأساسية إلى الأكثر تقدّمًا.

تحديد نوع Movie أساسي

يمكنك البدء بنوع Movie.

يتضمّن مخطط Movie توجيهات أساسية مثل:

  • ‫@table(name) و@col(name) لتخصيص أسماء الجداول والأعمدة في SQL تنشئ السمة SQL 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)")
}

القيم العددية الرئيسية وقيم الخادم

قبل الاطّلاع على المزيد من المعلومات حول تطبيق مراجعات الأفلام، من المهم التعرّف على SQL Connect القيم العددية الرئيسية وقيم الخادم.

القيم العددية الرئيسية هي معرّفات موجزة للعناصر يجمعها SQL 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 في الجدول باستخدام قيد مفتاح خارجي، تنشئ SQL Connect تلقائيًا الحقل المقابل على الجانب الآخر. لست بحاجة إلى تحديد حقل الربط العكسي (على سبيل المثال، من Actor إلى MovieActor).

التعامل مع العلاقات بين فردين في نوع MovieMetadata

الآن، تتبَّع مخرجي الأفلام، وأنشئ علاقة واحد لواحد مع Movie.

يمكنك استخدام التوجيه @ref لتخصيص قيود المفاتيح الخارجية:

  • يحدّد @ref(fields) حقول المفاتيح الخارجية التي يجب استخدامها.
  • يحدّد @ref(references) الحقول المُشار إليها في الجدول المستهدَف (يتم ضبطه تلقائيًا على المفتاح الأساسي، ولكن يمكن استخدام حقول @unique أيضًا). هذا خيار أكثر تقدّمًا، ويمكن لـ "SQL 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
}

استخدام الحقول التي تم إنشاؤها من المخطط لإنشاء العمليات

ستعمل عمليات SQL Connect على توسيع مجموعة من الحقول التي يتم إنشاؤها تلقائيًا بواسطة SQL Connect استنادًا إلى الأنواع وعلاقات الأنواع في المخطط. يتم إنشاء هذه الحقول بواسطة الأدوات المحلية كلما قمت بتحرير المخطط الخاص بك.

لنفترض أنّ المخطط يحتوي على نوع Movie ونوع Actor مرتبط به. ‫SQL 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 }
    }
  }

مع وضع ذلك في الاعتبار، يمكنك قراءة كيفية تنفيذ العمليات باستخدام هذه الحقول في دليل تنفيذ طلبات البحث ودليل تنفيذ التغييرات.

مفاهيم أكثر تقدّمًا حول المخططات

حقول التعداد

يتيح SQL Connect استخدام حقول التعداد التي يتم ربطها بأنواع التعداد في PostgreSQL. تتيح لك التعدادات تحديد قائمة بالقيم الثابتة والمحدّدة مسبقًا بسرعة وبترتيب معيّن.

لإضافة تعداد إلى المخطط، يجب الإعلان عن التعداد وقيمه المحدّدة مسبقًا، ثم الإشارة إليه في النوع.

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 لقائمة بنسب العرض إلى الارتفاع الأخرى المتاحة.

إدارة التغييرات في حقول التعداد

يمكنك إضافة قيم جديدة إلى التعداد، ولكن ترتيب قائمة التعداد مهم جدًا، لذا أدخِل قيمك الجديدة بحكمة. التغيير الوحيد المتوافق تمامًا مع الأنظمة القديمة في التعداد هو إضافة قيمة جديدة إلى نهاية قائمة القيم. تجدر الإشارة إلى أنّ إدراج قيمة جديدة بين قيم تعداد منشورة سابقًا أو إعادة ترتيب القيم الحالية يؤدي إلى تغيير الترتيب النسبي عند استخدام عوامل تشغيل نسبية مثل "أقل من" في طلبات البحث. إنّ إزالة القيم أو إعادة تسميتها هو دائمًا تغيير غير متوافق مع الأنظمة القديمة.

يجب عدم إعادة ترتيب القيم في قائمة قيم التعداد، لأنّ الترتيب مهمّ ويغيّر طريقة تطبيق الفلترة.

يجب إجراء التعديلات على قيم التعداد بعناية حتى لا يتم تعطيل الإصدارات القديمة من العملية أو رمز العميل. عند إزالة قيمة تعداد أو إعادة تسميتها، تأكَّد من عدم وجود أي مثيلات متبقية في قاعدة البيانات الحالية.

استخدام حقول التعداد في العمليات وفي رمز العميل

بعد إضافة حقل تعداد إلى المخطط، يمكنك استخدام هذا الحقل في طلبات البحث ورمز العميل.

يمكنك الاطّلاع على مزيد من المعلومات حول كتابة طلبات البحث باستخدام التعدادات، وحول كيفية كتابة العميل للسماح بإجراء تعديلات على التعدادات في دليل طلبات البحث.

مفاهيم متقدّمة أخرى

للانتقال إلى ما هو أبعد من الأنواع والعلاقات الأساسية والمفيدة، يمكنك الرجوع إلى الأمثلة في المستندات المرجعية.

أنواع البيانات المتوافقة

يتيح SQL Connect استخدام أنواع البيانات العددية التالية، مع عمليات التعيين إلى أنواع PostgreSQL باستخدام @col(dataType:).

نوع SQL Connect نوع GraphQL المضمّن أو
SQL 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 هذه الطوابع الزمنية ويخزّنها بالتوقيت العالمي المنسَّق (UTC).

التعداد مخصص enum

تعداد

Vector مخصص vector

المتّجه

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

  • يتم ربط GraphQL List بصفيف أحادي البُعد.
    • على سبيل المثال، يتم ربط [Int] بـ int5[]، و[Any] بـ jsonb[].
    • لا يتيح SQL 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);

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

قد يهمّك أيضًا: