ออกแบบสคีมา SQL Connect

เมื่อใช้ Firebase SQL Connect คุณจะออกแบบสคีมา GraphQL ที่แสดงโมเดลข้อมูลที่จำเป็นสำหรับแอปพลิเคชันของคุณ SQL Connect จะแปลงสคีมานี้เป็นอินสแตนซ์ Cloud SQL สำหรับ PostgreSQL ที่รองรับแอปของคุณ จากนั้นคุณจะเขียนการค้นหาและการเปลี่ยนแปลงเพื่อเชื่อมต่อกับแบ็กเอนด์และรวมการดำเนินการเหล่านี้ไว้ในเครื่องมือเชื่อมต่อเพื่อใช้ข้อมูลจากโค้ดฝั่งไคลเอ็นต์

SQL Connect มีเครื่องมือ AI ที่ช่วยคุณออกแบบและใช้สคีมา คู่มือนี้จะแนะนำแนวคิดสำคัญของการออกแบบสคีมาเพื่อสนับสนุนและเสริมเวิร์กโฟลว์มาตรฐานและเวิร์กโฟลว์ที่มีการใช้งาน AI เมื่อคุณเริ่มพัฒนาแอปและหลังจากนั้น

คู่มือเริ่มต้นใช้งานได้แนะนำสคีมาแอปรีวิวภาพยนตร์สำหรับ 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 ช่วยให้คุณกำหนดรายการค่าคงที่ที่กำหนดไว้ล่วงหน้าได้อย่างรวดเร็วโดยมีลำดับที่เฉพาะเจาะจง

หากต้องการเพิ่ม enum ลงในสคีมา ให้ประกาศ 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 เราได้เพิ่มช่อง enum originalAspectRatio สำหรับสัดส่วนภาพที่ใช้ถ่ายทำภาพยนตร์ และอีกช่อง otherAspectRatios สำหรับรายการสัดส่วนภาพอื่นๆ ที่มี

จัดการการเปลี่ยนแปลงในช่องการแจงนับ

คุณสามารถเพิ่มค่าใหม่ลงใน enum ได้ แต่ลำดับของรายการ enum มีความสำคัญมาก ดังนั้นโปรดแทรกค่าใหม่อย่างรอบคอบ การเปลี่ยนแปลง enum ที่เข้ากันได้แบบย้อนหลังอย่างสมบูรณ์เพียงอย่างเดียวคือการเพิ่มค่าใหม่ที่ส่วนท้ายของรายการค่า โดยเฉพาะอย่างยิ่ง การแทรกค่าใหม่ระหว่าง Enum ที่เผยแพร่ก่อนหน้านี้หรือการจัดลำดับค่าที่มีอยู่ใหม่จะเปลี่ยนลำดับสัมพัทธ์เมื่อใช้โอเปอเรเตอร์สัมพัทธ์ เช่น "น้อยกว่า" ในการค้นหา การนำค่าออกหรือเปลี่ยนชื่อค่าจะเป็นการเปลี่ยนแปลงที่เข้ากันไม่ได้แบบย้อนหลังเสมอ

คุณไม่ควรจัดเรียงค่าในรายการค่า enum ใหม่ เนื่องจากลำดับมีความสำคัญเนื่องจากจะเปลี่ยนวิธีการใช้การกรอง

การปรับค่า enum ควรทำอย่างระมัดระวังเพื่อไม่ให้ส่งผลกระทบต่อการทำงานหรือโค้ดไคลเอ็นต์เวอร์ชันเก่า เมื่อนำค่า enum ออกหรือเปลี่ยนชื่อค่า enum โปรดตรวจสอบว่าไม่มีอินสแตนซ์เหลืออยู่ในฐานข้อมูลปัจจุบัน

การใช้ช่อง enum ในการดำเนินการและในโค้ดไคลเอ็นต์

เมื่อเพิ่มช่อง enum ลงในสคีมาแล้ว คุณจะใช้ช่องนี้ในการค้นหาและโค้ดไคลเอ็นต์ได้

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเขียนคำค้นหาโดยใช้ Enum และวิธีเขียนไคลเอ็นต์เพื่ออนุญาตให้ปรับ Enum ได้โดยเริ่มจากคู่มือคำค้นหา

แนวคิดขั้นสูงอื่นๆ

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทและความสัมพันธ์พื้นฐานแต่มีประโยชน์ โปรดดูตัวอย่างในเอกสารอ้างอิง

ประเภทข้อมูลที่รองรับ

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 (real)
float8 (double precision)
numeric (decimal)
บูลีน GraphQL boolean boolean
UUID กำหนดเอง uuid uuid
Int64 กำหนดเอง bigint int8 (bigint, bigserial)
numeric (decimal)
วันที่ กำหนดเอง date วันที่
การประทับเวลา กำหนดเอง timestamptz

timestamptz

หมายเหตุ: ระบบจะไม่จัดเก็บข้อมูลเขตเวลาท้องถิ่น
PostgreSQL จะแปลงและจัดเก็บการประทับเวลาดังกล่าวเป็น UTC

การแจงนับ กำหนดเอง enum

enum

เวกเตอร์ กำหนดเอง vector

เวกเตอร์

ดูหัวข้อทำการค้นหาความคล้ายคลึงของเวกเตอร์ด้วย Vertex AI

  • GraphQL List จะแมปกับอาร์เรย์แบบ 1 มิติ
    • เช่น [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);

ขั้นตอนถัดไป

คุณอาจสนใจสิ่งต่อไปนี้