从二维坐标到 DM9 向量检索:余弦相似度的“降维”解读
从二维坐标到 DM9 向量检索:余弦相似度的“降维”解读
1 什么是向量数据?
随着AI技术的发展,向量数据库逐步进入大众的视野,当打开手机相册,AI能瞬间从几千张照片里“认出”你的猫;
当你在购物App上浏览,系统总能源源不断地推荐你喜欢的同款商品。这背后支撑AI做出“理解”和“判断”的,正是向量数据。简单来说,向量数据就是把我们世界里的文本、图片、音视频,转化成计算机能“读懂”的一串数字(数组)。它不再是简单的“是”或“否”,而是将复杂的高维信息,映射到一个可以计算的数学空间里。
2 高中数学之余弦相似度求解
说到向量,在高中数学中有一道非常经典的向量余弦求解题,相信大家都不陌生。我们先进行回顾:
向量求解:已知二维平面上 7 个点的坐标如下:

问题:求出与点 A 方向最相似的点(即与向量 OA 方向夹角最小的点,O 为原点)。
解:把每个点 P(x, y) 视为从原点 O(0,0) 出发的向量 v = (x, y)。
“方向相似”指的是两个向量指向的方向一致程度,用夹角余弦值衡量。我们计算点 A 的向量与其他所有点的向量的余弦相似度,找出最大值就是与点A方向最相似的点。
数学公式:
对于两个向量 u = (x₁, y₁) 和 v = (x₂, y₂),它们的夹角为 θ,则:
根据公式,我们把每个点的坐标代入进去,得到各个点和点A的余弦相似度。
汇总对比表

根据上述计算,我们就可以解出这到题目,与点 A 方向最相似的点是 B(50, 10),余弦相似度为1,两个点的向量方向一致,夹角为0。
可以看到,解题方式并不困难,但随着点数据的增多,计算量会随之增大。
3 数据库应用之传统方式解题
我们将题目和实际进行结合,这些点作为数据,需要做的第一步就是使用数据库将数据进行存储,再进行计算。
使用points_raw_2d来存储点数据,x和y分别存储每个点的坐标。
CREATE TABLE points_raw_2d (
id INT PRIMARY KEY,
name VARCHAR(50),
x DOUBLE,
y DOUBLE
);
INSERT INTO points_raw_2d VALUES
(1, 'A', 5, 1),
(2, 'B', 50, 10),
(3, 'C', 1, 5),
(4, 'D', 5, -1),
(5, 'E', -5, 1),
(6, 'F', -1, -5),
(7, 'G', 0, 0);
commit;
我们将点数据存储到表中以后,就可以使用sql进行求解。
需要注意的是,在求解时,如果出现了原点(如题目中的G),需要避免除0错误。
SELECT
id,
name,
x,
y,
-- 分子:点积
(5*x + 1*y) /
-- 分母:模长相乘
(SQRT(5*5 + 1*1) * SQRT(x*x + y*y)) AS cosine_sim
FROM points_raw_2d
ORDER BY cosine_sim DESC;
注:sqrt函数:求平方根。
将原点的情况,使用case when单独处理,调整使用以下SQL可以直接求解出题目答案。
SELECT
id,
name,
x,
y,
CASE
WHEN x = 0 AND y = 0 THEN NULL
ELSE (5*x + 1*y) /
(SQRT(5*5 + 1*1) * SQRT(x*x + y*y))
END AS cosine_sim
FROM points_raw_2d;
将数据存储到表,再使用sql计算,效率已经有了量级的提升。但弊端也是较为明显,sql不够灵活,如果题目出现变式,想要求解与B点方向最相似的点,整个sql的计算部分需要重新调整(需要代入B点的模长),当维度较大时,对sql的改动较大。
4 DM9向量求解作答
DM9支持向量求解该题目,带来全新的体验。
使用向量的方式来创建表,存储坐标信息。Pos(坐标列)指定为VECTOR向量类型,VECTOR(2)声明向量的维度为2,int8指定向量格式为8 bit的整数。
达梦中向量数据格式可以声明为INT8、FLOAT32、FLOAT64和BINARY。不指定向量格式默认为FLOAT32,此处我们的7个点坐标均为整数,可以选择INT8格式。
----向量方式建表
CREATE TABLE points_vec_2d (
id INT PRIMARY KEY,
name VARCHAR(50),
pos VECTOR(2,int8)
);
INSERT INTO points_vec_2d VALUES
(1, 'A', '[5, 1]'),
(2, 'B', '[50, 10]'),
(3, 'C', '[1, 5]'),
(4, 'D', '[5, -1]'),
(5, 'E', '[-5, 1]'),
(6, 'F', '[-1, -5]'),
(7, 'G', '[0, 0]');
select id,name ,to_char(pos) from points_vec_2d;
在此基础上,DM9还支持了向量函数,包括距离计算函数、 向量功能函数、聚集函数、支持向量类型的JSON函数等。
函数COSINE_DISTANCE可以直接计数出两个向量之间的余弦距离。因此我们的sql就会变得更加简洁。
TO_VECTOR(‘[5,1]’,2,INT8,DENSE)将默认的FLOAT向量格式转换为INT8类型。
SELECT
id,
name,
pos,
COSINE_DISTANCE(pos,TO_VECTOR('[5,1]',2,INT8,DENSE)) AS cosine_dist,
1 - COSINE_DISTANCE(pos, TO_VECTOR('[5,1]',2,INT8,DENSE)) AS cosine_sim -- 转成相似度
FROM points_vec_2d
向量求解的方式不仅简化了sql,对于求解不同坐标的相似度问题上,更加灵活,只需要传入坐标系中的任何一个点的坐标,就可以在已有表数据中便捷地查找出和该点相似度最高的点。
在原点的处理上,也避免了除0带来的数学上的问题,使用NaN增强了用户友好度。
5 高维度向量查找文本相似度
如何从二维过渡到高维,当今天AI、大模型火遍全球,量化的思想普及,用高维度向量来描述世界已经成为趋势。
大模型之所以能“理解”文本、图像、声音,本质上是把这些非结构化信息映射为高维空间中的坐标点。判断两段文本语义是否相似,就是判断两个高维点的方向是否接近。
这与我们在二维平面上计算 (5,1) 和 (50,10) 的余弦距离,没有任何本质区别。
我们通过构建以下示例来尝试用高维向量判断两段文本的语义相似度。
5.1模拟生成向量数据
首先,在本地准备sentences.txt文本,随机编写100条无规律的文本。将这100条无规律文本转化成对应的向量数据。
使用sentence_transformers模型,通过编写python程序,将文本转化成384维的向量数据。sentence_transformers用于生成文本、图像等数据的向量表示,输出维度通常在384到1024维之间。

运行成功后,获取到text_vectors.csv,记录了每个文本对应的384个坐标信息。


对已有的csv文件进行整合,将向量值合并到同一列,以json格式保存,生成vectors_as_json.csv文件。


将vectors_as_json.csv保存到本地,添加id列。
5.2迁移向量数据到dm9数据库
可以通过dm9的dts迁移工具将对应的csv文件数据迁移到数据库中。
新建迁移工程,迁移任务,选择迁移类型为CSV-DM,将初始数据迁移到dm9数据库中。
指定CSV格式,双引号作为文本限定符。
指定目的端对象,使用vectores_384d_2表暂存数据。
迁移成功,目的表中共100条数据。
查看表中的数据,vectores_384d_2中保存了100条文本信息以及对应的模型向量维度值。
这个时候迁移过来的向量数据,被存储为文本类型,我们需要将其转化成向量数据。创建vectores_384d表存储最终的向量数据,指定"VECTOR_384"列类型为 VECTOR(384, *),向量维度为384维,向量格式不指定。
CREATE TABLE "SYSDBA"."vectores_384d"
(
"id" VARCHAR(200),
"text" VARCHAR(200),
"VECTOR_384" VECTOR(384, *)) STORAGE(ON "MAIN", CLUSTERBTR) ;
对vectores_384d_2表的VECTOR_384列数据进行清洗,去除换行符和多余的空格,去除双引号。使用merge语句和TO_VECTOR函数,将字符串类型转换成向量数据,插入到最终表vectores_384d对应的列去。
---去掉换行符和空格
UPDATE "SYSDBA"."vectores_384d_2"
SET VECTOR_384 = REPLACE(REPLACE(REPLACE(VECTOR_384, CHR(10), ''), CHR(13), ''), ' ', ' ');
MERGE INTO "SYSDBA"."vectores_384d" a
USING "SYSDBA"."vectores_384d_2" b
ON (a."id" = b."id")
WHEN MATCHED THEN
UPDATE SET a.VECTOR_384 = TO_VECTOR(REPLACE(b.VECTOR_384, '"', ''));
我们就获得了对应的向量数据。
5.3查找文本相似度
使用第4章节中的sql查找任何一个文本的相似值。
如下:查找“我喜欢吃苹果,尤其是红富士”的相似语句,代入对应的向量值进行查找。
sentences.txt中与“我喜欢吃苹果,尤其是红富士”最相似的语句为“我最爱吃的水果是香蕉和苹果”。
查找“达梦数据库”的相似语句,代入对应的向量值进行查找。
sentences.txt中与“达梦数据库”最相似的语句为“国产数据库”。
以上示例,我们用最朴素的方式验证并使用了DM9的向量功能点,希望可以抛砖引玉,吸引更多技术深耕者共同探讨。
DM9 迈出的这一步,本质上是在回答一个问题:当 AI 应用需要大规模向量检索时,国产数据库能不能接住?
从本文的测试来看,答案是积极的。剩下的,就交给时间和生产环境去检验了。
#达梦数据库#达梦同行者征文#达梦9#dm9




