pgvector: เวกเตอร์ฝังตัวใน PostgreSQL
เปิดใช้ส่วนขยาย pgvector ใน PostgreSQL สร้างตารางที่มีคอลัมน์เวกเตอร์ แทรกเวกเตอร์ฝังตัว และเรียกใช้คำค้นหาเพื่อนบ้านใกล้เคียงโดยใช้ตัวดำเนินการระยะโคไซน์
pgvector: เวกเตอร์ฝังตัวใน PostgreSQL เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
pgvector: การค้นหาเวกเตอร์ใน PostgreSQL
pgvector เป็นส่วนขยาย PostgreSQL แบบโอเพนซอร์สที่เพิ่มชนิดข้อมูล vector และตัวดำเนินการค้นหาความคล้ายคลึง ช่วยให้คุณจัดเก็บเอ็มเบดดิงร่วมกับข้อมูลแอปพลิเคชันทั่วไปในฐานข้อมูลเดียวกับที่ใช้งานอยู่แล้ว โดยไม่ต้องมีที่จัดเก็บเวกเตอร์แยกต่างหาก
เหมาะอย่างยิ่งสำหรับทีมที่ใช้ PostgreSQL อยู่แล้วและต้องการเพิ่มการค้นหาเชิงความหมายโดยไม่เพิ่มการพึ่งพาโครงสร้างพื้นฐานใหม่
การเปิดใช้ส่วนขยาย pgvector
ติดตั้ง pgvector จากคลังอย่างเป็นทางการ หรือใช้ผู้ให้บริการ PostgreSQL แบบมีการจัดการที่ติดตั้งไว้ล่วงหน้าแล้ว (Supabase, Neon, AWS RDS, Render) จากนั้นเปิดใช้งานในฐานข้อมูลด้วยคำสั่ง SQL เพียงคำสั่งเดียว โดยไม่ต้องเริ่มระบบใหม่
-- Run this once per database to enable the extension
CREATE EXTENSION IF NOT EXISTS vector;
-- Verify it's installed
SELECT extname, extversion
FROM pg_extension
WHERE extname = 'vector';
-- Returns: vector | 0.7.0 (or similar)การสร้างตารางที่มีคอลัมน์เวกเตอร์
เพิ่มคอลัมน์เวกเตอร์โดยระบุ vector(n) โดย n คือมิติของเวกเตอร์ฝังตัว คุณสามารถใช้ร่วมกับคอลัมน์ PostgreSQL ปกติสำหรับข้อมูลเมทาดาทาได้ ทำให้กรองด้วย user_id, created_at หรือฟิลด์อื่น ๆ โดยใช้คำสั่ง SQL WHERE มาตรฐาน
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
category TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
embedding vector(1536) -- must match your model dimension
);
-- Index on category for fast metadata filtering
CREATE INDEX ON documents (category);
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'documents';การแทรกเวกเตอร์ฝังตัวจาก Python
ใช้ไดรเวอร์ psycopg2 หรือ asyncpg เพื่อแทรกแถวที่มีเวกเตอร์ฝังตัว แปลงรายการตัวเลขทศนิยมของ Python เป็นสตริงในรูปแบบ '[0.1, 0.2, ...]' ซึ่ง pgvector จะแยกวิเคราะห์ได้อย่างถูกต้อง แพ็กเกจ Python pgvector มีตัวช่วย register_vector สำหรับจัดการเรื่องนี้โดยอัตโนมัติ
import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI
conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
cur = conn.cursor()
client = OpenAI()
document = 'pgvector adds vector search to PostgreSQL.'
resp = client.embeddings.create(model='text-embedding-3-small', input=document)
embedding = resp.data[0].embedding
cur.execute(
'INSERT INTO documents (content, category, embedding) VALUES (%s, %s, %s)',
(document, 'database', embedding)
)
conn.commit()
print('Inserted document with embedding')ความคล้ายคลึงโคไซน์ด้วยตัวดำเนินการ <=>
pgvector เพิ่มตัวดำเนินการระยะห่างสามแบบ:
<=>— ระยะห่างโคไซน์ (1 - cosine_similarity)<->— ระยะห่างแบบยุคลิด (L2)<#>— ผลคูณภายในเชิงลบ (ใช้สำหรับความคล้ายคลึงของผลคูณจุด)
สำหรับเวกเตอร์ฝังตัวของข้อความ ให้ใช้ <=> (ระยะห่างโคไซน์) ORDER BY distance ASC จะคืนเอกสารที่คล้ายคลึงกันมากที่สุดก่อน
-- Find top 5 documents most similar to a query embedding
-- Replace '[0.1, 0.2, ...]' with the actual query vector
SELECT
id,
content,
category,
1 - (embedding <=> '[0.1, 0.2, 0.3]'::vector) AS cosine_similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, 0.3]'::vector
LIMIT 5;การรวมการค้นหาเวกเตอร์เข้ากับตัวกรอง SQL
ข้อได้เปรียบสำคัญประการหนึ่งของ pgvector คือคุณสามารถรวมการค้นหา ANN เข้ากับคำสั่ง SQL WHERE มาตรฐานได้ ทำให้กรองข้อมูลเมทาดาทาได้โดยตรงโดยไม่ต้องใช้ไวยากรณ์พิเศษ เพียงเขียน SQL ตามปกติ
-- Semantic search filtered to the 'database' category
-- and only recent documents
SELECT
id,
content,
1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE
category = 'database'
AND created_at > NOW() - INTERVAL '30 days'
ORDER BY embedding <=> %s::vector
LIMIT 5;
-- In Python with psycopg2:
# cur.execute(sql, (query_embedding, query_embedding))การสร้างดัชนี HNSW เพื่อเพิ่มความเร็ว
หากไม่มีดัชนี pgvector จะสแกนทุกแถวแบบตรงทั้งหมด ซึ่งเหมาะสำหรับข้อมูลไม่เกิน 10,000 แถว แต่จะช้าลงเมื่อข้อมูลมีขนาดใหญ่ขึ้น ให้สร้าง ดัชนี HNSW สำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุดแบบประมาณค่า พารามิเตอร์ m (จำนวนการเชื่อมต่อในแต่ละโหนด) และ ef_construction (ความกว้างของการค้นหาระหว่างสร้างดัชนี) เป็นการแลกเปลี่ยนระหว่างขนาดดัชนีและเวลาสร้าง กับความแม่นยำของการเรียกคืน
-- Create an HNSW index for cosine distance queries
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- At query time, control recall vs speed:
SET hnsw.ef_search = 40; -- higher = better recall, slower
-- Verify the index is being used:
EXPLAIN SELECT * FROM documents
ORDER BY embedding <=> '[0.1]'::vector(1)
LIMIT 5;ดัชนี IVFFlat: ทางเลือกแทน HNSW
ประเภทดัชนี IVFFlat จัดกลุ่มเวกเตอร์ลงในกลุ่ม lists และขณะสืบค้นจะค้นหาเฉพาะกลุ่ม probes ที่อยู่ใกล้ที่สุด ดัชนีนี้สร้างได้เร็วกว่า HNSW และใช้หน่วยความจำน้อยกว่า แต่มีความแม่นยำของการเรียกคืนต่ำกว่าเล็กน้อยเมื่อใช้ความเร็วเท่ากัน
หลักทั่วไปคือ ให้ใช้ IVFFlat เมื่อต้องการสร้างดัชนีให้เร็วขึ้นระหว่างการสร้างดัชนีใหม่บ่อย ๆ และใช้ HNSW กับคลังข้อมูลที่มีความคงที่และต้องการความเร็วในการสืบค้นสูงสุด
-- IVFFlat index: good for large, infrequently updated corpora
-- lists ≈ sqrt(n) where n is the number of vectors
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
-- At query time, probes controls recall vs speed:
SET ivfflat.probes = 10; -- check 10 of 100 clustersตัวอย่างการสืบค้นด้วย Python ฉบับสมบูรณ์
ต่อไปนี้คือตัวอย่างฟังก์ชัน Python ฉบับสมบูรณ์ที่รับคำสืบค้นจากผู้ใช้ สร้างเวกเตอร์ฝังตัว ดำเนินการค้นหาความคล้ายคลึงด้วย pgvector พร้อมกรองข้อมูลเมทาดาทา และคืนผลลัพธ์อันดับต้น ๆ เป็นรายการของพจนานุกรม
import psycopg2
from pgvector.psycopg2 import register_vector
from openai import OpenAI
conn = psycopg2.connect('postgresql://user:pass@localhost/mydb')
register_vector(conn)
client = OpenAI()
def semantic_search(query, category=None, top_k=5):
resp = client.embeddings.create(model='text-embedding-3-small', input=query)
q_vec = resp.data[0].embedding
sql = '''
SELECT content,
1 - (embedding <=> %s::vector) AS similarity
FROM documents
{where}
ORDER BY embedding <=> %s::vector
LIMIT %s
'''
where = 'WHERE category = %s' if category else ''
params = [q_vec, q_vec, top_k] if not category else [q_vec, category, q_vec, top_k]
cur = conn.cursor()
cur.execute(sql.format(where=where), params)
return [{'text': r[0], 'score': r[1]} for r in cur.fetchall()]ข้อแลกเปลี่ยนระหว่าง pgvector กับ Pinecone
การเปรียบเทียบ pgvector กับ Pinecone:
- pgvector: ติดตั้งและดูแลเอง ไม่มีค่าใช้จ่ายเพิ่มเติม ทำงานร่วมกับ SQL ได้อย่างสมบูรณ์ รองรับเวกเตอร์ประมาณ 5 ล้านรายการได้ดี แต่ต้องมีความรู้ด้านการดูแลฐานข้อมูลเพื่อปรับแต่ง
- Pinecone: มีการจัดการเต็มรูปแบบ รองรับขนาดใหญ่มาก (เวกเตอร์หลายพันล้านรายการ) มีการกรองเฉพาะทาง ค่าใช้จ่ายสูงกว่า และต้องดูแลบริการแยกต่างหาก
เลือก pgvector เมื่อคุณใช้งาน PostgreSQL อยู่แล้วและคลังข้อมูลมีเอกสารไม่ถึงไม่กี่ล้านรายการ เลือก Pinecone เมื่อจำเป็นต้องรองรับข้อมูลขนาดใหญ่มาก หรือเมื่อการหลีกเลี่ยงภาระด้านการดูแลระบบคุ้มค่ากับค่าใช้จ่าย
การใช้ pgvector กับ Supabase
Supabase คือบริการ PostgreSQL แบบโฮสต์ที่ติดตั้ง pgvector ไว้ล่วงหน้าแล้ว โดยมีไคลเอ็นต์ Python (supabase-py) และ REST API สำหรับการสืบค้นเวกเตอร์ ทำให้เป็นวิธีที่ง่ายที่สุดในการตั้งค่า pgvector สำหรับใช้งานจริงโดยไม่ต้องดูแลเซิร์ฟเวอร์ฐานข้อมูลด้วยตนเอง
from supabase import create_client
import os
url = os.environ['SUPABASE_URL']
key = os.environ['SUPABASE_SERVICE_KEY']
supabase = create_client(url, key)
# Insert a document with embedding
supabase.table('documents').insert({
'content': 'Supabase hosts PostgreSQL with pgvector.',
'embedding': embedding # list of 1536 floats
}).execute()
# Vector similarity search via RPC (Supabase edge function)
# result = supabase.rpc('match_documents', {'query_embedding': q_vec, 'match_count': 5}).execute()ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจแนวคิดด้านวิศวกรรม AI จากบทเรียนนี้
ทบทวนบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า pgvector เพิ่มชนิดคอลัมน์เวกเตอร์และตัวดำเนินการวัดระยะห่างแบบโคไซน์และแบบยุคลิดให้กับ PostgreSQL ดัชนี HNSW ช่วยให้ค้นหาเพื่อนบ้านที่ใกล้ที่สุดแบบประมาณค่าได้อย่างรวดเร็วเมื่อข้อมูลมีขนาดใหญ่ และ คำสั่ง SQL WHERE มาตรฐานช่วยกรองข้อมูลเมทาดาทาได้โดยไม่ต้องใช้ไวยากรณ์พิเศษ บทถัดไปเราจะเปรียบเทียบตัวเลือกคลังเวกเตอร์หลักทั้งหมด เพื่อช่วยคุณเลือกตัวเลือกที่เหมาะกับโครงการ
คำถามที่พบบ่อย
บทเรียน “pgvector: เวกเตอร์ฝังตัวใน PostgreSQL” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “pgvector: เวกเตอร์ฝังตัวใน PostgreSQL” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “pgvector: เวกเตอร์ฝังตัวใน PostgreSQL”
เปิดใช้ส่วนขยาย pgvector ใน PostgreSQL สร้างตารางที่มีคอลัมน์เวกเตอร์ แทรกเวกเตอร์ฝังตัว และเรียกใช้คำค้นหาเพื่อนบ้านใกล้เคียงโดยใช้ตัวดำเนินการระยะโคไซน์ คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “pgvector: เวกเตอร์ฝังตัวใน PostgreSQL” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม
ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เหตุใดคุณจึงต้องมีฐานข้อมูลเวกเตอร์
- เริ่มต้นใช้งาน Pinecone
- pgvector: เวกเตอร์ฝังตัวใน PostgreSQL
- การเลือกและทดสอบประสิทธิภาพแหล่งจัดเก็บเวกเตอร์