向量数据库

向量数据库的存储,主要是用来存储向量,这里向量可以是任何东西。

比如说:

歌曲:【歌手,歌名,歌曲的评论数,歌曲的风格,歌曲的上市的时间….】
这样把一首歌曲的,各种特征值,汇聚成一个向量。
然后就可以存库,并且已知某个人喜欢一首歌,就可以搜索相似的歌曲推荐给他。

词组:【词向量值】
把这样一个词向量存库后,将文字向量化存储,就可以根据用户的提问,搜索到近似的知识,近似的问题。

声音:【声音向量】
把一段声音向量化存库,是语音识别的常规操作

图片:【图向量】
如果将图片向量化存储,就可以搜索相似的图片。

视频:【音视频向量】
将视频向量化存储,可以搜索到相似的视频。

而且向量的距离也预示着一种关系,比如将“警察”和“小偷”,“猫”和“老鼠”, 存向量数据库后,警察到小偷的向量距离,和猫与老鼠的向量距离接近。

传统数据库是不适合存储向量数据的,所以需要引入传统的数据库。传统的数据库当然是sql
这个时间点,正好适合看看数据库选型,之前看过微博一张图,讲数据库的,

HBase
特点:
基于Hadoop的分布式列存储系统。
适合处理大规模数据集。
支持高并发读写和强一致性。
适用场景:
大数据分析和存储。
需要快速随机访问大量数据的场景。

MySQL
特点:
关系型数据库,使用SQL查询语言。
支持事务、复杂查询和关系数据模型。
适用场景:
传统的Web应用。
需要复杂查询和事务支持的场景。

TiDB
特点:
兼容MySQL协议的分布式数据库。
支持水平扩展和强一致性。
设计用于处理HTAP(混合事务/分析处理)工作负载。
适用场景:
需要MySQL兼容性和水平扩展能力的应用。
实时分析和事务处理。

Redis
特点:
高性能的内存数据结构存储,支持多种数据结构。
通常用作缓存和消息队列。
适用场景:
需要高速缓存的应用。
实时消息系统。

MongoDB
特点:
面向文档的NoSQL数据库。
支持灵活的数据模型和丰富的查询语言。
适用场景:
需要存储半结构化或无结构化数据的应用。
快速开发和迭代的项目。

Kafka
特点:
分布式流处理平台。
高吞吐量、可扩展、持久化消息系统。
适用场景:
大数据实时处理和分析。
构建可靠的数据管道和流应用。

消息队列(如RabbitMQ)
特点:
支持异步消息传递和解耦应用组件。
提供可靠的消息传递保证。
适用场景:
需要解耦微服务架构的应用。
异步处理和背压管理。
这样一看确实向量数据库独特的向量存储和检索是需要针对化设计的。

向量数据库存的是向量,主要场景也是找到相似的向量集合,所以和传统数据库的精确查找不太一样,这样的检索方式一般是最近邻(Nearest Neighbors)的方式

第一是检索:

暴力搜索总是最准的,可以直接算向量的欧式距离,来暴力搜索,搜索的质量很好,但是速度极慢。

聚类算法是一种优化,定下几个点,然后不断的优化迭代,让这几点代表了几个群体。然后检索的时候,只需要找这几个中心点和检索向量的距离,但是如果实际这样会不准确。
一般来时聚类个数可以提升来提升准确性,但是聚类个数提升意味着速度下降,当聚类个数提升到存的向量个数,那么就是退化成暴力搜索了。

还有位置敏感哈希函数,当一个向量点经给哈希函数后,相似的向量会因为这个哈希函数得到相同的哈希值,这样就只需要去该桶检索即可。这样位置敏感哈希函数,可以使用随机超平面的方式得到其编码。但是随机超平面的方式也是有问题的。

所以对位置敏感哈希函数,会进行一个分段措施,会对向量点的段进行检索,第一段会去第一段区的桶内检索,第二段会去第二段区的通内检索。

第二是内存:
当有10000w个向量,每个向量维度为128的时候,就占有了4.7GB了

可以把一个向量点,周围的相似点都把它替代为质心点,这样的有损压缩,实际上压缩率是跟质心数目有关的。落地实现是用向量和质心编码号进行关联,然后维持一个小码本,码本是编码号和对应的向量值。这个过程就是量化。

如果像两个的分布非常不集中,很稀疏,那么需要很多质心,越高维度,则数据越稀疏,这样需要的质心非常多。128维度的向量需要的质心数目为 2^64。但是依旧可以用分段来解决这些问题,将128维度分割成8个段,每个段只有16维度的向量值。这样8个子空间的码本其实相当小,这个方式也叫PQ,积量化。

PQ处理完后,4.7GB就到了70多mb。

这里需要引入一个6人理论,就是美国总统和一个任何人都是连接不高于6。
所以如果遍历向量的时候,使用这样的连接来进行检索。那么检索速度为很快。
这样的搜索方式叫做NSW(导航小世界)

这里需要进行手动帮这些节点建立连接
1 两点很近,则需要建立连接
2 每个点都有连接
3 12原则满足的情况下建立的连接需要少!

如何建立这个图是最关键的点,可以把点随机放回图,然后建立连接,在一开始这样的点分布会很稀疏。这样可以建立一个先快后慢的检索。

后面的人又演进了一个分层级的,HNSW,也就一层一层都有不同点,最上层的点是很稀疏,连接长度很长,每个层级都是按照连接长度来建立的,这样可以稳定的进行先快后慢的搜索方式。
这样的方式比普通的NSW好,但是维护的内存高。