다음을 통해 공유


벡터 데이터 형식

적용 대상: Microsoft Fabric의 SQL Server 2025(17.x) Azure SQL DatabaseAzure SQL Managed InstanceSQL 데이터베이스

벡터 데이터 형식은 유사성 검색 및 기계 학습 애플리케이션과 같은 작업에 최적화된 벡터 데이터를 저장하도록 설계되었습니다. 벡터는 최적화된 이진 형식으로 저장되지만 편의를 위해 JSON 배열로 노출됩니다. 벡터의 각 요소는 단정밀도(4 바이트) 부동 소수점 값으로 저장됩니다.

개발자에게 친숙한 환경을 제공하기 위해 벡터 데이터 형식이 만들어지고 JSON 배열로 표시됩니다. 예를 들어 3차원의 벡터를 .로 '[0.1, 2, 30]'나타낼 수 있습니다. varchar, nvarcharjson 형식을 사용하여 벡터 형식에서 암시적 및 명시적 변환을 수행할 수 있습니다.

Note

SQL Server 2025(17.x)는 반정밀도(float16) 벡터를 지원합니다. 자세한 내용은 벡터 데이터 형식의 반정밀도 부동 소수 자릿수 지원을 참조하세요.

float16 벡터는 현재 미리 보기로 제공됩니다. 테스트하려면 데이터베이스 범위 구성 옵션을 사용하도록 설정합니다 PREVIEW_FEATURES . 자세한 내용은 PREVIEW_FEATURES = { ON | OFF }를 검토하세요.

ALTER DATABASE SCOPED CONFIGURATION
SET PREVIEW_FEATURES = ON;
GO

제한 사항은 제한 사항알려진 문제를 검토하세요.

Note

벡터 기능은 [Always-up-to-date](/azure/azure-sql/managed-instance/ update-policy#always-up-to-date-update-policy) 정책으로 구성된 Azure SQL Managed Instance에서 사용할 수 있습니다.

벡터 데이터 작업에 대한 자세한 내용은 다음을 참조하세요.

샘플 구문

벡터 형식의 사용 구문은 테이블의 다른 모든 SQL Server 데이터 형식과 유사합니다.

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

기본적으로 기본 형식은 .입니다 float32. 반정밀도를 사용하려면 명시적으로 지정 float16 해야 합니다.

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

Dimensions

벡터에는 하나 이상의 차원이 있어야 합니다. 지원되는 최대 차원 수는 1998년입니다.

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
(
    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;
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

기능 가용성

벡터 형식은 모든 데이터베이스 호환성 수준에서 사용할 수 있습니다.

벡터에 대한 float16 지원은 현재 PREVIEW_FEATURES 구성에서 제한됩니다. VECTOR(..., float16)을 사용하기 전에 명시적으로 활성화해야 합니다.

ALTER DATABASE SCOPED CONFIGURATION
SET PREVIEW_FEATURES = ON;
GO

Conversions

  • 벡터 형식은 sql_variant 형식과 함께 사용할 수 없으며, sql_variant 변수나 열에 할당할 수 없습니다. 이 제한은 varchar(max), varbinary(max), nvarchar(max), xml, json 및 CLR 기반 데이터 형식과 유사합니다.

Compatibility

TDS 프로토콜의 향상된 기능

SQL Server는 최적화된 이진 형식으로 벡터를 저장하지만 편의를 위해 JSON 배열로 노출합니다.

지원되는 드라이버는 TDS 프로토콜에 향상된 기능을 사용하여 벡터 데이터를 이진 형식으로 보다 효율적으로 전송하고 애플리케이션에 네이티브 벡터 형식으로 제공합니다. 이 방법은 페이로드 크기를 줄이고, JSON 구문 분석의 오버헤드를 제거하고, 전체 부동 소수점 정밀도를 유지합니다. 따라서 AI 및 기계 학습 시나리오에서 고차원 벡터로 작업할 때 성능과 정확도가 모두 향상됩니다.

Note

float16 벡터는 현재 TDS를 통해 varchar(max) (JSON 배열)로 전송됩니다. ODBC, JDBC, .NET 등의 드라이버에서는 float16를 위한 이진 전송 지원이 아직 제공되지 않습니다.

네이티브 드라이버 지원

TDS 버전 7.4 이상 및 업데이트된 드라이버를 사용하는 애플리케이션은 기본적으로 벡터 데이터를 읽고, 쓰고, 스트리밍하고, 대량 복사할 수 있습니다.

이러한 기능에는 다음 드라이버의 버전이 필요합니다. 올바른 버전을 사용하여 네이티브 벡터 지원을 사용하도록 설정했는지 확인합니다.

  • Microsoft.Data.SqlClient: 버전 6.1.0에서는 SqlVector를 확장하는 System.Data.SqlDbTypes 유형이 도입되었습니다.
  • Microsoft JDBC Driver for SQL Server: 버전 13.1.0 미리 보기에서는 microsoft.sql.Types.VECTOR 형식과 microsoft.sql.Vector 클래스가 새롭게 도입되었습니다.

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 드라이버를 사용하지 않는 경우에도 클래스를 사용하여 JsonSerializer JSON 문자열로 직렬화하고 역직렬화하여 C#에서 벡터 데이터를 사용할 수 있습니다. 이렇게 하면 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 제약 조건을 제외하고, 열 수준 제약 조건은 지원되지 않습니다.

    • DEFAULTCHECK 제약 조건은 벡터 열에 대해 지원되지 않습니다.

    • 키 제약 조건(예: PRIMARY KEY 또는 FOREIGN KEY)은 벡터 열에 대해 지원되지 않습니다. 같음, 고유성, 벡터 열을 키로 사용하는 조인 및 정렬 순서는 벡터 데이터 형식에 적용되지 않습니다.

    • 벡터의 고유성에 대한 개념은 없으므로 고유한 제약 조건을 적용할 수 없습니다.

    • 벡터 내의 값 범위를 확인하는 것도 적용되지 않습니다.

  • 벡터는 비교, 더하기, 빼기, 곱하기, 나누기, 연결 또는 기타 수학, 논리 및 복합 할당 연산자를 지원하지 않습니다.

  • 메모리 최적화 테이블에서는 벡터 열을 사용할 수 없습니다.

Indexes

  • B-트리 인덱스 또는 columnstore 인덱스는 벡터 열에서 허용되지 않습니다. 그러나 벡터 열은 인덱스 정의에 포함된 열로 지정할 수 있습니다.

테이블 스키마 메타데이터

  • sp_describe_first_result_set 시스템 저장 프로시저가 벡터 데이터 형식을 올바르게 반환하지 않습니다. 따라서 많은 데이터 액세스 클라이언트와 드라이버는 varchar 또는 nvarchar 데이터 형식을 볼 수 있습니다.

원장 테이블

  • 데이터베이스에 sp_verify_database_ledger 열이 있는 테이블이 포함된 경우 저장 프로시저 에서 오류가 발생합니다.

사용자 정의 형식

  • 별칭 형식을 CREATE TYPE를 사용하여 벡터 형식에 대해서 만드는 것은 허용되지 않습니다. 이는 xmljson 데이터 형식의 동작과 유사합니다.

항상 암호화됨

  • 벡터 유형은 Always Encrypted 기능에서 지원되지 않습니다.

알려진 문제

  • 데이터 마스킹은 현재 Azure Portal에서 벡터 데이터를 varbinary 데이터 형식으로 표시합니다.