2. Lưu trữ KG trên PostgreSQL
Ở phần trước, bạn đã thực hiện cài đặt KG trên Python, trong đó:
- KG là một tập hợp các bộ-3: (Thực thể) -[Mối quan hệ]-> (Thực thể)
- Python sử dụng kiểu dữ liệu tuple để biểu diễn bộ-3
- Python sử dụng kiểu list để chứa toàn bộ KG (toàn bộ các bộ-3)
Với cách làm trên, chúng ta đã thực hiện cài đặt KG trên bộ nhớ máy tính (trên RAM). Cách cài đặt này chủ yếu để bạn tìm hiểu về KG, chứ không dùng trên môi trường thực tế. Vì nó có một số hạn chế sau:
- Khi tắt máy hoặc tắt chương trình thì KG cũng biến mất
- KG có kích thước lớn sẽ làm tràn bộ nhớ
- Không hỗ trợ xử lý đồng thời
- Thiếu công cụ truy vấn
Trong thực tế, với các hệ thống phần mềm lớn, có một số cách sau để lưu KG:
- Sử dụng Hệ quản trị cơ sở dữ liệu (HQTCSDL) thông thường
- Sử dụng Hệ quản trị cơ sở dữ liệu chuyên cho KG
- Kết hợp trong các hệ thống AI hiện đại
2.1 Sử dụng HQTCSDL thông thường
Cách này tận dụng hệ thống có sẵn của doanh nghiệp, tiện cho việc cài đặt, tiết kiệm chi phí, phù hợp với KG chưa quá lớn và không đòi hỏi hiệu năng xử lý cao.
Bạn có thể sử dụng PostgreSQL, MySQL, SQL Server, MongoDB, Redis.
Thực hành cài đặt
Trên máy tính của bạn đang có HQTCSDL nào thì bạn thực hiện cài đặt KG trên đó.
Ví dụ, tôi sẽ cài đặt trên PostgreSQL.
Để lưu trữ KG lên PostgreSQL, cách hiệu quả nhất là dùng Danh sách kề (Adjacency List), gồm 2 bảng:
- Bảng entities: Lưu các thực thể
- Bảng relationships: Lưu bộ-3, gồm thực thể nguồn (source_id), thực thể địch (target_id) và tên mối quan hệ (relation)
Bước 1: Thiết kế và tạo CSDL trong PostgreSQL
- Mở pgAdmin, tạo một CSDL mới (ví dụ: knowledge_graph_db) và chạy tập lệnh DDL sau:
[SQL]
-- 1. Tạo bảng lưu trữ các thực thể (entities)
CREATE TABLE IF NOT EXISTS entities (
id SERIAL PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL
);
-- 2. Tạo bảng lưu trữ các mối quan hệ (Relationships / Edges)
CREATE TABLE IF NOT EXISTS relationships (
id SERIAL PRIMARY KEY,
source_id INT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
target_id INT NOT NULL REFERENCES entities(id) ON DELETE CASCADE,
relation VARCHAR(255) NOT NULL,
CONSTRAINT unique_triple UNIQUE(source_id, target_id, relation)
);
Bước 2: Viết mã Python để chèn dữ liệu vào PostgreSQL
Để làm việc với PostgreSQL từ Python, bạn sử dụng thư viện psycopg2.
Cài đặt thư viện psycopg2 (nếu chưa có):
[CMD]
pip install psycopg2
Viết mã nguồn Python:
[insert_kg.py]
import psycopg2
# 1. Thông tin kết nối CSDL (Hãy thay đổi thông số theo cấu hình của bạn)
DB_CONFIG = {
"dbname": "knowledge_graph_db",
"user": "postgres",
"password": "your_password", # Thay mật khẩu của bạn vào đây
"host": "localhost",
"port": "5432"
}
# Tập bộ-3 (triples) đầu vào
triples = [
("RAG", "LLM", "cải thiện"),
("RAG", "Knowledge Graph", "kết hợp với"),
("Knowledge Graph", "Hiện tượng Hallucination", "giúp giảm thiểu"),
("Knowledge Graph", "Ngữ cảnh cấu trúc / Multi-hop Reasoning", "cung cấp"),
("LLM", "Thiếu tri thức miền chuyên sâu / Dữ liệu thời gian thực", "gặp hạn chế về")
]
def get_or_create_entity(cursor, entity_name):
"""Thêm thực thể vào bảng entities nếu chưa tồn tại và trả về ID."""
cursor.execute(
"""
INSERT INTO entities (name)
VALUES (%s)
ON CONFLICT (name) DO UPDATE SET name = EXCLUDED.name
RETURNING id;
""",
(entity_name,)
)
return cursor.fetchone()[0]
try:
# 2. Kết nối tới PostgreSQL
conn = psycopg2.connect(**DB_CONFIG)
cursor = conn.cursor()
# 3. Duyệt từng triple và chèn dữ liệu
for source, target, relation in triples:
# Lấy hoặc tạo mới ID cho thực thể nguồn và đích
source_id = get_or_create_entity(cursor, source)
target_id = get_or_create_entity(cursor, target)
# Chèn mối quan hệ (tránh trùng lặp nhờ ON CONFLICT)
cursor.execute(
"""
INSERT INTO relationships (source_id, target_id, relation)
VALUES (%s, %s, %s)
ON CONFLICT (source_id, target_id, relation) DO NOTHING;
""",
(source_id, target_id, relation)
)
# 4. Lưu thay đổi vào CSDL
conn.commit()
print("-> Đã lưu thành công Knowledge Graph vào PostgreSQL!")
except Exception as e:
if 'conn' in locals():
conn.rollback()
print("Lỗi khi chèn dữ liệu:", e)
finally:
if 'cursor' in locals():
cursor.close()
if 'conn' in locals():
conn.close()
Bước 3: Chạy đoạn mã Python (insert_kg.py)
Bước 4: Truy vấn kiểm tra dữ liệu từ PostgreSQL
Sau khi chạy đoạn mã Python, bạn có thể mở CSDL knowledge_graph_db trong pgAdmin để xem dữ liệu đã được chèn vào các bảng.
Hoặc có thể sử dụng lệnh SQL sau để kiểm tra và lấy lại các bộ-3 dữ liệu:
[SQL]
SELECT
e1.name AS source,
r.relation,
e2.name AS target
FROM relationships r
JOIN entities e1 ON r.source_id = e1.id
JOIN entities e2 ON r.target_id = e2.id;
2.2 Xem và đọc thêm
Sử dụng các từ khóa sau, tìm kiếm trong Google, Youtube và Chatbot để đọc và xem thêm: cài đặt KG vào HQTCSDL thông thường và Python.
2.3 Bài tập và câu hỏi
Bài tập 2.1: Thực hiện lại các cài đặt như trong phần lý thuyết của bài học.
Bài tập 2.2: Cho KG gồm các bộ-3 (triple) sau:
(Sinh viên) ──[đang theo học]──> (Ngành Khoa học máy tính)
(Sinh viên) ──[tham gia]──> (Câu lạc bộ lập trình)
(Sinh viên) ──[đăng ký]──> (Môn học OOP )
(Môn học OOP) ──[được giảng dạy bởi]──> (Giảng viên)
(Giảng viên) ──[hướng dẫn]──> (Đồ án tốt nghiệp)
(Sinh viên) ──[thực hiện]──> (Đồ án tốt nghiệp)
Yêu cầu: Cài đặt KG trên vào PostgreSQL, sử dụng ngôn ngữ lập trình Python. Đặt tên CSDL là KG_SinhVien_db.
Câu hỏi
Câu 1a: Trong mô hình Danh sách kề (Adjacency List) để lưu trữ Đồ thị tri thức trên PostgreSQL, bảng relationships thường lưu trữ các thành phần nào của một bộ-3 (triple)?
A. Tên thực thể nguồn và tên thực thể đích (dạng chuỗi văn bản)
B. Khóa ngoại trỏ đến ID của thực thể nguồn (source_id), ID của thực thể đích (target_id) và tên mối quan hệ (relation)
C. Chỉ lưu duy nhất danh sách các mối quan hệ mà không cần liên kết với thực thể
D. Lưu toàn bộ đồ thị dưới dạng tập tin nhị phân trực tiếp trên một hàng duy nhất
Câu 1b: Tại sao đoạn mã Python chèn dữ liệu vào PostgreSQL lại sử dụng câu lệnh ON CONFLICT (name) DO UPDATE SET name = EXCLUDED.name (hoặc DO NOTHING) khi làm việc với bảng entities và relationships?
A. Để tăng tốc độ thực thi câu lệnh SQL gấp nhiều lần so với thông thường
B. Để tự động xóa bỏ toàn bộ dữ liệu cũ trong CSDL trước khi chèn dữ liệu mới vào
C. Để xử lý tình huống trùng lặp dữ liệu (khi thực thể hoặc mối quan hệ đã tồn tại trong CSDL), giúp tránh phát sinh lỗi và đảm bảo tính toàn vẹn
D. Để chuyển đổi cấu trúc đồ thị từ dạng quan hệ sang dạng phi quan hệ (NoSQL) một cách tự động



