mysql 9.0开始支持向量(VECTOR)数据类型,社区褒贬不一,虽然它的功能还比较简陋,不过对于保存嵌入模型向量化的数据,还是非常有帮助的,而在mysql以前的版本中,我们的方案主要还是使用blob数据类型的字段来保存向量数据的内存数据。其实现在很多单位还在使用mysql的旧版本,并没有都跟新上mysql 9。以下主要介绍下mysql使用blob字段存储向量数据后续可能会遇到的小坑。
我有一个nodejs开发的程序,对一些新闻标题使用嵌入模型进行处理后将向量数据保存在mysql中,后续会取出跟其他的标题向量进行语义匹配,就这个简单的写入和读出就遇到问题了。
我使用的是一个4096维的嵌入模型,会将每一个新闻标题转换成一个包含4096个浮点数的数组,

let float32Array = new Float32Array(titlevector);
let buffer=Buffer.from(float32Array.buffer); 

将buffer作为字段值通过insert语句插入表格即可,没有什么毛病。
读取的话,执行SQL查询,得到返回的结果集dbchklist

		dbchklist.forEach(item => {
			const blob = item.tvb;
			item.tv= new Float32Array(blob.buffer, blob.byteOffset, 4096);
			});

好像没有毛病,但是执行时报错了

RangeError: start offset of Float32Array should be a multiple of 4
    at new Float32Array (<anonymous>)

Float32Array要求缓存得从4的倍数的地址开始!而在 Node.js 中使用 mysql2 库时,无法直接确保返回的 blob 对象内存对齐,这是由底层实现决定的。对于没有对齐的,可以创建新的对齐内存,使用高效 Uint8Array.set() 复制数据。

		dbchklist.forEach(item => {
			const blob = item.tvb;
			if (blob.byteOffset % 4 === 0) {
        		item.tv= new Float32Array(blob.buffer, blob.byteOffset, 4096);
				}
			else {
				const arrayBuffer = new ArrayBuffer(16384);
				const sourceView = new Uint8Array(
					blob.buffer, 
					blob.byteOffset, 
					16384
					);
				new Uint8Array(arrayBuffer).set(sourceView);
				item.tv=new Float32Array(arrayBuffer);
				}
			});

这样就可以正常把blob保存的向量数据正常读出了。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐