Với Firebase Data Connect, bạn thiết kế một giản đồ GraphQL đại diện cho mô hình dữ liệu cần thiết cho ứng dụng của mình. Data Connect chuyển đổi giản đồ này thành phiên bản Cloud SQL cho PostgreSQL hỗ trợ ứng dụng của bạn. Sau đó, bạn sẽ tạo các truy vấn và đột biến để giao tiếp với phần phụ trợ và gói các thao tác này thành trình kết nối để sử dụng dữ liệu từ mã ứng dụng.
Data Connect cung cấp công cụ AI để giúp bạn thiết kế và triển khai giản đồ. Hướng dẫn này giới thiệu các khái niệm quan trọng về thiết kế giản đồ để hỗ trợ và bổ sung cho quy trình làm việc tiêu chuẩn và quy trình làm việc được AI hỗ trợ khi bạn bắt đầu phát triển một ứng dụng, và hơn thế nữa.
Hướng dẫn Bắt đầu đã giới thiệu một giản đồ ứng dụng đánh giá phim cho PostgreSQL.
Hướng dẫn này sẽ phát triển thêm giản đồ đó và cung cấp danh sách SQL tương đương với giản đồ ứng dụng đánh giá phim cuối cùng.
Giản đồ cho ứng dụng đánh giá phim
Hãy tưởng tượng bạn muốn xây dựng một dịch vụ cho phép người dùng gửi và xem các bài đánh giá phim.
Bạn cần một giản đồ ban đầu cho ứng dụng như vậy để hỗ trợ các truy vấn cơ bản. Sau này, bạn sẽ mở rộng giản đồ này để tạo các truy vấn quan hệ phức tạp.
Trong Data Connect, bạn sẽ xác định các loại GraphQL để xác định hình dạng của dữ liệu mà ứng dụng có thể truy vấn và thao tác. Khi bạn viết giản đồ, các loại của bạn sẽ được dịch thành các bảng Cloud SQL cho PostgreSQL, thường là trong mối quan hệ trực tiếp giữa các loại GraphQL và bảng cơ sở dữ liệu, mặc dù có thể có các ánh xạ khác. Hướng dẫn này trình bày một số ví dụ từ cơ bản đến nâng cao hơn.
Xác định loại Movie cơ bản
Bạn có thể bắt đầu với loại Movie.
Giản đồ cho Movie chứa các chỉ thị cốt lõi như:
@table(name)và@col(name)để tuỳ chỉnh tên bảng và cột SQL. Data Connect tạo tên snake_case nếu không được chỉ định.@col(dataType)để tuỳ chỉnh các loại cột SQL.@defaultđể định cấu hình các giá trị mặc định của cột SQL trong quá trình chèn.
Để biết thêm thông tin chi tiết, hãy xem tài liệu tham khảo cho @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
}
Tự động lưu trữ dữ liệu người dùng quan trọng trong loại User
Ứng dụng của bạn sẽ theo dõi người dùng, vì vậy, bạn cần có loại User.
Chỉ thị @default đặc biệt hữu ích trong trường hợp này. Trường id ở đây
có thể tự động lấy mã nhận dạng của người dùng từ quá trình xác thực: hãy lưu ý việc
sử dụng @default(expr: "auth.uid") trong mẫu sau.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
Các đại lượng vô hướng chính và giá trị máy chủ
Trước khi xem xét kỹ hơn về ứng dụng đánh giá phim, bạn cần giới thiệu Data Connect các đại lượng vô hướng chính và giá trị máy chủ.
Các đại lượng vô hướng chính là các mã nhận dạng đối tượng ngắn gọn mà Data Connect tự động tập hợp từ các trường khoá trong giản đồ của bạn. Các đại lượng vô hướng chính là về hiệu quả, cho phép bạn tìm thấy thông tin về danh tính và cấu trúc dữ liệu của mình trong một lệnh gọi duy nhất. Chúng đặc biệt hữu ích khi bạn muốn thực hiện các hành động tuần tự trên các bản ghi mới và cần một mã nhận dạng duy nhất để chuyển đến các thao tác sắp tới, đồng thời khi bạn muốn truy cập vào các khoá quan hệ để thực hiện các thao tác phức tạp hơn.
Khi sử dụng giá trị máy chủ, bạn có thể cho phép máy chủ tự động điền
các trường trong bảng bằng các giá trị được lưu trữ hoặc có thể tính toán dễ dàng theo
các biểu thức CEL cụ thể phía máy chủ trong đối số expr. Ví dụ: bạn
có thể xác định một trường có dấu thời gian được áp dụng khi trường được truy cập bằng
thời gian được lưu trữ trong yêu cầu thao tác, updatedAt: Timestamp!
@default(expr: "request.time").
Xử lý mối quan hệ nhiều-nhiều trong các loại Actor và MovieActor
Sau khi xử lý người dùng, bạn có thể quay lại mô hình hoá dữ liệu phim.
Tiếp theo, bạn muốn các diễn viên đóng vai chính trong phim của mình.
Bảng Actor khá đơn giản.
# 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)")
}
Nếu bạn muốn các diễn viên đóng nhiều phim và phim có nhiều diễn viên, bạn sẽ cần một "bảng kết hợp".
Bảng MovieActor xử lý mối quan hệ nhiều-nhiều và
khoá chính của bảng này là sự kết hợp của [movie, actor] (các trường khoá ngoại từ
movie và 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
}
Khi bạn xác định mối quan hệ SQL trên bảng có ràng buộc khoá ngoại,
Data Connect sẽ tự động tạo trường tương ứng ở phía
bên kia. Bạn không cần xác định trường ánh xạ ngược (ví dụ: từ
Actor trở lại MovieActor).
Xử lý mối quan hệ một-một trong loại MovieMetadata
Bây giờ, hãy theo dõi các đạo diễn phim, cũng như thiết lập mối quan hệ một-một với Movie.
Bạn có thể sử dụng chỉ thị @ref để tuỳ chỉnh các ràng buộc khoá ngoại:
@ref(fields)chỉ định các trường khoá ngoại cần sử dụng.@ref(references)chỉ định các trường được tham chiếu trong bảng đích (mặc định là khoá chính, nhưng các trường@uniquecũng hoạt động). Đây là một lựa chọn nâng cao hơn ; Data Connect thường có thể suy luận điều này cho bạn.
Để biết thêm thông tin chi tiết, hãy xem tài liệu tham khảo cho @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
}
Sử dụng các trường được tạo từ giản đồ để xây dựng các thao tác
Các thao tác Data Connect sẽ mở rộng một tập hợp các trường do Data Connect tự động tạo dựa trên các loại và mối quan hệ giữa các loại trong giản đồ của bạn. Các trường này được tạo bởi công cụ cục bộ bất cứ khi nào bạn chỉnh sửa giản đồ.
Giả sử giản đồ của bạn chứa loại Movie và loại Actor được liên kết.
Data Connect tạo các trường movie, movies,
actors_on_movies và nhiều trường khác.
Truy vấn bằng trường
movie
|
Trường |
Sử dụng trường này để truy vấn một bộ phim duy nhất theo khoá của bộ phim đó. query GetMovie($myKey: Movie_Key!) { movie(key: $myKey) { title } } |
Truy vấn bằng trường
movies
|
Trường |
Sử dụng trường này để truy vấn nhiều bộ phim, ví dụ: tất cả các bộ phim có một năm nhất định. query GetMovies($myYear: Int!) { movies(where: { year: { eq: $myYear } }) { title } } |
Truy vấn bằng trường
actors_on_movies
|
Trường |
Sử dụng trường này để truy vấn tất cả các diễn viên được liên kết với một bộ phim nhất định. query GetActorsOnMovie($myKey: Movie_Key!) { actors_on_movies(where: { movie: { key: { eq: $myKey } } }) { actor { name } } } |
Với điều này, bạn có thể đọc cách triển khai các thao tác bằng các trường này trong hướng dẫn triển khai truy vấn và hướng dẫn triển khai đột biến.
Các khái niệm nâng cao hơn về giản đồ
Trường liệt kê
Data Connect hỗ trợ các trường liệt kê ánh xạ tới các loại được liệt kê của PostgreSQL. Enum cho phép bạn nhanh chóng xác định danh sách các giá trị tĩnh, được xác định trước theo một thứ tự cụ thể.
Để thêm một enum vào giản đồ, hãy khai báo enum và các giá trị được xác định trước của enum đó, sau đó tham chiếu đến enum đó trong loại của bạn.
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
}
Trong loại Movie, chúng tôi đã thêm một trường enum originalAspectRatio cho tỷ lệ khung hình mà bộ phim được quay và một trường otherAspectRatios khác cho danh sách các tỷ lệ khung hình có sẵn khác.
Quản lý các thay đổi đối với trường liệt kê
Bạn có thể thêm các giá trị mới vào enum, nhưng thứ tự của danh sách enum có ý nghĩa rất quan trọng, vì vậy, hãy chèn các giá trị mới một cách khôn ngoan. Thay đổi duy nhất hoàn toàn tương thích ngược với enum là thêm một giá trị mới vào cuối danh sách giá trị. Đáng chú ý là việc chèn một giá trị mới giữa các enum đã xuất bản trước đó hoặc sắp xếp lại các giá trị hiện có sẽ thay đổi thứ tự tương đối khi các toán tử tương đối như "nhỏ hơn" được sử dụng trong các truy vấn. Việc xoá hoặc đổi tên giá trị luôn là một thay đổi không tương thích ngược.
Bạn không bao giờ được sắp xếp lại các giá trị trong danh sách giá trị enum; thứ tự là quan trọng vì nó thay đổi cách áp dụng tính năng lọc.
Bạn nên điều chỉnh các giá trị enum một cách cẩn thận để không làm hỏng các phiên bản cũ hơn của thao tác hoặc mã ứng dụng. Khi xoá hoặc đổi tên một giá trị enum, hãy đảm bảo không còn thực thể nào trong cơ sở dữ liệu hiện tại.
Sử dụng các trường enum trong các thao tác và trong mã ứng dụng
Giờ đây, khi đã thêm một trường enum vào giản đồ, bạn có thể sử dụng trường này trong các truy vấn và mã ứng dụng.
Tìm hiểu thêm về cách viết truy vấn bằng enum và cách viết ứng dụng để cho phép điều chỉnh enum bắt đầu trong hướng dẫn truy vấn.
Các khái niệm nâng cao khác
Để chuyển sang các loại và mối quan hệ cơ bản nhưng hữu ích, hãy tham khảo các ví dụ trong tài liệu tham khảo.
Loại dữ liệu được hỗ trợ
Data Connect hỗ trợ các loại dữ liệu vô hướng sau đây, với
các phép gán cho các loại PostgreSQL bằng @col(dataType:).
| Data Connect loại | Loại tích hợp sẵn của GraphQL hoặc Data Connect loại tuỳ chỉnh |
Loại PostgreSQL mặc định | Các loại PostgreSQL được hỗ trợ (bí danh trong dấu ngoặc đơn) |
|---|---|---|---|
| Chuỗi | GraphQL | văn bản | văn bản bit(n), varbit(n) char(n), varchar(n) |
| Int | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
| Nổi | GraphQL | float8 | float4 (real) float8 (double precision) numeric (decimal) |
| Boolean | GraphQL | boolean | boolean |
| mã nhận dạng duy nhất (UUID) | Tuỳ chỉnh | uuid | uuid |
| Int64 | Tuỳ chỉnh | bigint | int8 (bigint, bigserial) numeric (decimal) |
| Ngày | Tuỳ chỉnh | ngày | ngày |
| Dấu thời gian | Tuỳ chỉnh | timestamptz | timestamptz Lưu ý: Thông tin múi giờ cục bộ không được lưu trữ. |
| Bảng liệt kê | Tuỳ chỉnh | enum | enum |
| Vectơ | Tuỳ chỉnh | vectơ | vectơ Xem bài viết Thực hiện tìm kiếm mức độ tương đồng vectơ bằng Vertex AI. |
ListGraphQL ánh xạ tới một mảng một chiều.- Ví dụ:
[Int]ánh xạ tớiint5[],[Any]ánh xạ tớijsonb[]. - Data Connect không hỗ trợ mảng lồng nhau.
- Ví dụ:
Giản đồ SQL tương đương
-- 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);
Các bước tiếp theo
Bạn có thể quan tâm đến:
- Tạo giản đồ cho ứng dụng bằng các công cụ hỗ trợ AI
- Xem tài liệu tham khảo về cú pháp.