เมื่อใช้ 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 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 | ข้อความ | ข้อความ bit(n), varbit(n) char(n), varchar(n) |
| จำนวนเต็ม | GraphQL | จำนวนเต็ม | Int2 (smallint, smallserial), int4 (integer, int, serial) |
| ลอยขึ้นมา | GraphQL | float8 | float4 (real) float8 (double precision) numeric (decimal) |
| บูลีน | GraphQL | บูลีน | บูลีน |
| UUID | กำหนดเอง | uuid | uuid |
| Int64 | กำหนดเอง | bigint | int8 (bigint, bigserial) numeric (decimal) |
| วันที่ | กำหนดเอง | วันที่ | วันที่ |
| การประทับเวลา | กำหนดเอง | timestamptz | timestamptz หมายเหตุ: ระบบจะไม่จัดเก็บข้อมูลเขตเวลาท้องถิ่น |
| การแจงนับ | กำหนดเอง | enum | enum |
| Vector | กำหนดเอง | vector | vector |
Listของ GraphQL จะแมปกับอาร์เรย์ 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 Assistance
- การอ่านเอกสารอ้างอิงไวยากรณ์