写在前面
最近在学习一些 AI 相关的开发,了解了一些未接触过的东西,其中有一部分是向量数据库,想开一个专题,对相关的内容做一下整理。
内容
什么是向量数据库
一般在我们的日常开发中,使用的数据库存储主要有两种形式:行存储形式
和列存储形式
。
行存储形式常见的就是我们的 MySQL,列存储形式常见的有 HBase。
数据用行存储和列存储有什么区别呢?
假设有一个用户信息表,如果用行存储,在磁盘里的表现形式是:
张三 | 18 | 男 | 李四 | 19 | 男 |
---|
而如果是用列存储,则相同属性的数据,会靠在一起:
张三 | 李四 | 18 | 19 | 男 | 男 |
---|
我们可以发现,假如我想查询某个用户的数据,那么对于行存储,我只要找到张三,然后顺序遍历下去,就可以拿到该用户的全部记录了。而如果是列存储,则为了组装出这个用户的数据,需要跳过多个内容才能获取到。
但如果我想统计有多少个男性这样的数据,行存储则反过来需要全表遍历了。而列存储我只需要找到性别列的开头位置,然后顺序遍历下去,统计即可。
于是行存储和列存储就引申出了两类数据处理:OLTP 和 OLAP。
OLTP(Online transaction processing)翻译为联机事务处理,是关系型数据库的主要应用,常用来做数据的查询,也就是我们的 Select 操作*(想想对于关系型数据库,我们经常提到的就是如何优化查询语句之类的问题)*。
OLAP(OnLine Analytical Processing)翻译为联机分析处理,则是常用来做分析、决策的操作,例如 Group By 之类的操作。
所以日常生活中,我们需要根据实际的业务情况,考虑这块业务是倾向于事务处理,还是分析处理,然后再反推回我们需要怎样的数据库。
但随着人工智能的发展,有些数据需要以更高维度的形式存在,例如图像识别、推荐系统等,它们用到了数学上的向量来进行表示。而行存储和列存储,都是从二维的角度来处理,也就是传统的数据库是难以很好地处理更高维度的数据,因此就有了向量数据库。
在向量数据库里,一个向量就是一条数据,例如一张图片,一只狗。一个向量里会有多个元素,代表着这个事物的多个特征,假设说我们想要从毛发、鼻子长度、体型、颜色的四个维度来标识一只狗,那么这个向量里就要有这四个元素。
由于我们可以用多个维度来标识一个事物,也就意味着如果我们想要知道事物之间的关系,有了更多的条件来让我们判断。利用数学上向量的某些距离度量算法,就可以让我们实现这个目标。举个例子,假设我们有四个向量,向量A-人物小A、向量B-人物小B、向量C-猫和向量D-老鼠。如果我们从物种维度上来进行距离度量,则小A和小B的距离应该是小于小A和猫的距离,毕竟物种不同。从另外一个角度,假设小A是警察,小B是贼,我们可能通过计算发现,小A和小B之间的距离,居然跟猫和老鼠之间的距离差不多,这种情况可能就容易让我们产生一种类比的关系。所以用多维向量来表示事物,让我们有了更多的想象空间。
向量的距离度量
向量之间的距离度量,一般有三种方法:
- 余弦相似度
- 点积
- 欧几里得距离
余弦相似度
余弦相似度就是我们高中数学的时候,会计算的 cos 的值。如果两个向量方向相同,cos 等于1,如果方向相反,cos 等于 -1。我们可以通过之间的夹角大小,来判断这两个向量之间的关系大小。
点积
点积是将两个向量之间各自的值相乘,然后将乘积相加,最终得到一个数值。我们通过这个总和的大小,来判断这两个向量之间关系的大小。
欧几里得距离
欧几里得距离,则是计算两个向量的顶点之间的距离,通过顶点距离的大小来判断两个向量之间关系的大小。
参考
什么是列式存储,一文秒懂
What is Qdrant?
向量数据库技术鉴赏