เมื่อใช้ 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
|
ช่อง |
ใช้ช่องนี้เพื่อค้นหาภาพยนตร์เรื่องเดียวตามคีย์ query GetMovie($myKey: Movie_Key!) { movie(key: $myKey) { title } } |
คำค้นหาที่มีช่อง
movies
|
ฟิลด์ |
ใช้ช่องนี้เพื่อค้นหาภาพยนตร์หลายเรื่อง เช่น ภาพยนตร์ทั้งหมดที่มีปีที่ระบุ query GetMovies($myYear: Int!) { movies(where: { year: { eq: $myYear } }) { title } } |
คำค้นหาที่มีช่อง
actors_on_movies
|
ช่อง |
ใช้ช่องนี้เพื่อค้นหานักแสดงทั้งหมดที่เกี่ยวข้องกับภาพยนตร์ที่ระบุ 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 หมายเหตุ: ระบบจะไม่จัดเก็บข้อมูลเขตเวลาท้องถิ่น |
| การแจงนับ | กำหนดเอง | enum | enum |
| เวกเตอร์ | กำหนดเอง | vector | เวกเตอร์ |
- 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);
ขั้นตอนถัดไป
คุณอาจสนใจสิ่งต่อไปนี้
- การสร้างสคีมาสำหรับแอปโดยใช้เครื่องมือช่วยเหลือของ AI
- อ่านเอกสารอ้างอิงไวยากรณ์