paint-brush
Kiến trúc một hệ thống tạo nhúng vectơ mạnh mẽ cho dữ liệu PostgreSQLtừ tác giả@timescale
7,894 lượt đọc
7,894 lượt đọc

Kiến trúc một hệ thống tạo nhúng vectơ mạnh mẽ cho dữ liệu PostgreSQL

từ tác giả Timescale16m2023/11/14
Read on Terminal Reader

dài quá đọc không nổi

"Đắm mình vào thế giới của PGVectorizer, một giải pháp tiên tiến để nhúng dữ liệu vào các bảng PostgreSQL một cách liền mạch. Tìm hiểu về các quyết định thiết kế kỹ thuật phức tạp và sự đánh đổi được thực hiện để đảm bảo tính đơn giản, khả năng phục hồi và hiệu suất cao. Hệ thống này, được trang bị Timescale Thư viện Vector Python, trao quyền cho các nhà phát triển để dễ dàng đồng bộ hóa và cập nhật dữ liệu, mang lại mức độ hiệu quả mới cho các ứng dụng dựa trên PostgreSQL, từ tìm kiếm ngữ nghĩa đến AI tổng hợp."
featured image - Kiến trúc một hệ thống tạo nhúng vectơ mạnh mẽ cho dữ liệu PostgreSQL
Timescale HackerNoon profile picture


Việc nhúng dữ liệu được lưu trữ trong bảng PostgreSQL chắc chắn là hữu ích – với các ứng dụng khác nhau, từ hệ thống đề xuất và tìm kiếm ngữ nghĩa cho đến các ứng dụng AI tổng quát và thế hệ tăng cường truy xuất. Tuy nhiên, việc tạo và quản lý các phần nhúng cho dữ liệu trong các bảng PostgreSQL có thể phức tạp, với nhiều điều cần cân nhắc và các trường hợp đặc biệt cần tính đến, chẳng hạn như luôn cập nhật các phần nhúng cho các bản cập nhật và xóa bảng, đảm bảo khả năng phục hồi trước các lỗi và tác động đến các hệ thống hiện có phụ thuộc vào cái bàn.


Trong bài đăng blog trước đây, chúng tôi đã trình bày chi tiết hướng dẫn từng bước về quy trình tạo và quản lý nội dung nhúng cho dữ liệu cư trú trong PostgreSQL bằng cách sử dụng PGVectorizer – hệ thống tạo nhúng đơn giản và linh hoạt của chúng tôi dành cho dữ liệu nằm trong PostgreSQL. Bằng cách sử dụng một ứng dụng blog với dữ liệu được lưu trữ trong cơ sở dữ liệu PostgreSQL làm ví dụ, chúng tôi đã trình bày cách tạo và cập nhật các phần nhúng vectơ bằng cách sử dụng Python, LangChain và Timescale Vector.


Trong bài đăng trên blog này, chúng tôi sẽ thảo luận về các quyết định thiết kế kỹ thuật và những đánh đổi mà chúng tôi đã thực hiện khi xây dựng PGVectorizer để đảm bảo tính đơn giản, khả năng phục hồi và hiệu suất cao. Chúng tôi cũng sẽ thảo luận về các thiết kế thay thế nếu bạn muốn tự cuộn.


Hãy nhảy vào nó.

Thiết kế Trình tạo vectơ hiệu suất cao cho dữ liệu PostgreSQL (PgVectorizer)

Đầu tiên, hãy mô tả cách hệ thống chúng ta đang xây dựng sẽ hoạt động. Vui lòng bỏ qua phần này nếu bạn đã đọc bài viết PGVectorizer .


Tổng quan về hệ thống

Để làm ví dụ minh họa, chúng tôi sẽ sử dụng một ứng dụng blog đơn giản lưu trữ dữ liệu trong PostgreSQL bằng bảng được xác định như sau:


 CREATE TABLE blog ( id SERIAL PRIMARY KEY NOT NULL, title TEXT NOT NULL, author TEXT NOT NULL, contents TEXT NOT NULL, category TEXT NOT NULL, published_time TIMESTAMPTZ NULL --NULL if not yet published );


Chúng tôi muốn tạo các phần nhúng trên nội dung của bài đăng trên blog để sau này chúng tôi có thể sử dụng nó cho việc tạo tăng cường tìm kiếm ngữ nghĩa và truy xuất sức mạnh. Nội dung nhúng chỉ nên tồn tại và có thể tìm kiếm được đối với các blog đã được xuất bản (trong đó published_time NOT NULL ).


Trong khi xây dựng hệ thống nhúng này, chúng tôi có thể xác định một số mục tiêu mà bất kỳ hệ thống đơn giản và linh hoạt nào tạo ra các phần nhúng đều phải có:


  • Không có sửa đổi đối với bảng gốc. Điều này cho phép các hệ thống và ứng dụng đã sử dụng bảng này không bị ảnh hưởng bởi những thay đổi đối với hệ thống nhúng. Điều này đặc biệt quan trọng đối với các hệ thống cũ.


  • Không sửa đổi các ứng dụng tương tác với bảng. Việc phải sửa đổi mã làm thay đổi bảng có thể không thực hiện được đối với các hệ thống cũ. Đây cũng là thiết kế phần mềm kém vì nó kết hợp các hệ thống không sử dụng phần nhúng với mã tạo ra phần nhúng.


  • Tự động cập nhật các phần nhúng khi các hàng trong bảng nguồn thay đổi (trong trường hợp này là bảng blog). Điều này làm giảm gánh nặng bảo trì và góp phần tạo ra phần mềm không cần lo lắng. Đồng thời, bản cập nhật này không cần phải diễn ra ngay lập tức hoặc trong cùng một cam kết. Đối với hầu hết các hệ thống, “sự nhất quán cuối cùng” là ổn.


  • Đảm bảo khả năng phục hồi trước các lỗi mạng và dịch vụ: Hầu hết các hệ thống đều tạo ra các phần nhúng thông qua lệnh gọi đến hệ thống bên ngoài, chẳng hạn như API OpenAI. Trong trường hợp hệ thống bên ngoài ngừng hoạt động hoặc xảy ra sự cố mạng, điều bắt buộc là phần còn lại của hệ thống cơ sở dữ liệu của bạn phải tiếp tục hoạt động.


Những hướng dẫn này là cơ sở của một kiến trúc mạnh mẽ mà chúng tôi đã triển khai bằng cách sử dụng Thư viện Python Timescale Vector , một thư viện để làm việc với dữ liệu vectơ bằng PostgreSQL. Để hoàn thành công việc thành công, hãy thêm chức năng mới vào thư viện này— PGVectorizer —để làm cho việc nhúng dữ liệu PostgreSQL trở nên đơn giản nhất có thể.


Đây là kiến trúc mà chúng tôi đã quyết định:


Kiến trúc tham chiếu cho một hệ thống đơn giản và linh hoạt để nhúng dữ liệu vào bảng PostgreSQL hiện có. Chúng tôi sử dụng trường hợp sử dụng mẫu của một ứng dụng viết blog, do đó có tên bảng ở trên.


Trong thiết kế này, trước tiên, chúng tôi thêm một trình kích hoạt vào bảng blog để theo dõi các thay đổi và khi thấy một sửa đổi, chúng tôi sẽ chèn một công việc vào bảng blog_work_queue để chỉ ra rằng một hàng trong bảng blog đã lỗi thời khi nhúng nó.


Theo lịch trình cố định, công việc của người tạo nội dung nhúng sẽ thăm dò bảng blog_work_queue và nếu tìm thấy công việc cần làm, công việc này sẽ thực hiện các thao tác sau trong một vòng lặp:


  • Đọc và khóa một hàng trong bảng blog_work_queue
  • Đọc hàng tương ứng trong bảng blog
  • Tạo phần nhúng cho dữ liệu trong hàng blog
  • Viết phần nhúng vào bảng blog_embedding
  • Xóa hàng bị khóa trong bảng blog_work_queue


Để xem hệ thống này hoạt động như thế nào, hãy xem ví dụ về cách sử dụng tạo và duy trì các phần nhúng trong bảng PostgreSQL bằng OpenAI, LangChain và Timescale Vector trong bài đăng blog này .


Quay trở lại ví dụ về bảng ứng dụng blog của chúng ta, ở mức độ cao, PGVectorizer phải thực hiện hai việc:


  • Theo dõi các thay đổi đối với các hàng trong blog để biết hàng nào đã thay đổi.


  • Cung cấp một phương pháp để xử lý các thay đổi để tạo các phần nhúng.


Cả hai điều này phải diễn ra đồng thời và có hiệu suất cao. Hãy xem nó hoạt động như thế nào.


Theo dõi sự thay đổi đối với bảng blog bằng bảng blog_work_queue

Bạn có thể tạo một bảng xếp hàng công việc đơn giản như sau:


 CREATE TABLE blog_embedding_work_queue ( id INT ); CREATE INDEX ON blog_embedding_work_queue(id);


Đây là một bảng rất đơn giản nhưng có một điều cần lưu ý: bảng này không có khóa duy nhất. Điều này được thực hiện để tránh các vấn đề về khóa khi xử lý hàng đợi, nhưng điều đó có nghĩa là chúng tôi có thể có các bản sao. Chúng ta sẽ thảo luận về sự đánh đổi sau trong Phương án 1 bên dưới.


Sau đó, bạn tạo trình kích hoạt để theo dõi mọi thay đổi được thực hiện đối với blog :


 CREATE OR REPLACE FUNCTION blog_wq_for_embedding() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO blog_embedding_work_queue VALUES (OLD.id); ELSE INSERT INTO blog_embedding_work_queue VALUES (NEW.id); END IF; RETURN NULL; END; $$; CREATE TRIGGER track_changes_for_embedding AFTER INSERT OR UPDATE OR DELETE ON blog FOR EACH ROW EXECUTE PROCEDURE blog_wq_for_embedding(); INSERT INTO blog_embedding_work_queue SELECT id FROM blog WHERE published_time is NOT NULL;


Trình kích hoạt sẽ chèn ID của blog đã thay đổi thành blog_work_queue. Chúng tôi cài đặt trình kích hoạt rồi chèn bất kỳ blog hiện có nào vào work_queue. Thứ tự này rất quan trọng để đảm bảo rằng không có ID nào bị bỏ đi.


Bây giờ, hãy mô tả một số thiết kế thay thế và lý do chúng tôi từ chối chúng.


Phương án 1: Triển khai khóa chính hoặc khóa duy nhất cho bảng blog_work_queue.

Việc giới thiệu khóa này sẽ loại bỏ vấn đề nhập trùng lặp. Tuy nhiên, không phải là không có thách thức, đặc biệt là vì khóa như vậy sẽ buộc chúng ta phải sử dụng mệnh INSERT…ON CONFLICT DO NOTHING để chèn ID mới vào bảng và mệnh đề đó sẽ khóa ID trong cây B.


Đây là vấn đề nan giải: trong giai đoạn xử lý, cần phải xóa các hàng đang được xử lý để tránh việc xử lý đồng thời. Tuy nhiên, việc thực hiện việc xóa này chỉ có thể được thực hiện sau khi phần nhúng tương ứng đã được đặt vào blog_embeddings. Điều này đảm bảo không có ID nào bị mất nếu có sự gián đoạn giữa chừng—chẳng hạn như nếu quá trình tạo nội dung nhúng gặp sự cố sau khi xóa nhưng trước khi nội dung nhúng được ghi.


Bây giờ, nếu chúng ta tạo khóa chính hoặc khóa duy nhất thì giao dịch giám sát việc xóa vẫn mở. Do đó, điều này hoạt động như một khóa đối với các ID cụ thể đó, ngăn chặn việc chèn chúng trở lại blog_work_queue trong toàn bộ thời gian của công việc tạo nhúng. Vì việc tạo phần nhúng mất nhiều thời gian hơn so với giao dịch cơ sở dữ liệu thông thường của bạn, điều này gây ra rắc rối. Khóa sẽ ngăn cản quá trình kích hoạt bảng 'blog' chính, dẫn đến hiệu suất của ứng dụng chính bị giảm. Điều tồi tệ hơn là nếu xử lý nhiều hàng cùng lúc, bế tắc cũng trở thành một vấn đề tiềm ẩn.


Tuy nhiên, các vấn đề tiềm ẩn phát sinh từ các mục nhập trùng lặp không thường xuyên có thể được quản lý trong giai đoạn xử lý, như minh họa sau. Một bản sao lẻ tẻ ở đây không có vấn đề gì vì nó chỉ làm tăng nhẹ khối lượng công việc mà công việc nhúng thực hiện. Điều này chắc chắn dễ chịu hơn việc vật lộn với những thử thách khóa nêu trên.


Phương án 2: Theo dõi công việc cần thực hiện bằng cách thêm một cột vào bảng blog để theo dõi xem có tồn tại phần nhúng cập nhật hay không.

Ví dụ: chúng ta có thể thêm một cột boolean embedded được đặt thành false khi sửa đổi và chuyển thành true khi quá trình nhúng được tạo. Có ba lý do để từ chối thiết kế này:

  • Chúng tôi không muốn sửa đổi bảng blog vì những lý do mà chúng tôi đã đề cập ở trên.


  • Để có được danh sách các blog không được nhúng một cách hiệu quả sẽ yêu cầu một chỉ mục bổ sung (hoặc chỉ mục một phần) trên bảng blog. Điều này sẽ làm chậm các hoạt động khác.


  • Điều này làm tăng tỷ lệ xáo trộn trên bảng vì giờ đây mọi sửa đổi sẽ được viết hai lần (một lần với embedding=false và một lần với embedding=true) do tính chất MVCC của PostgreSQL.


Một Work_queue_table riêng biệt sẽ giải quyết những vấn đề này.


Phương án 3: Tạo nội dung nhúng trực tiếp trong trình kích hoạt.

Cách tiếp cận này có một số vấn đề:


  • Nếu dịch vụ nhúng không hoạt động, trình kích hoạt sẽ không thành công (hủy giao dịch của bạn) hoặc bạn cần tạo đường dẫn mã dự phòng để… lưu trữ các ID không thể nhúng vào hàng đợi. Giải pháp thứ hai đưa chúng ta quay lại thiết kế đề xuất nhưng có độ phức tạp cao hơn.


  • Trình kích hoạt này có thể sẽ chậm hơn nhiều so với các hoạt động cơ sở dữ liệu còn lại do độ trễ cần thiết để liên hệ với dịch vụ bên ngoài. Điều này sẽ làm chậm phần còn lại của hoạt động cơ sở dữ liệu của bạn trên bảng.


  • Nó buộc người dùng phải viết mã nhúng tạo trực tiếp vào cơ sở dữ liệu. Vì ngôn ngữ chung của AI là Python và việc tạo nhúng thường yêu cầu nhiều thư viện khác nên việc này không phải lúc nào cũng dễ dàng hoặc thậm chí có thể thực hiện được (đặc biệt nếu chạy trong môi trường đám mây PostgreSQL được lưu trữ). Sẽ tốt hơn nhiều nếu có một thiết kế trong đó bạn có thể lựa chọn tạo các phần nhúng bên trong hoặc bên ngoài cơ sở dữ liệu.


Bây giờ chúng ta đã có danh sách các blog cần nhúng, chúng ta cùng xử lý danh sách nhé!


Tạo các phần nhúng

Có nhiều cách để tạo phần nhúng. Chúng tôi khuyên bạn nên sử dụng tập lệnh Python bên ngoài. Tập lệnh này sẽ quét hàng đợi công việc và các bài đăng blog liên quan, gọi một dịch vụ bên ngoài để tạo các phần nhúng và sau đó lưu trữ các phần nhúng này trở lại cơ sở dữ liệu. Lý do của chúng tôi cho chiến lược này là như sau:


  • Lựa chọn Python : Chúng tôi khuyên dùng Python vì nó cung cấp một hệ sinh thái phong phú, chưa từng có cho các tác vụ dữ liệu AI, nổi bật là các thư viện dữ liệu và phát triển LLM mạnh mẽ như LangChain và Llama Index.


  • Chọn tập lệnh bên ngoài thay vì PL/Python : Chúng tôi muốn người dùng có quyền kiểm soát cách họ nhúng dữ liệu của mình. Tuy nhiên, đồng thời, nhiều nhà cung cấp đám mây Postgres không cho phép thực thi mã Python tùy ý bên trong cơ sở dữ liệu vì lo ngại về bảo mật. Vì vậy, để cho phép người dùng linh hoạt trong cả tập lệnh nhúng cũng như nơi họ lưu trữ cơ sở dữ liệu, chúng tôi đã sử dụng một thiết kế sử dụng tập lệnh Python bên ngoài.


Các công việc phải vừa hiệu quả vừa an toàn đồng thời. Tính đồng thời đảm bảo rằng nếu công việc bắt đầu chạy chậm, người lập lịch có thể bắt đầu nhiều công việc hơn để giúp hệ thống bắt kịp và xử lý tải.


Chúng ta sẽ tìm hiểu cách thiết lập từng phương thức đó sau, nhưng trước tiên, hãy xem tập lệnh Python trông như thế nào. Về cơ bản, kịch bản có ba phần:


  • Đọc hàng đợi công việc và bài đăng trên blog

  • Tạo phần nhúng cho bài đăng trên blog

  • Viết phần nhúng vào bảng blog_embedding


Bước 2 và 3 được thực hiện bằng lệnh gọi lại embed_and_write mà chúng tôi xác định trong Bài đăng trên blog của PGVectorizer . Vì vậy, hãy xem xét sâu hơn cách chúng ta xử lý hàng đợi công việc.

Xử lý hàng đợi công việc

Trước tiên, chúng tôi sẽ hiển thị cho bạn mã và sau đó nêu bật các yếu tố chính đang diễn ra:


 def process_queue(embed_and_write_cb, batch_size:int=10): with psycopg2.connect(TIMESCALE_SERVICE_URL) as conn: with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cursor: cursor.execute(f""" SELECT to_regclass('blog_embedding_work_queue')::oid; """) table_oid = cursor.fetchone()[0] cursor.execute(f""" WITH selected_rows AS ( SELECT id FROM blog_embedding_work_queue LIMIT {int(batch_size)} FOR UPDATE SKIP LOCKED ), locked_items AS ( SELECT id, pg_try_advisory_xact_lock( {int(table_oid)}, id) AS locked FROM ( SELECT DISTINCT id FROM selected_rows ORDER BY id ) as ids ), deleted_rows AS ( DELETE FROM blog_embedding_work_queue WHERE id IN ( SELECT id FROM locked_items WHERE locked = true ORDER BY id ) ) SELECT locked_items.id as locked_id, {self.table_name}.* FROM locked_items LEFT JOIN blog ON blog.id = locked_items.id WHERE locked = true ORDER BY locked_items.id """) res = cursor.fetchall() if len(res) > 0: embed_and_write_cb(res) return len(res) process_queue(embed_and_write)


Mã SQL trong đoạn mã trên rất tinh tế vì nó được thiết kế để vừa có hiệu suất vừa an toàn khi chạy đồng thời, vì vậy hãy cùng xem qua nó:


  • Đưa các mục ra khỏi hàng đợi công việc : Ban đầu, hệ thống truy xuất một số mục nhập được chỉ định từ hàng đợi công việc, được xác định bởi tham số kích thước hàng đợi lô. Khóa FOR UPDATE được thực hiện để đảm bảo rằng các tập lệnh thực thi đồng thời không thử xử lý các mục hàng đợi giống nhau. Lệnh SKIP LOCKED đảm bảo rằng nếu bất kỳ mục nhập nào hiện đang được xử lý bởi tập lệnh khác, hệ thống sẽ bỏ qua mục đó thay vì chờ đợi, tránh sự chậm trễ không cần thiết.


  • Khóa ID blog : Do khả năng có các mục trùng lặp cho cùng một blog_id trong bảng hàng đợi công việc, nên chỉ khóa bảng nói trên là không đủ. Việc xử lý đồng thời cùng một ID bởi các công việc khác nhau sẽ gây bất lợi. Hãy xem xét điều kiện chủng tộc tiềm năng sau:


  • Công việc 1 khởi tạo và truy cập blog, lấy phiên bản 1.


  • Một bản cập nhật bên ngoài cho blog xảy ra.


  • Sau đó, Công việc 2 bắt đầu, nhận được phiên bản 2.


  • Cả hai công việc đều bắt đầu quá trình tạo nhúng.


  • Công việc 2 kết thúc, lưu trữ phần nhúng tương ứng với phiên bản blog 2.


  • Sau khi kết luận, Công việc 1 đã ghi đè nhầm phần nhúng phiên bản 2 bằng phiên bản 1 đã lỗi thời.


Mặc dù người ta có thể giải quyết vấn đề này bằng cách giới thiệu tính năng theo dõi phiên bản rõ ràng, nhưng nó gây ra sự phức tạp đáng kể mà không mang lại lợi ích về hiệu suất. Chiến lược mà chúng tôi đã chọn không chỉ giảm thiểu vấn đề này mà còn ngăn chặn các hoạt động dư thừa và lãng phí công việc bằng cách thực thi đồng thời các tập lệnh.


Khóa tư vấn Postgres, có tiền tố là mã định danh bảng để tránh sự trùng lặp tiềm ẩn với các khóa khác, được sử dụng. Biến thể try , tương tự như ứng dụng SKIP LOCKED trước đó, đảm bảo hệ thống tránh phải chờ khóa. Việc đưa vào mệnh đề ORDER BY blog_id giúp ngăn ngừa tình trạng bế tắc tiềm ẩn. Chúng tôi sẽ đề cập đến một số lựa chọn thay thế dưới đây.


  • Dọn dẹp hàng đợi công việc : Sau đó, tập lệnh sẽ xóa tất cả các mục trong hàng đợi công việc đối với các blog mà chúng ta đã khóa thành công. Nếu các mục hàng đợi này hiển thị thông qua Kiểm soát đồng thời nhiều phiên bản (MVCC), thì các cập nhật của chúng sẽ được hiển thị trong hàng blog được truy xuất. Lưu ý rằng chúng tôi xóa tất cả các mục có ID blog nhất định, không chỉ các mục được đọc khi chọn hàng: điều này xử lý hiệu quả các mục nhập trùng lặp cho cùng một ID blog. Điều quan trọng cần lưu ý là việc xóa này chỉ được thực hiện sau khi gọi hàm embed_and_write() và lưu trữ nội dung nhúng đã cập nhật sau đó. Trình tự này đảm bảo chúng tôi không mất bất kỳ bản cập nhật nào ngay cả khi tập lệnh bị lỗi trong giai đoạn tạo nhúng.


  • Bắt các blog để xử lý: Ở bước cuối cùng, chúng tôi tìm nạp các blog để xử lý. Lưu ý việc sử dụng phép nối bên trái: cho phép chúng tôi truy xuất ID blog cho các mục đã xóa không có hàng blog. Chúng ta cần theo dõi những mục đó để xóa phần nhúng của chúng. Trong lệnh gọi lại embed_and_write , chúng tôi sử dụng posted_time là NULL làm trọng điểm cho blog bị xóa (hoặc chưa được xuất bản, trong trường hợp đó, chúng tôi cũng muốn xóa nội dung nhúng).

Phương án 4: Tránh sử dụng khóa tư vấn bằng cách sử dụng bảng khác.

Nếu hệ thống đã sử dụng khóa tư vấn và bạn lo lắng về xung đột, bạn có thể sử dụng bảng có ID blog làm khóa chính và khóa các hàng. Trên thực tế, đây có thể là bảng blog nếu bạn chắc chắn rằng các khóa này sẽ không làm chậm bất kỳ hệ thống nào khác (hãy nhớ rằng các khóa này phải được giữ trong suốt quá trình nhúng, quá trình này có thể mất một lúc).


Ngoài ra, bạn có thể có bảng blog_embedding_locks chỉ dành cho mục đích này. Chúng tôi không đề xuất tạo bảng đó vì chúng tôi cho rằng nó có thể khá lãng phí về mặt không gian và việc sử dụng khóa tư vấn sẽ tránh được chi phí này.

Kết luận và các bước tiếp theo

Chúng tôi đã giới thiệu PGVectorizer và phác thảo một hệ thống chuyên nghiệp trong việc tạo ra các vectơ nhúng từ dữ liệu được lưu trữ trong PostgreSQL và tự động cập nhật chúng. Kiến trúc này đảm bảo các phần nhúng vẫn được đồng bộ hóa với dữ liệu không ngừng phát triển, phản hồi liền mạch với các phần chèn, sửa đổi và xóa.


Trong bài đăng trên blog này, chúng tôi đã cung cấp cho bạn cái nhìn hậu trường về cách chúng tôi tạo ra một hệ thống có khả năng phục hồi, xử lý hiệu quả các thời gian ngừng hoạt động tiềm ẩn của dịch vụ tạo nhúng. Thiết kế của nó rất thành thạo trong việc quản lý tốc độ sửa đổi dữ liệu cao và có thể sử dụng liền mạch các quy trình tạo nhúng đồng thời để đáp ứng tải tăng cao.


Hơn nữa, mô hình cam kết dữ liệu với PostgreSQL và sử dụng cơ sở dữ liệu để quản lý việc tạo nhúng trong nền nổi lên như một cơ chế dễ dàng để giám sát việc bảo trì nhúng trong quá trình sửa đổi dữ liệu. Vô số bản demo và hướng dẫn trong không gian AI tập trung đặc biệt vào việc tạo dữ liệu ban đầu từ tài liệu, bỏ qua các sắc thái phức tạp liên quan đến việc duy trì đồng bộ hóa dữ liệu khi nó phát triển.


Tuy nhiên, trong môi trường sản xuất thực tế, dữ liệu luôn thay đổi và việc vật lộn với sự phức tạp của việc theo dõi và đồng bộ hóa những thay đổi này không phải là một nỗ lực tầm thường. Nhưng đó chính là mục đích của cơ sở dữ liệu! Tại sao không chỉ sử dụng nó?


Dưới đây là một số tài nguyên để tiếp tục hành trình học tập của bạn :



Viết bởi Matvey Arye.

Cũng được xuất bản ở đây.