SQL Server 2025 – Vector Search
Merhaba,
SQL Server 2025, yapay zekâ çağının dinamiklerine uyum sağlamak adına kapsamlı bir dönüşüm geçirerek, veritabanı motoruna yerleşik vektör arama (native vector search) yeteneği kazandırmıştır. Bu stratejik adım SQL Server’ı geleneksel veri yönteminin ötesine taşıyarak, yapay zekâya özgü semantik arama (semantic search) altyapısını doğal bir bileşen haline getirmiştir. Böylece metin, görsel ve ses gibi yapılandırılmamış veri türlerinde, yalnızca anahtar kelime eşleşmesine dayalı sorgularla sınırlı kalmaksızın, anlamsal benzerlik temelinde daha derinlikli ve bağlamsal sorgulamalar mümkün hale gelmiştir.
Anlayacağınız bu yenilik, yalnızca teknik bir güncelleme değil, aynı zamanda bilgi erişiminin, aramanın ve analiz süreçlerinin temel doğasını yeniden şekillendiren ve yapay zekâ destekli uygulamalar geliştirirken ilişkisel veritabanı olan SQL Server’ı bir vektör depolama katmanı olarak da kullanmamıza olanak tanıyan dönüşümsel sürecin ta kendisidir.
Şimdi gelin SQL Server’ın vector search ile ilgili bizlere sağladığı olanakları inceleyelim ve bir yandan da pratiksel olarak Python dili eşliğinde bu olanakları nasıl kullanabileceğimizi hep birlikte tecrübe edelim…
Vektör Veri Türü – Vector(n)
SQL Server 2025, artık Vector(n) adında yeni bir veri türü sunmaktadır. Bu tür sayesinde metin, görsel, ses veya diğer yapılandırılmamış verilerden elde edilen embedding vektörler doğrudan tablolar içerisinde sakalanabilmektedir.
Vektörler, tipik olarak float öğelerden oluşan sıralı dizilerdir. SQL Server, vector veri türü sayesinde bu dizileri optimize edilmiş ikili (binary) formatta saklamaktadır.
Semantik Arama Fonksiyonları
SQL Server 2025, klasik anahtar kelime tabanlı sorgulamanın ötesine geçerek, anlamsal yakınlığa dayalı (semantic similarity search) yapma olanağı tanımaktadır. Bu doğrultuda aşağıdaki algoritmaları benimseyen fonksiyonlar sunmaktadır;
- Exact k-NN Araması –
VECTOR_DISTANCE('cosine' | 'euclidean' | 'dot', v1, v2)
İki vektör arasındaki benzerliği ölçer.
Exact k-NN, verilen bir sorgu örneği için veri kümesindeki tüm noktaları tarar ve gerçek anlamda en yakın n adet komşuyu bularak getirir. Bu işlem için SQL Server, exact nearest neighbor (ENN) ya da k-NN aramasını/algoritmasını kullanmaktadır. Bu yöntem sayesinde tam doğruluk sağlanabilir ancak her vektörle mesafe hesaplandığı için büyük veri setlerinde ister istemez ciddi maliyet söz konusu olabilmektedir.
Örnek kullanım;
DECLARE @v1 VECTOR(2) = '[1,1]'; DECLARE @v2 VECTOR(2) = '[-1,-1]'; SELECT VECTOR_DISTANCE('euclidean', @v1, @v2) AS euclidean, VECTOR_DISTANCE('cosine', @v1, @v2) AS cosine, VECTOR_DISTANCE('dot', @v1, @v2) AS negative_dot_product;Yukarıdaki kod bloğunu incelersek eğer iki boyutlu @v1 ve @v2 vektörleri üzerinden
VECTOR_DISTANCEfonksiyonu ile öklid(euclidean) mesafesi, kosinüs(cosine) mesafesi ve nokta(dot) çarpımı mesafesi hesaplanmakta ve her bir metriğe göre hesaplanan mesafe aşağıdaki görselde olduğu gibi float olarak döndürülmektedir.
Bu hesaplamalar ne anlama geliyor? diye sorarsanız olayın pekte matematiksel tekniğine girmeksizin şöyle özetlemekte fayda görmekteyim;Öklid mesafesi, iki vektör arasındaki ‘düz çizgi’ mesafesini hesaplar. Haliyle çıktı olarak elde edilen sayısal değer vektörlerin uzayda birbirlerine ne kadar uzakta olduğunu ifade eder. Böylece, bu değer büyüdükçe vektörlerin daha farklı olduğu yorumunda bulunulabilir.
Kosinüs mesafesi, iki vektör arasındaki açısal farkı ölçmekte ve bu ölçüm neticesinde 0 ile 2 arasında bir değer üretilerek benzerlik analizinde bulunulabilmektedir. 2 değeri, vektörlerin tamamen zıt yönlerde (aralarındaki açı 180 derece) olduğunu göstermektedir. Haliyle örnekte verdiğimiz [1,1] ve [-1,-1] vektörlerinin de birbirine tamamen ters yönlü olduğu zahiren aşikar olsa da kosinüs ölçümü neticesinde de bu doğrulanmaktadır. Uzun lafın kısası kosinüs mesafesinde ölçün neticesi 0’a yaklaştıkça benzerlik artmakta, bilakis 2’ye yaklaştıkça azalmaktadır.
Nokta çarpımı ise vektörlerin yönelimine ve büyüklüğüne bağlı bir benzerlik ölçüsüdür. Esasında iki vektörün elemanlarının karşılıklı çarpımlarının toplamlıdır. Elde edilen netice ne kadar büyük ve pozitifse, vektörler o kadar benzerdir. Ancak SQL Server’da nokta çarpımının negatifi alındığı için bu mantığın tam tersi geçerlidir. Yani düşük veya negatif değer benzerlik gösterirken, yüksek ve pozitif değer ise farkı gösterecektir.
Ayrıca aşağıdaki örnek vektör tabanlı benzerlik aramasını da inceleyelim;
DECLARE @v AS VECTOR(512); SELECT TOP 1 @v = embedding FROM embeddings SELECT TOP(10) VECTOR_DISTANCE('cosine', @v, embedding) AS distance FROM embeddings ORDER BY distanceYukarıdaki sorguyu çalıştırdığımızda
değerinin üretildiğini gözlemlemekteyiz. Bu da yaklaşık 0.0000000596 değerine yani 0 (sıfır)’a yakın diyebiliriz. Ee haliyle kosinüs ölçümüne göre bu vektörler aynı vektörlerdir diyebiliriz.Tavsiye odur ki, k-NN araması 50.000 (elli bin) vektörden az veriye uygulanmalıdır. Daha büyük verilerde ise tabloda arama yapılacak verinin kapsamının önceden daraltılması gerekmektedir. Evet, k-NN araması, doğruluk açısından en yüksek garantiyi sağlamaktadır sağlamasına ancak yapay zekâ sistemlerinde, embedded edilmiş veriler bir tür soyutlama olduğundan %100 doğruluğa da ihtiyaç duyulmamaktadır. Bundan kaynaklı küçük veri setlerinde bu yaklaşım etkiliyken, büyük kurumsal çalışmalarda ise daha verimli yaklaşımlar hesaba katılmalıdır.
- Approximate k-NN | ANN Algoritması –
VECTOR_SEARCH(...)
ANN indekslerini kullanarak yüksek hacimli veri içinde en benzer kayıtları getirir.
Yukarıdaki satırlarda k-NN araması için, tüm veri noktalarıyla mesafe hesapladığından ve kesin sonuçlar verdiğinden ancak bunun büyük veri setleri için yavaş olabileceğinden bahsetmiştik. ANN araması ise kesin sonuçlar yerine yaklaşık (approximate) en yakın komşuları bulmak için optimizasyonlar sunmakta ve böylece sorgulama hızını artırmaktadır.
SQL Server 2025’te
VECTOR_SEARCHfonksiyonu ile ANN aramaları gerçekleştirilebilmektedir. Bu fonksiyon, vektör indekslerini kullanarak yaklaşık en yakın komşuları bulmaktadır. Bu davranışı sayesinde özellikle milyonlarca vektör içeren veri setlerinde k-NN aramasına kıyasla çok daha hızlı arama gerçekleştirebilmektedir.Bunun için, ANN algoritmasını yukarıdaki k-NN algoritmasında kullandığımız sorguyla ilişkilendirerek örneklendirirsek eğer;
DECLARE @v AS VECTOR(512); SELECT TOP 1 @v = embedding FROM embeddings SELECT TOP(10) VECTOR_DISTANCE('cosine', @v, embedding) AS distance FROM embeddings ORDER BY distanceBu sorguda, tam olarak k-NN araması yapılmaktadır ve tüm vektörlerle kosinüs mesafesi hesaplanmaktadır. Bundan kaynaklı da önceki satırlarda konuştuğumuz gibi büyük veri setlerinde yavaşlık ve yüksek maliyet söz konusu olabilmektedir.
DECLARE @v AS VECTOR(512); SELECT TOP 1 @v = embedding FROM embeddings SELECT TOP(10) VECTOR_DISTANCE('cosine', @v, embedding) AS distance FROM embeddings WHERE VECTOR_SEARCH(@v, embedding, 'cosine', 10)Bu sorguda ise vektör indeksleri kullanılarak yaklaşık en yakın 10 vektör bulunmakta ve ardından k-NN araması yapılmaktadır. Böylece tüm tabloyu taramak yerine indeks tabanlı bir arama yapılmakta ve böylece çok daha hızlı davranış sergilenmektedir.
ANN araması, vektörler arasındaki yakınlık hesaplarını grafik tabanlı veriler üzerinden gezerek yapmaktadırlar. Bu sayede; işlemci ve bellek kullanımını düşürür, yüksek sorgu başına işlem (QPS) ve düşük gecikme sağlar.
AI İle Entegrasyon: Embedding Üretimi
SQL Server 2025, Azure OpenAI, OpenAI API ve Ollama gibi yerel LLM çözümleriyle doğrudan entegre olarak vektör verisi oluşturabilmektedir. Bu entegrasyon sayesinde, T-SQL üzerinden AI_GENERATE_EMBEDDINGS fonksiyonu kullanılarak kullanıcıdan gelen metinler otomatik olarak vektör temsillerine (embeddings) dönüştürülebilir.
Bunun dışında tabi ki de AI_GENERATE_EMBEDDINGS fonksiyonu yerine özel embedding çalışmaları gerçekleştirmek de mümkündür. Ancak bu, SQL Server’ın doğrudan sağladığı entegrasyonlar dışında ek geliştirme ve yapılandırma gerektirebilmektedir. Özellikle içeriğimizin devamında pratiksel olarak sunacağımız SentenceTransformer('all-MiniLM-L6-v2') gibi bir model eşliğinde bu durumu örneklendiriyor olacağız.
Yazılımcı Bakış Açısı
Vektör indeksleri, ilişkisel indekslerden farklıdırlar. Biliyorsunuz ki biz yazılımcılar, hız ve doğruluk arasında bir denge kurmak mecburiyetindeyiz. Eğer sorgular düşük gecikme gerektiriyorsa Yaklaşık En Yakın Komşu (ANN) indeksleri ideal bir seçim olacaktır. Ancak kesinlik kritik önem taşıyorsa ve vektör sayısı makul bir seviyedeyse, Tam En Yakın Komşu (ENN) daha uygun bir tercih olacaktır. Yani gerektiği yerde maliyet gözden çıkarılmalıdır.
SQL Server’ın vektör arama yetenekleri, ilişkisel veritabanı sorgularıyla entegre çalışabildiği için güçlü bir avantaj sağlamaktadır. Bu sayede, hem embedded edilmiş vektörleri hem de yapısal verileri aynı anda işleyen çok boyutlu sorgular oluşturulabilir. Bu özellik, Retrieval-Augmented Generation (RAG) mimarilerinde yalnızca anlamsal benzerliklere dayalı sonuçlar değil, aynı zamanda bağlamsal filtrelerle (örneğin; tarih, kullanıcı grubu veya erişim düzeyi) zenginleştirilmiş, hedef odaklı bilgi getirimi sağlamaktadır. Böylece RAG sistemleri, daha anlamlı, kontrollü ve alana özgü yanıtlar üretebilme kapasitesine erişebilir.
Pratiksel Olarak Vector Embedding ve Vector Search Çalışması
Evet… Artık sıra, vector embedding ve vector search davranışlarını pratiksel olarak uygulamaya geldi diyebiliriz. Tabi tüm bu çalışmada veritabanı olarak SQL Server 2025’i tercih edeceğiz. Ancak süreçte SQL Server’ın yapay zekâ ile ilgili getirisi olan AI ile bir entegrasyon gerçekleştirmeyecek ve tüm embedding ve search çalışmasını özelleştirilmiş bir vaziyette yürüteceğiz. Ee haliyle AI_GENERATE_EMBEDDINGS fonksiyonunu bu makalede deneyimlemeyecek, o konuyu belki başka bir içeriğe yahut sizlere bırakmış olacağız.
Şimdi aşağıdaki talimatlar eşliğinde önergeleri sıralı bir şekilde seyrederek pratik çalışmaya eşlik edebilirsiniz:
-
Temel Kurulumlar
İlk olarak SQL Server 2025 ile birlikte uygulamalarla SQL Server veritabanı arasında iletişim kurmamızı sağlayacak olan ODBC Driver gibi temel kurulumların gerçekleştirilmesi gerekmektedir. Bunun için aşağıdaki talimatlar eşliğinde ilgili altyapıyı sağlayabilirsiniz.
- SQL Server 2025
SQL Server 2025’i bu talimat neticeisnde Docker container olarak ayağa kaldırın:docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Test123!" -p 1433:1433 --name sqlserver2025 -d mcr.microsoft.com/mssql/server:2025-latest
- ODBC Driver
ODBC Driver’ı bu linkten indirip, yükleyin:
https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver17
- SQL Server 2025
-
Proje Dosyalarının ve Ortamının Hazırlanması
Ardından proje dosyalarının ve ortamının hazırlanması gerekmektedir.
- Proje Klasörünün Oluşturulması
Uygun bir yerde istediğiniz isimde bir klasör oluşturun. (Benim tercih ettiğim isim : SQL_Server_2025_Vector_Embedding_And_Vector_Search) - requirements.txt’nin Oluşturulması
Oluşturulan klasörde requirements.txt adında bir dosya oluşturun ve içeriğine aşağıdaki kütüphane isimlerini yazın:flask pyodbc sentence-transformers Pillow torch numpy
‘Nedir bu kütüphanelerin işlevselliği?’ diye sorarsanız hızlıca özetleyelim;
- flask : Hafif bir Python web framework’üdür. Web uygulamaları geliştirmek için kullanılır.
- pyodbc : Python’dan ODBC veritabanlarına bağlanmak ve veri sorgulamak için kullanılan bir kütüphanedir.
- sentence-transformers : Cümle ve metinleri vektör temsillerine dönüştürmek için kullanılan bir NLP kütüphanesidir.
- Pillow : Python’da görüntü işleme ve manipülasyonu için kullanılan bir kütüphanedir.
- torch : Derin öğrenme modelleri oluşturmak ve eğitmek için kullanılan bir makine öğrenimi kütüphanesidir.
- numpy : Bilimsel hesaplamalar için çok boyutlu diziler ve matematiksel işlemler sağlayan bir kütüphanedir.
- Python Bağımlılıklarının Kurulumu
İlgili dizinde requirements.txt içerisinde belirtilen Python kütüphanelerini aşağıdaki talimat eşliğinde kurun:pip install -r requirements.txt
- app.py Dosyasının Oluşturulması
Vector embedding ve vector search işlemlerinin Python ile yürütüleceği app.py isimli dosyayı oluşturun.
- Proje Klasörünün Oluşturulması
-
Uygulamanın Geliştirilmesi
Artık uygulamayı geliştirebiliriz. Bunun için app.py dosyasında, hem vector embedding hem de vector search çalışmalarının yanında bir yandan da bu çalışmaları test edebilmemizi sağlayacak olan API çalışmalarını da Python’da yürütmemiz gerekecektir. Buradaki ilerleme mutlak sıralı takip gerektireceği için her bir önergenin başına koyduğum adım numarasını ardışık takip etmeye özen göstermenize dikkatinizi çekerim.
- 1-) Gerekli Kütüphanelerin Import Edilmesi
# Gerekli kütüphaneler import ediliyor from flask import Flask, request, jsonify from sentence_transformers import SentenceTransformer from PIL import Image import io import base64 import pyodbc import numpy as np import torch import os
- 2-) Temel Flask Nesnesinin Oluşturulması
# Flask uygulaması başlatılıyor app = Flask(__name__)
- 3-) Metin ve Görsel Veriler İçin Modellerin Yüklenmesi
# Metin verileri için embedding modeli yükleniyor text_model = SentenceTransformer('all-MiniLM-L6-v2') # Görsel veriler için CLIP tabanlı embedding modeli yükleniyor clip_model = SentenceTransformer('clip-ViT-B-32') - 4-) SQL Server Veritabanına Bağlantı Kurulması
# SQL Server veritabanına bağlantı kuruluyor try: # Direkt Example veritabanına bağlan conn = pyodbc.connect( 'DRIVER={ODBC Driver 17 for SQL Server};' 'SERVER=localhost,1433;' 'DATABASE=Example;' 'UID=sa;' 'PWD=Test123!;' 'TrustServerCertificate=yes;' ) cursor = conn.cursor() print("Example veritabanına bağlantı başarılı!") except Exception as e: print(f"SQL Server bağlantısı hatası: {e}") print("Lütfen SQL Server'ın çalıştığından ve Example veritabanının mevcut olduğundan emin olun!") raise - 5-) Embeddings Tablosunun Oluşturulması
# Embeddings tablosu oluşturuluyor def create_table(): try: # Tablo var mı kontrol et cursor.execute(""" IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='embeddings' and xtype='U') BEGIN CREATE TABLE embeddings ( id INT IDENTITY(1,1) PRIMARY KEY, data_type NVARCHAR(10), original_data NVARCHAR(MAX), embedding VECTOR(512), -- SQL Server 2025 VECTOR türü - CLIP modeli 512 boyutlu original_data_type NVARCHAR(20), file_path NVARCHAR(255), label NVARCHAR(100) ) PRINT 'VECTOR embeddings tablosu oluşturuldu!' END ELSE BEGIN PRINT 'Embeddings tablosu zaten mevcut!' END """) conn.commit() except Exception as e: print(f"Tablo oluşturulurken hata: {e}") raise # Tabloyu oluştur create_table()Vector embedding sürecinde verileri tutacağımız tablo ‘Example’ isimli veritabanı içerisine var mı yok mu kontrol edilmekte, yoksa eğer oluşturulmaktadır.
Ayrıca burada embedding kolonunun VECTOR(512) türünden olduğuna dikkatinizi çekerim. İşte bu, SQL Server 2025 ile hayatımıza girmiş olan vector türünü ilk deneyimlememiz 🙂 Günün sonunda bu kolon
görselde de görüldüğü üzere vector türünden oluşturulacaktır.
- 6-) embed Endpoint’inin Hazırlanması
# /embed endpoint'i @app.route('/embed', methods=['POST']) def embed(): try: data_type = request.form.get('type') file_path = None original_data_type = data_type label = request.form.get('label') if data_type == 'text': text = request.form.get('data') if not text: return jsonify({'error': 'Metin verisi eksik!'}), 400 try: embedding = text_model.encode(text) except Exception as e: return jsonify({'error': f'Embedding alınırken hata: {e}'}), 500 original_data = text file_path = None elif data_type == 'image': if 'data' not in request.files: return jsonify({'error': 'Görsel dosyası eksik!'}), 400 image_file = request.files['data'] try: image = Image.open(image_file.stream).convert('RGB') except Exception as e: return jsonify({'error': f'Görsel okunamadı: {e}'}), 400 save_dir = 'uploaded_images' os.makedirs(save_dir, exist_ok=True) image_filename = image_file.filename save_path = os.path.join(save_dir, image_filename) try: image.save(save_path) except Exception as e: return jsonify({'error': f'Görsel kaydedilemedi: {e}'}), 500 file_path = save_path try: embedding = clip_model.encode(image) except Exception as e: return jsonify({'error': f'Embedding alınırken hata: {e}'}), 500 try: buffered = io.BytesIO() image.save(buffered, format="PNG") original_data = base64.b64encode(buffered.getvalue()).decode() except Exception as e: return jsonify({'error': f'Base64 dönüştürme hatası: {e}'}), 500 else: return jsonify({'error': 'type must be text or image'}), 400 # Embedding'i hazırla try: embedding_array = embedding.astype(np.float32) embedding_str = f"[{','.join(map(str, embedding_array))}]" except Exception as e: return jsonify({'error': f'Embedding vectore dönüştürülürken hata: {e}'}), 500 # Veritabanına ekle try: # Önce tablo türünü kontrol et cursor.execute("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'embeddings' AND COLUMN_NAME = 'embedding'") column_type = cursor.fetchone()[0] if column_type == 'vector': # Vector türü için doğrudan SQL kullan embedding_values = ','.join(map(str, embedding.astype(np.float32))) sql = f"INSERT INTO embeddings (data_type, original_data, embedding, original_data_type, file_path, label) VALUES (?, ?, CAST('[{embedding_values}]' AS VECTOR(512)), ?, ?, ?)" cursor.execute(sql, data_type, original_data, original_data_type, file_path, label) else: # VARBINARY kullan embedding_bytes = embedding.astype(np.float32).tobytes() cursor.execute( "INSERT INTO embeddings (data_type, original_data, embedding, original_data_type, file_path, label) VALUES (?, ?, ?, ?, ?, ?)", data_type, original_data, embedding_bytes, original_data_type, file_path, label ) except Exception as e: return jsonify({'error': f'Veritabanına ekleme hatası: {e}'}), 500 conn.commit() return jsonify({'status': 'success'}) except Exception as e: return jsonify({'error': f'Bilinmeyen hata: {e}'}), 500Burada dikkat ederseniz kullanıcıdan POST request’i ile gelecek olan verinin içeriğine bakılmakta ve yapılacak davranış bu içeriğe göre belirlenmektedir. 10 ile 21. satır aralığında gelen metinsel veriler analiz edilerek, embedding edilmektedir. 23 ile 54. satır aralığında ise görsel veriler analiz edilmekte, embedding edilebilmesi için önce RGB’ye dönüştürülmekte ve öylece embedding edilmektedir. Ayrıca fiziksel olarak hangi görselin olduğunu da takip edebilmemiz için ‘uploaded_images’ isimli klasöre görselin orjinal hali de eklenmektedir.
60 ile 64. satır aralığında embedding edilmiş olan veriler vektöre dönüştürülmekte ve 67 ile 83. satır aralığında ise elde edilen vektör veritabanına eklenmektedir.
- 7-) Vector Search Endpoint’inin Hazırlanması
# /vector_search endpoint'i @app.route('/vector_search', methods=['POST']) def vector_search(): try: data_type = request.form.get('type') if data_type == 'text': text = request.form.get('data') if not text: return jsonify({'error': 'Metin verisi eksik!'}), 400 query_embedding = text_model.encode(text) elif data_type == 'image': if 'data' not in request.files: return jsonify({'error': 'Görsel dosyası eksik!'}), 400 image_file = request.files['data'] image = Image.open(image_file.stream).convert('RGB') query_embedding = clip_model.encode(image) else: return jsonify({'error': 'type must be text or image'}), 400 # Tüm embedding'leri çek cursor.execute("SELECT id, data_type, original_data, embedding, original_data_type, file_path, label FROM embeddings") results = cursor.fetchall() if not results: return jsonify({'error': 'Hiç embedding bulunamadı.'}), 404 # Tablo türünü kontrol et cursor.execute("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'embeddings' AND COLUMN_NAME = 'embedding'") column_type = cursor.fetchone()[0] # En benzer sonucu bul best_match = None best_similarity = -1 print(f"Toplam {len(results)} embedding bulundu") print(f"Tablo türü: {column_type}") for row in results: db_id, db_data_type, db_original_data, db_embedding, db_original_data_type, db_file_path, db_label = row try: if column_type == 'vector': # Vector türü için Python'da cosine similarity kullan # Vector'ü string'den parse et vector_str = str(db_embedding) # [1.0,2.0,3.0] formatından array'e çevir vector_values = vector_str.strip('[]').split(',') db_embedding_array = np.array([float(x.strip()) for x in vector_values], dtype=np.float32) # Cosine similarity hesapla similarity = np.dot(query_embedding, db_embedding_array) / (np.linalg.norm(query_embedding) * np.linalg.norm(db_embedding_array)) print(f"ID {db_id} vector cosine similarity: {similarity}") else: # VARBINARY için cosine similarity db_embedding_array = np.frombuffer(db_embedding, dtype=np.float32) similarity = np.dot(query_embedding, db_embedding_array) / (np.linalg.norm(query_embedding) * np.linalg.norm(db_embedding_array)) print(f"ID {db_id} varbinary cosine similarity: {similarity}") # Threshold'u düşür - 0.1'den büyük olanları kabul et if similarity > 0.1 and similarity > best_similarity: best_similarity = similarity best_match = { 'id': db_id, #'data_type': db_data_type, #'original_data': db_original_data, #'original_data_type': db_original_data_type, 'file_path': db_file_path, 'label': db_label, 'similarity': float(similarity) } except Exception as e: print(f"Similarity hesaplama hatası ID {db_id}: {e}") continue print(f"En iyi similarity: {best_similarity}") print(f"En iyi match: {best_match}") if best_match: return jsonify(best_match) else: return jsonify({'error': 'Benzer sonuç bulunamadı.'}), 404 except Exception as e: return jsonify({'error': f'Hata: {e}'}), 500Yine POST edilerek gelen request üzerindeki verilere göre vector search’ün nasıl yapılacağı kararlaştırılmakta ve davranış ona göre oluşturulmaktadır. 22 ile 23. satır aralığında embeddings tablosundaki tüm veriler elde edilmekte ve 43 ile 53. satır aralığında vector türüne göre kosinüs ölçeği eşliğinde vector search gerçekleştirilmektedir. Ayrıca 56 ile 58. satır aralığında ise kolonun türü vector yerine ‘VARBINARY’ olma ihtimaline karşın, bu duruma uygun vector search işlemi gerçekleştirilmektedir.
61 ile 71. satır aralığında ise yapılan vector search neticesinde elde edilen vektörlerden benzerlik (similarity) değeri 0.1’in üstü olanlar ayrılmakta ve böylece istenen verideki hassasiyet eşiği manuel olarak tarafımızca biraz daha optimize edilerek, verinin aranana yakınlık ihtimali daha da artırılmaktadır.
- 8 -) Debug Endpoint’inin Oluşturulması
# Debug endpoint'i - embedding sayısını kontrol et @app.route('/debug', methods=['GET']) def debug(): try: cursor.execute("SELECT COUNT(*) FROM embeddings") count = cursor.fetchone()[0] cursor.execute("SELECT id, data_type, label FROM embeddings") embeddings = cursor.fetchall() return jsonify({ 'total_embeddings': count, 'embeddings': [{'id': row[0], 'type': row[1], 'label': row[2]} for row in embeddings] }) except Exception as e: return jsonify({'error': f'Debug hatası: {e}'}), 500Kaç verinin embedded edildiğine dair istatistiği hızlıca edinebilmek için bu endpoint geliştirilmiştir.
- 9-) Flask Uygulamasının Başlatılması
# Flask uygulaması başlatılıyor if __name__ == '__main__': app.run(debug=True)
İşte bu kadar 🙂 Uygulamayı artık olması gerektiği gibi geliştirmiş bulunuyoruz. Şimdi teste geçebiliriz.
- 1-) Gerekli Kütüphanelerin Import Edilmesi
-
Test Edilmesi
Hem vector embedding hem de vector search için testlerin gerçekleştirilmesi gerekmektedir.
- Uygulamanın Ayağa Kaldırılması
python app.py
- Vector Embedding Testi
Görsel veriler için;curl -X POST -F "type=image" -F "data=@görsel.path.jpg" -F "label=görsel veri ismi" http://localhost:5000/embed
Birkaç görsel veri üzerinden örnek embedding talebinin çıktısı aşağıdaki görseldeki gibi olacaktır;
Metinsel veriler için;curl -X POST -F "type=text" -F "data=metinsel veri" -F "label=metinsel veri ismi" http://localhost:5000/embed
- Vector Search Testi
Görsel veriler için;curl -X POST -F "type=image" -F "data=@görsel.path.jpg" http://localhost:5000/vector_search
Görsel veriler üzerinden örnek vector search ise aşağıdaki gibi olacaktır;
Metinsel veriler için;curl -X POST -F "type=text" -F "data=metinsel veri" http://localhost:5000/vector_search
Tüm çalışmalar neticesinde veritabanının son halide aşağıdaki gibi olacaktır;
- Debug Testi
http://localhost:5000/debug
- Uygulamanın Ayağa Kaldırılması
Ve böylece pratiksel çalışmamızı da tamamlamış ve SQL Server 2025 eşliğinde hem vector embedding’i, hem vector search’ü hem de bir yandan SQL Server 2025’in vector türünü hep birlikte deneyimlemiş olduk. Artık teoride kalan son dokunuşlara dönebilir ve azar azar içeriğimizi nihayete erdirebiliriz.
Teknik Avantajlar ve Fark Yaratan Özellikler
SQL Server’ın vektör arama yetenekleri, vektörel arama ile ilişsek veriler arasında köprü kuran güçlü bir altyapıya sahiptir. Şöyle ki; vector veri türünü kullanarak, örnekte de deneyimlediğimiz gibi embedding edilmiş verilerle yapılandırılmış verileri aynı tabloda saklama olanağı söz konusudur. Böylece tek bir veritabanı ile AI destekli uygulama geliştirme biz yazılımcılar açısından oldukça kolaylaşabilmektedir.
Ayrıca bu teknolojinin sunduğu avantajlar, özellikle veri mahremiyetine duyarlı projeler için dikkat çekicidir. Ek bir araca gerek kalmaksızın yapay zekâ yeteneklerini doğrudan T-SQL komutları ile yönetebilir, geleneksel SQL uzmanlığına gerek olmaksızın semantic search yapabilir ve tüm süreçler tamamen on-prem ortamında gerçekleşebilir.
Nihai olarak;
SQL Server 2025’in vektör arama özelliği, yapay zekâ çağının ihtiyaç duyduğu semantik düzeyde sorgulama yeteneklerini kurumsal veritabanlarına entegre ederek devrimsel bir sıçrama sunmaktadır. Bu özellik, yalnızca teknolojik olarak değil, aynı zamanda veriye erişim, yorumlama ve karar verme biçimimiz üzerinde de köklü değişiklikler yaratma potansiyeline sahiptir.
Farkındaysanız, geleceği inşa eden sistemler artık sadece veriye değil, verinin anlamına da erişmek mecburiyetindedir. İşte SQL Server, tam da bu noktada 2025 ile varlık göstermektedir.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Not : Örnek çalışmaya aşağıdaki GitHub adresinden erişebilirsiniz.
https://github.com/gncyyldz/SQL_Server_2025_Vector_Embedding_And_Vector_Search


Gençay hocam selamlar. Buradaki çıktılarda yer alan similarity değeri, “embeddings” tablosuna daha önce kaydedilmiş olan diğer veriler ile olan benzerlik derecesini ifade ediyor diye düşünüyorum doğru mu?
Eğer böyle ise, burada bir sorun var gibi görünüyor. Birbirine çok benzeyen görseller ile çok alakasız farklı bir görsel üzerinde testlerimi gerçekleştirdiğimde similarity değeri için benzer sonuçlar aldım.
Olayı ben de çok yanlış anlamış olabilirim. Bu konu da cevap verirseniz memnun olurum. Emeğinize sağlık. Teşekkür ederim.
İnceleyip, ilk fırsatta döneceğim. Teşekkürler.
Harika bir yazı. Kalemine sağlık. Çok teşekkürler
🌹