Eine Vektordatenbank speichert und sucht numerische Vektoren (Embeddings) effizient. Sie sind das Rückgrat von RAG-Systemen.


Was ist ein Embedding?

Text: "Der Hund springt schnell"
      ↓ (Embedding Model: all-MiniLM-L6-v2)
Vector: [0.234, -0.512, 0.891, ..., 0.123]  (384-dim)

Jede Zahl repräsentiert eine semantische Eigenschaft (z.B. "animal-ness", "movement", "speed").


Ähnlichkeitsmetriken

Cosine Similarity (Standard)

Vector A: [1, 0, 0]
Vector B: [0.866, 0.5, 0]  (rotiert um 30°)

cos(A, B) = (A · B) / (||A|| × ||B||)
          = 0.866 / (1 × 1)
          = 0.866

Range: [-1, 1]
      -1 = entgegengesetzt
       0 = orthogonal (unabhängig)
       1 = identisch

Praktisch:

  • Unabhängig von Magnitude (Länge)
  • "Winkel" zwischen Vektoren
  • Standard für Semantic Search

Dot Product (schneller)

A · B = 0.234 × 0.156 + (-0.512) × 0.321 + ...

Gleich wie Cosine, aber nicht normalisiert
→ Nur sinnvoll wenn Vektoren normalisiert sind!

Vorteil: Schneller (keine Normalisierung nötig) Nachteil: Kann zu Magnitude-Bias führen wenn Vektoren variabel groß

Euclidean Distance

d(A, B) = √(Σ(A_i - B_i)²)

Beispiel:
A = [1, 2]
B = [4, 6]
d = √((1-4)² + (2-6)²) = √(9 + 16) = 5

Range: [0, ∞]
      0 = identisch
      > = unähnlich

Wann: Manchmal in speziellen Anwendungen, aber meist nicht für Semantic Search.


Vektordatenbank Vergleich (2026)

Feature ChromaDB Pinecone Weaviate Qdrant Milvus pgvector
Type In-Memory + Persist Managed Cloud Graph-Vector Cloud/Self-Hosted Distributed PostgreSQL Plugin
Setup pip install (trivial) API nur Container Container Kubernetes SQL Extension
Lokal ✅ (mit PostgreSQL)
Skalierung Mittel Unlimited Gut Gut Sehr Gut Begrenzt (DB)
Filtering Basic Excellente Excellente Gut Gut Excellente (SQL)
Cost (Self) Free - Free Free Free ~€5-20/Mo
Cost (Cloud) $0.03/M vectors Pay-per-API €500+/Mo Starter Free Enterprise PostgreSQL Costs
Metadata Mittel Excellente Excellente Gut Gut Excellente (SQL)

Detaillierte Optionen

ChromaDB (Anfänger-freundlich)

from chromadb import Client

client = Client()
collection = client.create_collection(
    name="my_documents",
    metadata={"hnsw:space": "cosine"}
)

# Add documents
collection.add(
    ids=["1", "2", "3"],
    documents=["Der Hund springt", "Eine Katze ruht", "Der Vogel fliegt"],
    metadatas=[
        {"source": "article1"},
        {"source": "article2"},
        {"source": "article3"}
    ]
)

# Query
results = collection.query(
    query_texts=["Hund springt"],
    n_results=2
)
# Returns: [["Der Hund springt", "Der Vogel fliegt"], distances, metadatas]

Vorteile:

  • Trivial zu starten (5 Zeilen Code)
  • Embedded möglich (keine separaten Server)
  • Open-Source, aktiv entwickelt

Nachteile:

  • Skaliert nicht über 100M vectors
  • Keine komplexen Filtering-Operationen
  • Keine Replikation/HA native

Best For: Prototyping, kleine bis mittlere Systeme (<10M vectors)


Pinecone (Managed, Production)

import pinecone

pinecone.init(api_key="YOUR_KEY", environment="us-west1-gcp")
index = pinecone.Index("my-index")

# Upsert vectors
index.upsert(
    vectors=[
        ("id1", [0.234, -0.512, ...], {"text": "Der Hund springt"}),
        ("id2", [0.891, 0.234, ...], {"text": "Eine Katze ruht"}),
    ],
    namespace="default"
)

# Search
results = index.query(
    vector=[0.245, -0.501, ...],  # Query vector
    top_k=5,
    filter={
        "source": {"$eq": "article1"}
    },
    include_metadata=True
)

Stärken:

  • Vollständig managed (kein Ops-Overhead)
  • Excellente Filtering (metadata search)
  • Unlimited skalierbar
  • 99.99% SLA

Schwächen:

  • Nicht open-source
  • Teuer bei großem Volumen (pay-per-vector)
  • Vendor Lock-in

Best For: Produktion, hohe Anforderungen, Budgets vorhanden


Weaviate (Knowledge Graphs + Vectors)

import weaviate

client = weaviate.Client("http://localhost:8080")

# Define schema
client.schema.create_class({
    "class": "Document",
    "vectorizer": "text2vec-openai",  # Auto-embed text
    "properties": [
        {
            "name": "content",
            "dataType": ["text"]
        },
        {
            "name": "source",
            "dataType": ["string"]
        }
    ]
})

# Add data
with client.batch as batch:
    batch.add_data_object(
        data_object={
            "content": "Der Hund springt schnell",
            "source": "article1"
        },
        class_name="Document"
    )

# Semantic search
results = client.query.get("Document").with_near_text({
    "concepts": ["Hund springt"]
}).with_where({
    "path": ["source"],
    "operator": "Equal",
    "valueString": "article1"
}).do()

Strengths:

  • Knowledge Graph Features (Relations zwischen Objekten)
  • Multi-Modales (Text, Bilder, Audio gleichzeitig)
  • Graph Traversal (kann Relationen folgen)
  • Open-Source

Schwächen:

  • Komplexer zu deployen
  • Speicher-hungrig
  • Graphquery-Performance kann problematisch sein bei großen Graphen

Best For: Komplexe Relationen, Knowledge Graphs, Multi-Modal


Qdrant (Rust-optimiert, schnell)

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

client = QdrantClient(url="http://localhost:6333")

# Create collection
client.create_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
)

# Add points
client.upsert(
    collection_name="documents",
    points=[
        PointStruct(
            id=1,
            vector=[0.234, -0.512, ...],
            payload={"text": "Der Hund springt"}
        ),
    ]
)

# Search
results = client.search(
    collection_name="documents",
    query_vector=[0.245, -0.501, ...],
    limit=5,
    query_filter={
        "must": [
            {
                "key": "text",
                "match": {"text": "Hund"}
            }
        ]
    }
)

Strengths:

  • Geschrieben in Rust (sehr schnell)
  • Hybrid Search (Vector + BM25 Text)
  • Open-Source, selbst-gehostet einfach
  • Kostenlos

Schwächen:

  • Kleineres Ökosystem als Weaviate
  • Hybrid Search noch experimentell

Best For: Performance-kritisch, Self-Hosted, Cost-sensitive


Milvus (Enterprise, Kubernetes)

from pymilvus import Collection, connections, CollectionSchema, FieldSchema, DataType

connections.connect("default", host="localhost", port="19530")

fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
    FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=384),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512),
]

schema = CollectionSchema(fields, "Document collection")
collection = Collection("documents", schema)

# Insert
collection.insert([
    [1, 2],  # IDs
    [[0.234, -0.512, ...], [0.891, 0.234, ...]],  # Vectors
    ["Der Hund springt", "Eine Katze ruht"],  # Texts
])

# Search
results = collection.search([0.245, -0.501, ...], "vector", limit=5)

Strengths:

  • Massiv skalierbar (Kubernetes native)
  • Enterprise-Features (Replication, Sharding)
  • Open-Source
  • Best für Millionen Vektoren

Schwächen:

  • Komplexe Deployment
  • Overkill für kleine bis mittlere Use-Cases
  • DevOps-intensive

Best For: Enterprise, massive Scale, Self-Managed Infrastructure


pgvector (PostgreSQL Extension)

CREATE EXTENSION vector;

CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    content TEXT,
    embedding vector(384),
    source VARCHAR(255)
);

CREATE INDEX ON documents USING HNSW (embedding vector_cosine_ops);

-- Insert
INSERT INTO documents (content, embedding, source)
VALUES (
    'Der Hund springt schnell',
    '[0.234, -0.512, ..., 0.123]'::vector,
    'article1'
);

-- Search
SELECT id, content, embedding <=> '[0.245, -0.501, ...]'::vector AS distance
FROM documents
WHERE source = 'article1'
ORDER BY embedding <=> '[0.245, -0.501, ...]'::vector
LIMIT 5;

Strengths:

  • SQL Queries (full power)
  • Integriert mit PostgreSQL (Backup, Replication existieren)
  • Billiger als spezialisierte Lösungen
  • ACID Guarantees

Schwächen:

  • Nicht so optimiert wie spezialisierte Vector DBs
  • Scaling begrenzt (noch immer einzelne DB)
  • Neuere Technologie (nicht Enterprise-getestet wie Milvus)

Best For: Kleine bis mittlere Systeme, SQL-Heavy Workflows, Existing PostgreSQL Users


Indexing-Strategien

HNSW (Hierarchical Navigable Small World)

Approximative Nearest Neighbor Search Algorithm

Idee: Baue hierarchisches "Small World" Netzwerk
      von Vektoren, wo nahe Vektoren verbunden sind

Struktur:
Level 0: [Alle Vektoren, vollständig verbunden]
Level 1: [Subset, gröbere Navigation]
Level 2: [Noch gröberer]

Search:
1. Start am höchsten Level
2. Navigiere zu nächstem Nachbarn
3. Wenn kein besserer Found, geh zum nächsten Level
4. Repeat

Properties:

  • Fast O(log N) Suche
  • Memory-effizient
  • Probabilistisch (beste Annäherung, nicht Garantie)

Wann: Standard für ≤100M Vektoren


IVF (Inverted File)

Idee: Cluster Vektoren, speichere Cluster-Indizes

1. Offline: K-means clustering (z.B. 100 Cluster)
2. Speichere welche Vektoren in welchem Cluster

Search:
1. Berechne nächste Cluster(s) zur Query
2. Suche nur in diesen Clustern
3. → Viel schneller (nur 1-5% der Vektoren durchsucht)

Trade-off:

  • Schneller bei großem K (Cluster count)
  • Weniger Speicher als HNSW
  • Aber: Risk von schlechten Clusterings

Wann: >100M Vektoren, wenn Speicher kritisch


Self-Hosted vs. Cloud

Self-Hosted (ChromaDB, Qdrant, Milvus lokal)

Kostenstruktur:
- Initial: 0€ (Software free)
- Server: ~€50-200/Mo (VM)
- Ops: ~10h/Mo (Backup, Monitoring)
- Total: ~€150-300/Mo

Scaling:
- Braucht Engineering (Sharding, Replikation)
- Bottleneck: Network, Speicher
- Bis ~10M Vektoren machbar solo

Cloud-Managed (Pinecone, Weaviate Cloud)

Kostenstruktur:
- Vectors: €0.01-0.10 pro 1M
- Queries: €0.04-0.10 pro 1M
- Minimum: ~€50/Mo
- 10M Vectors: ~€100/Mo + Query Costs

Skalierung:
- Automatic (kein Ops)
- Replicated (HA standard)
- Global (CDN möglich)
- Bottleneck: Cost bei großem Volume

Cost Breakeven

ChromaDB/Qdrant (Self-Hosted):
Initial + Server + Ops = ~€150-300/Mo

Pinecone:
10M Vectors = ~€100/Mo + Query Costs

Breakeven:
- Kleine Systeme (<5M vectors): Cloud besser
- Mittlere (5-50M): Self-Hosted meist besser
- Große (>50M): Self-Hosted definitiv besser (aber OpsCosts steigen)

Praktische Integration mit RAG

from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 1. Create Vector Store
embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_documents(
    documents=documents,
    embedding=embeddings,
    collection_name="my_docs",
)

# 2. Retrieval
retriever = vector_store.as_retriever(
    search_type="similarity",  # oder "mmr"
    search_kwargs={"k": 3}
)

# 3. In RAG Pipeline
from langchain.chains import RetrievalQA

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type="stuff"  # oder "map_reduce", "refine"
)

answer = qa_chain.run("Frage?")

Vektordatenbanken sind kritisch für RAG. Wähle basierend auf:

  • Größe: <10M → ChromaDB/pgvector, >100M → Qdrant/Milvus
  • Komplexität: Einfach → ChromaDB, Komplex → Weaviate
  • Budget: Unbegrenzt → Pinecone, Sparen → Self-Hosted