벡터 데이터 형식

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

벡터 데이터 타입은 유사성 탐색 및 머신러닝 애플리케이션과 같은 연산에 최적화된 벡터 데이터를 저장합니다. 벡터는 최적화된 이진 형식으로 저장되지만 편의를 위해 JSON 배열로 노출됩니다. 벡터의 각 요소는 단정밀도(4 바이트) 부동 소수점 값으로 저장됩니다.

개발자에게 친숙한 환경을 제공하기 위해 벡터 데이터 형식이 만들어지고 JSON 배열로 표시됩니다. 예를 들어 3차원의 벡터를 .로 '[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 Managed Instance에서 사용할 수 있습니다.

반정밀도 float16 벡터

  • 반정밀도(float16) 벡터는 일반적으로 Azure SQL Database, Azure SQL Managed Instance, Microsoft Fabric의 SQL 데이터베이스에서 제공됩니다. 미리보기 설정은 필요하지 않습니다.

  • SQL Server 2025 (17.x)에서는 반정밀도(float16) 벡터가 미리보기로 제공됩니다. SQL Server 2025에서 float16을 사용하려면 데이터베이스 범위 설정 옵션을 활성화 PREVIEW_FEATURES 해야 합니다. 자세한 내용은 SQL Server 2025에서 미리보기 기능 활성화를 참조하세요.

반정밀도 벡터에 대한 자세한 내용은 벡터 데이터 타입의 반정밀도 float 지원을 참조하세요.

SQL Server 2025에서 미리보기 기능을 활성화하기

SQL Server 2025의 일부 미리보기 기능을 위해서는 데이터베이스 범위별 설정 옵션을 활성화 PREVIEW_FEATURES 해야 합니다.

ALTER DATABASE SCOPED CONFIGURATION
SET PREVIEW_FEATURES = ON;
GO

자세한 내용은 PREVIEW_FEATURES를 참조하세요.

Examples

A. 열 정의

문장 내 CREATE TABLE 열(column definition)에서 벡터 타입을 사용하세요. 다음은 그 예입니다.

다음 예제에서는 벡터 열이 있는 테이블을 만들고 데이터를 삽입합니다.

테이블에서 벡터 열을 정의하려면 기본 기본 타입인 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 미리 보기에서는 microsoft.sql.Types.VECTOR 형식과 microsoft.sql.Vector 클래스가 새롭게 도입되었습니다.

Note

float16 벡터에 대한 네이티브 바이너리 전송은 SQL Server용 JDBC 드라이버 13.4와 SQL Server용 Microsoft ODBC 드라이버 18.7.1 Microsoft에서 지원됩니다. 이 드라이버들은 반정밀도 벡터 값을 네이티브 와이어 포맷으로 직렬화하고 역직렬화하여 JSON 표현에 비해 네트워크 페이로드를 줄입니다. 네이티브 float16 전송용으로 이 드라이버 버전 또는 그 이후를 사용하세요. 네이티브 float16 전송을 지원하지 않는 드라이버도 JSON 배열로 varchar(max) 표현된 벡터로 계속 작업할 수 있습니다.

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 제약 조건을 제외하고는 지원되지 않습니다.

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

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

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

    • 벡터 내 값의 범위 검사는 적용되지 않습니다.

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

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

Indexes

  • 벡터 컬럼에는 B-트리 인덱스나 컬럼스토어 인덱스를 사용할 수 없습니다. 하지만 인덱스 정의에서 vector 열을 포함 열로 지정할 수 있습니다.
  • 벡터 인덱스는 최근접 이웃 탐색 성능을 향상시키기 위해 벡터 열에 근사적인 인덱스를 생성합니다. 벡터 인덱싱과 벡터 검색이 어떻게 작동하는지, 그리고 정확 검색과 근사 검색의 차이에 대해 더 알고 싶다면 SQL 데이터베이스 엔진의 벡터 검색 및 벡터 인덱스를 참조하세요.

테이블 스키마 메타데이터

  • sp_describe_first_result_set 시스템 저장 프로시저가 벡터 데이터 타입을 올바르게 반환하지 않습니다. 그 결과, 많은 데이터 접근 클라이언트와 드라이버가 varchar 또는 nvarchar 데이터 타입을 인식하게 됩니다.

원장 테이블

  • 저장 프로시저 sp_verify_database_ledger 가 벡 터 열을 가진 테이블을 포함하면 오류를 생성합니다.

사용자 정의 형식

  • CREATE TYPE 형식에 대해 을(를) 사용하여 별칭 형식을 만들 수 없습니다. 이 제한은 xml 과 json 데이터 타입의 동작과 유사합니다.

항상 암호화됨

  • 벡터 타입은 항상 암호화된 기능에서는 지원되지 않습니다.

알려진 문제

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