矢量数据类型(预览版)
适用于:Azure SQL 数据库
矢量数据类型旨在存储针对相似性搜索和机器学习应用等操作进行了优化的矢量数据。 矢量以优化的二进制格式存储,但为了方便起见,以 JSON 数组的形式公开。 矢量的每个元素都存储为单精度(4 字节)浮点值。
注意
该数据类型为预览版,可能会发生变化。 请务必阅读联机服务的服务级别协议 (SLA) 文档中的预览版使用条款。 有关当前预览版的限制,请参阅限制和已知问题。
若要详细了解如何在 SQL 数据库中使用矢量数据,请参阅:
示例语法
矢量类型的使用语法与表中的所有其他 SQL Server 数据类型类似。
column_name VECTOR( {<dimensions>} ) [NOT NULL | NULL]
维度
矢量必须至少有一个维度。 支持的最大维度数为 1998。
示例
A. 列定义
矢量类型可用于 CREATE TABLE
语句中包含的列定义,例如:
以下示例创建一个包含矢量列的表并将数据插入其中。
CREATE TABLE dbo.vectors
(
id INT PRIMARY KEY,
v VECTOR(3) NOT NULL
);
INSERT INTO dbo.vectors (id, v) VALUES
(1, '[0.1, 2, 30]'),
(2, '[-100.2, 0.123, 9.876]');
SELECT * FROM dbo.vectors;
B. 在变量中的用法
以下示例使用新的矢量数据类型来声明矢量,并使用 VECTOR_DISTANCE
函数来计算距离。
矢量类型可与变量配合使用:
DECLARE @v VECTOR(3) = '[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
功能可用性
Azure SQL 数据库中目前以预览版形式提供对矢量的原生支持。
新的矢量类型在所有数据库兼容性级别下可用。
兼容性
为了允许所有客户端能够对矢量数据进行操作,矢量被公开为 varchar(max) 类型。 客户端应用程序可以像处理 JSON 数组一样处理矢量数据。 引擎会自动将矢量转换为 JSON 数组,以及将 JSON 数组转换为矢量,使得新类型对于客户端来说是透明的。 由于采用这种方法,所有驱动程序和所有语言都自动与新类型兼容。
你可以立即开始使用新的矢量类型。 下面是一些示例:
使用 C#,可以通过 JsonSerializer
类将矢量序列化和反序列化为字符串,以及将字符串序列化和反序列化为矢量。
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));
}
}
限制
正在进行的预览设有以下限制:
表
- 不支持列级约束,但
NULL
/NOT NULL
约束除外。- 矢量列不支持
DEFAULT
和CHECK
约束。 - 矢量列不支持键约束,例如
PRIMARY KEY
或FOREIGN KEY
。 相等性、唯一性、使用矢量列作为键的联接以及排序顺序不适用于矢量数据类型。 - 矢量没有唯一性的概念,因此唯一性约束不适用。
- 在矢量内检查值的范围的操作也不适用。
- 矢量列不支持
- 矢量不支持比较、加法、减法、乘法、除法、串联或任何其他数学、逻辑和复合赋值运算符。
- 矢量列不能在内存优化表中使用。
- 不允许使用
ALTER TABLE ... ALTER COLUMN
将矢量列更改为其他数据类型。
表架构元数据
sp_describe_first_result_set 系统存储过程不会正确返回矢量数据类型。 因此,许多数据访问客户端和驱动程序都会看到 varchar 或 nvarchar 数据类型。
INFORMATION_SCHEMA.COLUMNS
会报告使用矢量类型作为 varbinary 的列。 若要获取正确的数据类型,解决方法是使用sys.columns
系统视图。sys.columns
返回矢量的长度(以字节为单位)。 若要获取维度数,请使用以下公式:dimensions = (length - 8) / 4
其中
length
是max_length
返回的值。 例如,如果看到 20 个字节的max_length
,则维度数为 (20 - 8) / 4 = 3。
转换
可以使用
CAST
或CONVERT
从矢量类型隐式或显式转换为 varchar 和 nvarchar 类型。同样,只有 varchar 和 nvarchar 可以隐式或显式转换为矢量类型。矢量类型不能与 sql_variant 类型配合使用,也不能分配给 sql_variant 变量或列。 此限制类似于 varchar(max)、varbinary(max)、nvarchar(max)、xml、json 以及基于 CLR 的数据类型。
尚不支持与 JSON 数据类型之间的相互转换。 解决方法是先与 nvarchar(max) 进行相互转换,然后再与 JSON 进行相互转换。 例如,将矢量转换为 JSON 类型:
DECLARE @v VECTOR(3) = '[1.0, -0.2, 30]'; SELECT CAST(CAST(@v AS NVARCHAR(MAX)) AS JSON) AS j;
从 JSON 类型转换为矢量:
DECLARE @j JSON = JSON_ARRAY(1.0, -0.2, 30) SELECT CAST(CAST(@j AS NVARCHAR(MAX)) AS VECTOR(3)) AS v;
索引
- 矢量列上不允许使用 B 树索引或列存储索引。 不过,可以将矢量列指定为索引定义中包含的列。
用户定义类型
- 不允许使用
CREATE TYPE
为矢量类型创建别名类型,这与 xml 和 json 数据类型的行为类似。
账本表
- 如果数据库包含一个带有矢量列的表,则存储过程
sp_verify_database_ledger
会生成错误。
已知问题
在正在进行的预览中,存在以下已知问题:
- SQL Server Management Studio、Azure Data Studio 或 VS Code 的 mssql 扩展等工具目前可能无法生成特定表(其中包含一个使用矢量数据类型的列)的脚本。
- SQL Server Management Studio、Azure Data Studio 或 VS Code 的 mssql 扩展等工具目前可能会针对某个使用矢量类型的列报告 varbinary 数据类型,而不是矢量数据类型。
- 如果表包含矢量类型,则 BCP 和
BULK INSERT
目前无法工作。 - 如果存在使用矢量类型的表,则目前无法通过 DacFx 进行导入和导出。
- 列加密目前不支持矢量类型。
- Always Encrypted 目前不支持矢量类型。
- 数据掩码目前在门户中将矢量数据显示为 varbinary 数据类型。
这些问题将在未来的更新中解决,文档也将相应地进行更新。