向量資料類型

適用於: SQL Server 2025 (17.x) Azure SQL DatabaseAzure SQL 託管執行個體Microsoft Fabric 中的 SQL 資料庫

向量資料型別儲存針對相似度搜尋及機器學習應用優化的向量資料。 向量會以優化的二進位格式儲存,但為了方便起見,會公開為 JSON 陣列。 向量的每個元素都會儲存為單精度 (4 位元組) 浮點值。

為了為開發人員提供熟悉的體驗,系統會建立 向量 數據類型並顯示為 JSON 陣列。 例如,具有三個維度的向量可以表示為 '[0.1, 2, 30]'。 你可以隱式或明確地在 向量 型別與 varchar、 nvarchar 和 json 型別之間轉換。

如需使用向量數據的詳細資訊,請參閱:

範例語法

向量類型的使用語法類似於數據表中所有其他 SQL Server 數據類型。

column_name VECTOR ( { <dimensions> } ) [ NOT NULL | NULL ]

預設的基礎型態是 float32。 若要使用 半精度,請明確指定 float16 。

column_name VECTOR ( <dimensions> [ , <base_type> ] ) [ NOT NULL | NULL ]

Dimensions

向量必須至少有一個維度。 最大維度數取決於向量基底類型:

  • float32 支援最高 1,998 維度。
  • float16 支援最高 3,996 維度。

功能可用性

向量資料型別在所有資料庫相容性層級下皆可取得。 如果你沒指定基底類型,向量會用 float32。

向量功能可在以 Always-up-to-date 原則 設定的 Azure SQL 受控實例中使用。

半精度 float16 向量

  • 半精度(float16)向量通常可在 Azure SQL Database、Azure SQL 受控執行個體 以及 Microsoft Fabric 的 SQL 資料庫中取得。 不需要預覽設定。

  • 在 SQL Server 2025(17.x)中,預覽版中提供半精度(float16)向量。 要在 SQL Server 2025 中使用 float16,必須啟用PREVIEW_FEATURES資料庫範圍設定選項。 欲了解更多資訊,請參閱啟用 SQL Server 2025 的預覽功能。

欲了解更多關於半精度向量的資訊,請參閱 向量資料型態中的半精度浮點數點支援。

啟用 SQL Server 2025 的預覽功能

在 SQL Server 2025 中,某些預覽功能必須啟用PREVIEW_FEATURES資料庫範圍設定選項。

ALTER DATABASE SCOPED CONFIGURATION
SET PREVIEW_FEATURES = ON;
GO

欲了解更多資訊,請參見 PREVIEW_FEATURES。

Examples

A. 欄位定義

在陳述句中的CREATE TABLE欄位定義中使用向量型態。 例如:

下列範例會建立具有向量數據行的數據表,並將數據插入其中。

在表格中定義 向量 欄位,使用預設的基礎類型 float32 或 float16 進行半精度儲存。

CREATE TABLE dbo.vectors
(
    id INT PRIMARY KEY,
    v VECTOR(3) NOT NULL -- Uses default base type (**float32**)
);

CREATE TABLE dbo.vectors_fp16
(
    id INT PRIMARY KEY,
    v VECTOR(3, float16) -- Uses float16 for reduced storage and precision
);

INSERT INTO dbo.vectors (id, v)
VALUES (1, '[0.1, 2, 30]'),
       (2, '[-100.2, 0.123, 9.876]'),
       (3, JSON_ARRAY(1.0, 2.0, 3.0)); -- Using JSON_ARRAY to create a vector

SELECT *
FROM dbo.vectors;

B. 變數中的使用方式

以下範例使用新的 向量 資料型態宣告向量,並利用函 VECTOR_DISTANCE 數計算距離。

使用帶有變數的 向量 類型:

DECLARE @v AS VECTOR(3) = '[0.1, 2, 30]';
SELECT @v;
GO
DECLARE @v AS VECTOR(3, float16) = '[0.1, 2, 30]';
SELECT @v;

C. 預存程式或函式中的使用方式

你可以在儲存程序或函式中使用 向量 資料型態作為參數。 例如:

CREATE PROCEDURE dbo.SampleStoredProcedure
@V VECTOR(3),
@V2 VECTOR(3) OUTPUT
AS
BEGIN
    SELECT @V;
    SET @V2 = @V;
END

Conversions

  • 你不能用 向量 型別搭配 sql_variant 型別,或把它指派到 sql_variant 變數或欄位。 這項限制類似於 varchar(max)、 varbinary(max)、 nvarchar(max)、 xml、 json 和 CLR 型數據類型。

Compatibility

TDS 協定的改進

SQL Server 會以優化的二進位格式儲存向量,但為了方便起見,將它們公開為 JSON 陣列。

支援的 驅動程式會使用 TDS 通訊協定的增強功能,以二進位格式更有效率地傳輸向量數據,並將其呈現給應用程式作為原生向量類型。 此方法可減少承載大小、消除 JSON 剖析的額外負荷,並保留完整的浮點精確度。 因此,在 AI 和機器學習案例中使用高維度向量時,其可改善效能和精確度。

原生驅動程序支援

使用 TDS 7.4 版或更高版本和 更新驅動程式的應用程式,可以原生讀取、寫入、串流和大量複製向量數據。

這些功能需要以下驅動程式的版本。 請確定您使用正確的版本來啟用原生向量支援。

  • Microsoft.Data.SqlClient: 6.1.0 版引進類型 SqlVector ,並擴充 System.Data.SqlDbTypes。
  • Microsoft JDBC Driver for SQL Server: 13.1.0 版 Preview 引進 microsoft.sql.Types.VECTOR 類型和 microsoft.sql.Vector 類別。

Note

Microsoft JDBC Driver 13.4 for SQL Server 及 Microsoft ODBC Driver 18.7.1 for SQL Server 支援原生二進位傳輸 float16 向量。 這些驅動程式使用原生線路格式序列化與反序列化半精度向量值,降低網路有效負載,相較於 JSON 表示方式。 使用這些驅動版本或更新版本來進行原生 float16 傳輸。 不支援原生 float16 傳輸的驅動程式仍可繼續使用以 varchar(max) JSON 陣列表示的向量。

Note

對於不支援更新 TDS 通訊協定的用戶端,SQL Server 會繼續將向量數據公開為 varchar(max) 類型,以確保回溯相容性。 用戶端應用程式可以使用向量數據,就像是 JSON 陣列一樣。 SQL Database 引擎會自動將向量從 JSON 陣列來回轉換,使用戶端的新類型變得透明。 因此,驅動程式和所有語言都會自動與新類型相容。

您可以立即開始使用新的 向量 類型。 下列範例顯示不同的語言和驅動程式組態。

Important

原生向量支援需要 Microsoft.Data.SqlClient 6.1.0 或更新版本。

using Microsoft.Data;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlTypes;

namespace VectorSampleApp
{
    class Program
    {
        // Set your environment variable or fallback to local server
        private static readonly string connectionString =
            Environment.GetEnvironmentVariable("CONNECTION_STR")
            ?? "Server=tcp:localhost,1433;Database=Demo2;Integrated Security=True;TrustServerCertificate=True";

        private const int VectorDimensions = 3;
        private const string TableName = "dbo.Vectors";

        static void Main()
        {
            using var connection = new SqlConnection(connectionString);
            connection.Open();
            SetupTables(connection, TableName, VectorDimensions);
            InsertVectorData(connection, TableName);
            ReadVectorData(connection, TableName);
        }

        private static void SetupTables(SqlConnection connection, string tableName, int vectorDimensionCount)
        {
            using var command = connection.CreateCommand();

            command.CommandText = $@"
                IF OBJECT_ID('{tableName}', 'U') IS NOT NULL DROP TABLE {tableName};
                IF OBJECT_ID('{tableName}Copy', 'U') IS NOT NULL DROP TABLE {tableName}Copy;";
            command.ExecuteNonQuery();

            command.CommandText = $@"
                CREATE TABLE {tableName} (
                    Id INT IDENTITY(1,1) PRIMARY KEY,
                    VectorData VECTOR({vectorDimensionCount})
                );

                CREATE TABLE {tableName}Copy (
                    Id INT IDENTITY(1,1) PRIMARY KEY,
                    VectorData VECTOR({vectorDimensionCount})
                );";
            command.ExecuteNonQuery();
        }

        private static void InsertVectorData(SqlConnection connection, string tableName)
        {
            using var command = new SqlCommand($"INSERT INTO {tableName} (VectorData) VALUES (@VectorData)", connection);
            var param = command.Parameters.Add("@VectorData", SqlDbTypeExtensions.Vector);

            // Insert null using DBNull.Value
            param.Value = DBNull.Value;
            command.ExecuteNonQuery();

            // Insert non-null vector
            param.Value = new SqlVector<float>(new float[] { 3.14159f, 1.61803f, 1.41421f });
            command.ExecuteNonQuery();

            // Insert typed null vector
            param.Value = SqlVector<float>.CreateNull(VectorDimensions);
            command.ExecuteNonQuery();

            // Prepare once and reuse for loop
            command.Prepare();
            for (int i = 0; i < 10; i++)
            {
                param.Value = new SqlVector<float>(new float[]
                {
                    i + 0.1f,
                    i + 0.2f,
                    i + 0.3f
                });
                command.ExecuteNonQuery();
            }
        }

        private static void ReadVectorData(SqlConnection connection, string tableName)
        {
            using var command = new SqlCommand($"SELECT VectorData FROM {tableName}", connection);
            using var reader = command.ExecuteReader();

            while (reader.Read())
            {
                var sqlVector = reader.GetSqlVector<float>(0);

                Console.WriteLine($"Type: {sqlVector.GetType()}, IsNull: {sqlVector.IsNull}, Length: {sqlVector.Length}");

                if (!sqlVector.IsNull)
                {
                    float[] values = sqlVector.Memory.ToArray();
                    Console.WriteLine("VectorData: " + string.Join(", ", values));
                }
                else
                {
                    Console.WriteLine("VectorData: NULL");
                }
            }
        }
    }
}

Note

如果你不用最新的 .NET 驅動程式,也可以用 C# 把向量資料序列化並反序列化成 JSON 字串,並用類別JsonSerializer來處理。 此方法可確保與 SQL Server 為較舊的用戶端提供的向量 varchar(max) 表示法相容。

using Microsoft.Data.SqlClient;
using Dapper;
using DotNetEnv;
using System.Text.Json;

namespace DotNetSqlClient;

class Program
{
    static void Main(string[] args)
    {
        Env.Load();

        var v1 = new float[] { 1.0f, 2.0f, 3.0f };

        using var conn = new SqlConnection(Env.GetString("MSSQL"));
        conn.Execute("INSERT INTO dbo.vectors VALUES(100, @v)", param: new {@v = JsonSerializer.Serialize(v1)});

        var r = conn.ExecuteScalar<string>("SELECT v FROM dbo.vectors") ?? "[]";
        var v2 = JsonSerializer.Deserialize<float[]>(r);
        Console.WriteLine(JsonSerializer.Serialize(v2));
    }
}

Tools

下列工具支援 向量 資料類型:

Limitations

向量類型有下列限制:

Tables

  • 不支援欄位層級的條件約束,除了 NULL 和 NOT NULL 條件約束之外。

    • DEFAULT和CHECK限制不支援向量欄。

    • PRIMARY KEY 或 FOREIGN KEY 等鍵約束不支援 向量 資料行。 相等、唯一性、使用向量數據行做為索引鍵的聯結,且排序順序不適用於 向量 數據類型。

    • 向量沒有唯一性的概念,因此不適用唯一條件約束。

    • 檢查向量內的值範圍並不適用。

  • 向量不支持比較、加法、減法、乘法、除法、串連或任何其他數學、邏輯和複合指派運算符。

  • 你不能在記憶體優化的表格中使用 向量 欄位。

Indexes

  • 你不能在 向量 欄位上使用 B 樹索引或欄位儲存索引。 不過,你可以在索引定義中將 向量 欄位作為包含欄位。
  • 向量索引會在 向量欄位上建立近似索引,以提升最近鄰搜尋的效能。 欲了解更多向量索引與向量搜尋的運作方式,以及精確搜尋與近似搜尋的差異,請參閱 SQL 資料庫引擎 中的向量搜尋與向量索引。

數據表架構元數據

  • sp_describe_first_result_set系統的儲存程序無法正確回傳向量資料型別。 因此,許多資料存取用戶端與驅動程式會看到 varchar 或 nvarchar 資料型態。

分類帳表格

  • 如果資料庫包含具有 sp_verify_database_ledger 欄位的資料表,儲存程序 就會產生錯誤。

用戶定義型別

  • 你無法使用 CREATE TYPE 為 vector 類型建立別名類型。 此限制與 XML 與 JSON 資料型態的行為相似。

永遠加密

  • 向量類型在「永遠加密」功能中不被支援。

已知問題

  • 數據遮罩目前會在 Azure 入口網站中將 向量 數據顯示為 varbinary 數據類型。