@devilogic
2016-07-03T02:27:18.000000Z
字数 2608
阅读 1249
devilogic
话说有天下午和邹老师讨论数据处理方面的东西,这方面我就知道几个名词,什么haddop、hbase之类的,属于哄骗爸妈的那种级别。我问邹老师为啥非关系型数据库例如:mongodb比起关系型数据库例如:mysql要快呢?
邹老师给我解释了半天行存储与列存储之间的关系,我听的是云山雾罩的。大意就是关系型数据库中,数据是以表的形式行进行存储的。要查关联数据时首先要检索到行然后提取出行的某个字段或者说是特性吧。然后做关联查询。而列存储呢?是按照列存储的,就要比行的快。(记不太清楚,邹老师是如何表达的了)。总之是要快。
其实这个弄得我是很晕的。为啥列存储要比行存储检索要快呢?如果从矩阵的角度来看。行矩阵是列矩阵的转置而已,并无什么其他的优点。但是从另外一个角度看就是。无论行还是列存储,如果都按行取出,那么前者取出的是某条完整记录而按照后者取出的是某个特性的全部集合。一条完整的记录拥有很多特性,这些特性之间没法进行统一的运算。而固定某个特性是可以进行统一批量的运算的,之后我直接这样安慰自己。
直到最近的日子,业余时间研究机器学习,想起了正交性这样的概念。尝试的从这个角度理解列存储检索的速度比行的快。
这里需要补充一些基本的数学知识,虽然我不想在一篇技术日志中扩展的来记录数学知识,但是基本概念还是在这里列出,以保持文章的完整。
引用教科书上的一段话。
两个线段的夹角为直角的充要条件是两个向量对应的标量积为零。一般的若为定义了标量积的向量空间,且中的两个向量的标量积为零,则称它们正交(orthogonal)。
其中标量积就是两个向量的内积,就是一个行向量乘以一个列向量,这样得出的并不是第三个向量,而是一个标量。即向量与向量的乘积等于
也就是说当时,我们称之为正交。
那么两个向量与均为或中的向量。则它们之间的距离定义为数值
若和为或中的两个非零向量,且为它们的夹角,则
若和的夹角,则
好吧,有了以上数学知识后,就可以探讨邹老师的那个问题了。例如:我有一个数据库存储了份文档分别为到,而在每个文档下记录了其中关键字所出现的频率。如果使用列存储则表示为:
表格中的数据为文档出现关键字的次数。假如我们有一个关键字要进行查询,例如:查询fuck,hooker,dick
这三个关键字。那么我们只需要构造一个向量,其中要查询向量位置不为,其他元素均为。并且做单位向量处理,需要将搜索向量的各行乘以。这是因为。同样的道理作用于以上的矩阵,归一化处理可将数据统一到一个量级里进行计算,而不使得某个数据过大而引起最终计算结果的导向。
使用以上数据库矩阵,我们称为乘以搜索向量,则得到一个结果向量,这个向量的每一值都是与之相关的夹角的值。,而
这个值越接近说明两个向量越接近,越接近则说明相关性越远。
norml <- function(v) {
u <- v^2
r <- sum(u)
return(v / sqrt(r))
}
foo <- function(M, s) {
mat <- as.matrix(M)
count <- nrow(mat)
for (i in 1:count) {
mat[i,] <- norml(mat[i,])
}
v <- norml(s)
r <- t(mat) %*% t(t(v))
return(r)
}
v <- c(0,3,6,5,1,0,0,2,3,1,2,0,5,3,3,6,0,4,0,0,0,6,0,0)
mat <- matrix(v, nrow=4, ncol=6)
s <- norml(c(0,1,1,1))
r <- abs(foo(mat, s) - 1)
#print(r)
print(which(r == min(r)))
最终求出是号文档。
其实我也不知道这到底是不是行存储与列存储的区别。其实行列存储只是从一个特性一致的变量可以批量进行计算的角度来看,可以进行大量数据的并行运算。