数据质量是数据管理中最重要的问题之一[1].数据质量的一个重要内容是不一致性检测.不一致数据普遍存在却并非显而易见的,使用不一致数据可能导致错误的决策,甚至会付出昂贵的代价.
在实际应用中,为提高数据质量,通常需要找出不一致数据,也就是对数据进行不一致性检测.对一个集中式数据库来说,不一致性检测较为容易,如对集中式数据库进行函数依赖冲突检测,可以使用一种基于SQL技术的检测方法[2].然而在现实中,一个关系表的数据可能被切分,并分布在不同的站点上[2].
例1:考虑如下一个关系表STUDENT(id,SNo,SName,Dept,CNo,CName,CGrade,Instr,Office),每一个学生元组包含了学号、姓名、院系、课程编号、课程名称、课程成绩、任课教师、办公室编号等内容.这里,ID是关系表STUDENT的主键,STUDENT的一个实例D0见表 1.
为了检测不一致性,在关系表STUDENT上定义了如下几个FD作为数据质量规则:
· φ1:SNo→SName
· φ2:CNo→CName
· φ3:CNo,SNo→Instr
· φ4:Instr→Office
这里,φ1声明了学号唯一决定学生姓名,φ2声明了课程编号唯一决定课程名称,φ3表示课程编号和学号唯一确定任课教师,φ4表示任课教师唯一确定办公室编号.
假定想要找到D0中不一致的数据,即D0中至少违反一个函数依赖的元组.这里,用ti表示D0中id为i的元组,则在D0中存在冲突的元组有t1,t2,t4,t5,t6,t8,t9,t10.具体来说,元组t4和t6违反函数依赖φ2:元组t4和t6课程编号相同,课程名称不同.与此类似,元组t5和t9违反函数依赖φ2.
在集中式数据库中,要检测D0中存在的冲突元组,可以使用基于SQL的技术.对于每一个函数依赖,编写一套相应的SQL语句,在数据库中执行该语句,即可检测违反该函数依赖的元组[2].而如果D0被水平或者垂直切分,各数据块分布在不同的站点.这种检测方法无法直接使用,通常需要进行数据迁移.
考虑前面提到的表 1,其数据被水平切分成3部分,分别见表 2~表 4,其中,分片
已有的关于分布式环境下完整性约束的研究主要关注条件函数依赖(conditional functional dependency,简称CFD)的冲突检测,如Fan提出了一种分布式环境下检测条件函数依赖的方法[2],该检测方法主要是基于模式表(pattern tableau).与条件函数依赖不同,函数依赖由于缺乏可以利用的模式表,无法利用该技术进行不一致性检测,因此,该技术不适合分布式环境下函数依赖的不一致性检测.其他关于分布式环境下完整性约束的研究主要集中于定义在系统状态上的约束[3]或者是约束可以在本地进行验证的情况[4, 5].
本文的主要贡献如下:
(1) 给出了分布式环境下单个函数依赖不一致性检测响应时间代价模型,基于该模型,将最小化响应时间问题划归为整数规划问题.由于分布式环境不一致性检测任务分配问题为NP-难问题,无法在多项式时间得到最优解,本文基于该模型给出了3/2-近似最优检测任务分配算法.
(2) 研究了多个函数依赖进行批量检测的问题,总结了可以进行批量检测的多个函数依赖的特征,并给出了分布式环境下多个函数依赖批量并行检测的算法.
(3) 基于真实和人工数据集,通过实验验证了本文提出的单个函数依赖不一致性检测算法和多个函数依赖批量检测算法,并进行了对比分析.
本文使用真实及人工大数据集,基于Hadoop平台对提出的检测方法进行了性能检测,并与传统的集中式方法和基于Hadoop的Naïve方法进行了比较.实验结果表明:本文的方法在数据规模和分片数量方面扩展性良好,在减少响应时间和数据迁移方面效果明显.
1 预备知识 1.1 函数依赖函数依赖可以看作是定义在关系上的完整性约束.假定R是一个关系模式,在其上定义了一个函数依赖集合,Attrs(R)={A1,A2,…,Am}定义了R上的属性集合,R上的每一个属性A∈Attrs(R)的域用Dom(A)表示.R的一个实例I是一个元组的集合,其中每一个元组属于Dom(A1)x…xDom(Am).这里,用t[A]表示元组t的属性A的值,用t[L]表示Attrs(R)中一组属性L在t上的投影.
定义1. 函数依赖(简称FD)是定义在关系R上的形如X→Y的表达式,这里,X,Y是Attrs(R)上的属性集合.函数依赖X→Y在关系R上成立,当且仅当对R的每一个实例,如果R中的任意两个元组有着相同的X属性值,则必然有着相同的Y属性值.一个函数依赖X→Y是平凡的,如果Y是X的一个子集.平凡函数依赖对所有的关系实例都成立.如果一个函数依赖满足Y∩X=∅,则这个函数依赖是非平凡的.
对于函数依赖φ:X→Y,X是φ的左侧(left hand side,简称LHS),而Y是φ的右侧(right hand side,简称RHS).由于平凡函数依赖对所有关系实例都成立,本文中仅考虑非平凡函数依赖的不一致性检测问题.
1.2 函数依赖冲突函数依赖作为完整性约束的一种,其冲突意味着违反了完整性约束.函数依赖冲突在现实中普遍存在,特别是在数据集成、数据融合以及Web数据抽取等应用中更为常见.
给定关系R的一个实例D,函数依赖φ:A→B,将D上违反φ的冲突表示为Viot(φ,D).对于D中的每一个元组t,如果存在一个元组t'满足t(A)=t'(A)且t(B)¹t'(B),说明元组t和t'违反了函数依赖φ,因此有t∈Viot(φ,D).假定S为定义在D上的函数依赖的集合,则Viot(S,D)表示D上的所有违反S中函数依赖的冲突.用符号ViotP(φ,D)表示PAViot(φ,D),这里,PAViot(φ,D)是Viot(φ,D)在属性A上的投影,R中其他元素值用空值null表示.与Viot(φ,D)相比,ViotP(φ,D)包含数据更少.
一个关系R的任一水平分片与R有着相同的模式,因此,如果函数依赖φ是定义在R的实例D上面的,则φ同样也是定义在D的各个分片上的.这里,将D的任一水平分片Di上违反φ的冲突定义为Viot(φ,Di).
1.3 函数依赖冲突检测 给定关系R的实例D,D水平切分为(D1,…,Dn).假定D的每一个切分分布在一个单独的节点上,对于i∈[1,n],Di分布在节点Si上.函数依赖φ是定义在R上的一个函数依赖,函数依赖φ的冲突检测问题是查找ViotP(φ,D).给定函数依赖φ,φ可以在本地检测当且仅当满足
具有最小响应时间的函数依赖不一致性检测问题,其输入是一个函数依赖的集合S和水平切分的关系R的实例D,响应时间满足以下条件:(a) 集合S中的函数依赖在数据迁移U之后可以本地检测;(b) 响应时间RT是最小的.然而找到一个最小响应时间的检测算法是不现实的,在水平切分情况下,具有最小响应时间的函数依赖不一致性检测问题是一个NP-难问题[4].
2 分布式大数据不一致性检测这一节探讨分布式环境下水平切分的关系数据不一致性检测问题.与集中式数据相比,分布式环境下函数依赖不一致性检测更具挑战性,通常需要进行数据的迁移.在进行不一致检测时,需要确定哪些元组需要迁移以及迁移到哪个节点.对于单个函数依赖来说,该问题是已经是非平凡的.根据前面的介绍,找出一个具有最小响应时间的检测算法是NP-难的.
2.1 单个函数依赖冲突检测· 算法CetDetect.
首先,选择一个节点Sj作为函数依赖φ的执行节点,其他节点上的元组都迁移到节点Sj;最后,函数依赖φ的冲突检测可以在节点Sj进行.这里选择元组数量分布最多的节点作为执行节点,可以减少数据迁移量及通信代价.算法CetDetect中,每个元组最多迁移一次.由于该算法将所有数据迁移到一个节点,在该节点进行不一致性检测,在数据规模特别大时,大量数据迁移到一个节点,检测任务由一个节点承担,导致负载严重不均衡,该节点很容易成为检测的瓶颈.
· 算法SingleFdDetRT.
算法SingleFdDetRT进行分布式环境大数据不一致检测时,分为以下几个步骤:(a) 数据预处理;(b) 任务分配;(c) 数据迁移;(d) 不一致性检测.
给定关系R的实例D,D水平切分为(D1,…,Dn).假定D的每一个切分分布在一个单独的节点上,对于∀i∈[1,n],Di分布在节点Si上.对任一节点Si,i∈[1,n],算法首先对其上的数据Di进行预处理,假定其数据预处理时间为predeal(Di).为保证不一致检测的准确性,预处理后的数据需要进行数据的迁移,也就是不一致性检测任务的分配.假定任一节点Si迁入的数据为DDi-in,迁出的数据为DDi-out,则总的数据迁移量为
${\rm{\Delta }}D = \sum\limits_{i \in [1,n]} {{\rm{\Delta }}{D_{i{\rm{ - }}in}}} = \sum\limits_{i \in [1,n]} {{\rm{\Delta }}{D_{i{\rm{ - }}out}}} .$ |
也就是说,在数据迁移过程中,各节点总的迁入数据量与总的迁出数据量相同.假定对任一节点Si,i∈[1,n], 完成数据迁移后,其数据规模为
$cos{t_{RT}}(\varphi ) = \mathop {\max }\limits_{i \in [1,n]} predeal({D_i}) + \frac{1}{{bw}}\sum\limits_{i \in [1,n]} {{\rm{\Delta }}{D_{i{\rm{ - }}out}}} + \mathop {\max }\limits_{i \in [1,n]} check({D'_i})$ | (1) |
其中,predeal(Di)为各节点数据预处理耗时,n为节点个数,bw为网络带宽,φ为待检测的函数依赖.
依据公式(1),函数依赖不一致性检测的响应时间取决于3部分:各节点数据预处理的最大耗时
不一致性检测的第1步是数据的预处理.数据预处理的主要目的是消除与待检测函数依赖属性值相关的冗余数据,其好处有两个方面:一是可以减少数据迁移量,特别是在冗余数据比较多的情况;二是可以提高检测效率.预处理一方面消除了冗余数据,另一方面,预处理后的数据更有利于不一致性检测.
定义2. 关系r上基于函数依赖X→Y的属性集X∪Y将r中所有元组划分成不同的等价类,称为r在X∪Y上的一个划分,用PX∪Y表示.等价类划分的原则是同一个等价类内有着相同的X属性值,且去除冗余.
在数据预处理阶段,首先在各个节点并行扫描一遍本地数据,依据定义2,将本地元组进行等价类的划分.进一步将划分好的等价类表示成键值对<key,value>的形式,用P<X,Y>表示,其中,以每个等价类中X属性值为key,Y的不同属性值集合为value.这种键值对的表示形式对X和Y属性值是相同的,仅保留一组值,因此可以有效去除各个节点的冗余数据.经过预处理后的数据由于去除了冗余数据,因此可以减少数据迁移量和检测的工作量.以表 2为例,对函数依赖φ2,根据定义2,可以得到关系r在数据片段
PCNo∪CName={{(202,Ecology)},{(301,Geometry)},{(101,Economics)}}.
用键值对表示为
P<CNo,CName>={<202,[Ecology]>,<301,[Geometry]>,<101,[Economics]>}.
对于各个节点得到的局部数据等价类,为并行检测函数依赖不一致性,需要进行数据迁移.这里使用哈希函数计算每个等价类的哈希值,哈希函数的输入为函数依赖LHS属性值.根据定义2,同一等价类内的函数依赖LHS属性值相同,因此其哈希值也相同.也就是说,每一个等价类有唯一的哈希值.然后,将具有相同哈希值的等价类迁移到同一个执行节点,并进行等价类的合并.等价类合并过程中消除了全局的冗余数据,因此可以减少不一致性检测要处理的数据规模,提高检测效率.各个执行节点得到合并后的等价类后,根据同一等价类中包含的元组个数进行不一致性检测:如果等价类中元组个数为1,说明不存在违反函数依赖的情况;如果等价类中元组个数大于1,说明存在违反函数依赖的情况.
完成以上的数据等价类合并工作,得到初步预处理数据,下一步考虑在各个节点对得到的初步预处理数据进行分片.数据分片的目的是为了便于接下来的并行检测.数据分片的原则是,存在潜在冲突的元组数据分配到相同的分片内,这样可以保证不一致检测结果的准确性.
本文考虑利用散列函数对各节点初步预处理过的数据进行分片,假定每个节点上的预处理数据根据散列函数m散列为m片,将预处理得到的键值对的key作为散列函数m的输入,可以将key转换为0到m-1的整数值.
根据各个键值对散列值的不同,散列函数将D的任一切分Di分成m片,分别为
图 1中,H1为散列值为0的键值对组成的块,H2为散列值为1的键值对组成的块,以此类推.对∀φ∈[1,m],有:
${H^j} = H_1^j \cup ... \cup H_n^j.$ |
这里考虑分片大小m的取值问题.m取值的大小会影响数据分配时的负载均衡,m取值越小,则分片的粒度越大;m取值越大,则分片的粒度越小.如果m<n,说明分片数量<节点数量,在进行任务分配时,会出现有些节点没有负载,而有些节点的负载较大的情况.如果分片过多,理论上有利于负载分配更加均衡,但是进行负载分配也需要耗时.为提高不一致性检测的并行度,使得每个节点都不会因为没有分配检测任务而空闲,本文中散列分片数量不少于节点个数,即m≥n.
在得到散列及合并后的数据分片H1,…,Hm后,为对数据分片执行不一致性检测,需要将数据片分配到执行节点,接下来考虑m个数据片的任务分配情况,该问题为多处理机调度问题.
问题1(多处理机调度问题). 任给有穷的任务集A,每一个任务a∈A的响应时间为t(a)∈Ζ+,处理机数目为n∈Ζ+,任务截止时间为D∈Ζ+,其中,Ζ+为正整数集合.判定:
是否能将任务集A划分成n个不相交的集合A=A1∪…∪An,使得:
定理1. 多处理机调度问题为NP-完全问题[6].
证明:利用限制法证明.考虑该问题的一种特例,当m=2且
本文中需要检测的数据块为m个,节点个数为n个,对每个i=1,2,…,m和每个φ=1,2,…,n,第i个数据块在第φ个节点上检测耗时为tij.依据不一致性检测响应时间代价模型costRT(φ),要想减少总的响应时间,应当最小化数据迁移时间
· 目标函数:
$\min {\rm{ }}t + \frac{1}{{bw}}\sum\limits_{j = 1}^n {{\rm{\Delta }}{D_{j{\rm{ - }}out}}} .$ |
· 约束条件:
$\begin{align} & \sum\limits_{j=1}^{n}{{{x}_{ij}}}=1,\text{ }1\le i\le m; \\ & \text{ }\forall j\in [1,n],\text{ }t\ge \sum\limits_{i=1}^{m}{{{x}_{ij}}{{t}_{ij}}}; \\ & \text{ }\forall j\in [1,n],\text{ }\!\!\Delta\!\!\text{ }{{D}_{j\text{-}out}}={{D}_{j}}-\sum\limits_{i=1}^{m}{{{x}_{ij}}H_{j}^{i}},\text{ }1\le i\le m; \\ & \text{ }{{x}_{ij}}\in \{0,1\},\text{ }1\le i\le m,\text{ }1\le j\le n. \\ \end{align}$ |
可以将上述整数规划问题关于xij的约束进行松弛,松弛后的约束条件为0≤xij≤1,1≤i≤m,1≤φ≤n.这样,可以将上述整数规划问题松弛为线性规划问题.
由于该问题为NP-完全问题,在多项式时间内难以得到问题的精确解,本文给出一种近似最优的综合考虑数据迁移量与负载均衡的算法.
算法1. Sorted-LoadBalance.
Input:机器集合M={Mi},i∈[1,n];任务集合A={A1,…,Am}.
Output: A(1),A(2),…,A(n).
1. for each i∈[1,n] do
2. Ti=0,Ai={};
3. end for;
4. Desc(A); //依据A中任务耗时tj的大小对A中任务降序排列
5. 假定t1≥t2≥…≥tm;
6. for each φ∈[1,m] do
7. if机器Mi任务耗时达到最小值
8. if
9. 将任务φ分配给机器Mi;
10. end if;
11. A(i)←A(i)∪φ;
12. Ti←Ti+tj;
13. end if;
14. end for.
引理1. 给定包含m个任务的集合A={A1,…,Am},n个机器节点,T为响应时间最优值,tj为任务Aj的响应时间,φ∈[1,m],则有:T≥
证明:m个任务的总的处理时间为
引理2. 给定包含m个任务的集合A={A1,…,Am},n个机器节点,T为响应时间最优值,tj为任务Aj的响应时间,φ∈[1,m],如果m>n,则有T≥2tn+1.
证明:对于根据执行时间大小降序排序后的任务序列,其前n+1个任务中,每一个需要的响应时间至少为tn+1.任务个数为n+1个,而机器节点个数为n个,根据鸽笼原理,必然有一个机器节点分得的任务个数为2个,因此,该节点的响应时间≥2tn+1;而T为所有机器节点响应时间的最大值,因此有T≥2tn+1.
定理2. 当m>n时,算法Sorted-LoadBalance的响应时间T≤
证明:并行执行多个任务时,如果负载最大的机器Mi的负载为一个任务,则调度是最优的.假定节点Si负载至少为2个任务,设tj为分配给Si的最后一个任务的响应时间,这里,φ≥n+1.因为前n个任务分配给不同的节点,由引理2,
${{t}_{j}}\le {{t}_{n}}_{+1}\le \frac{1}{2}{{T}^{*}}$ | (2) |
在将响应时间为tj的任务分配给节点Si之前,Si的负载是所有节点里最小的,此时,Si的负载响应时间为Ti-tj,其中,Ti为在将响应时间为tj的任务分配给节点Si之后,Si的所有负载的响应时间.因此,所有节点负载的响应时间均≥Ti-tj.所有节点的负载响应时间相加得到
由于所有节点负载的任务响应时间之和与全体任务的响应时间之和相等,因此有:
${{\tilde{T}}_{i}}{{t}_{j}}\le T*$ | (3) |
公式(2)和公式(3)相加,可得:Tj≤
引理3. 给定函数依赖φ,哈希函数m,
根据该引理,为计算ViotP(φ,D),可以通过为任一数据块Hj,φ∈[1,n],选择一个执行节点Sj,在该节点上计算
算法SingleFdDetRT如算法2所示.
算法2. SingleFdDetRT.
Input: Functional Dependency φ:X→Y; D=(D1,…,Dn).
Output: ViotP(φ,D).
/* 在任一节点Si,并行执行以下程序: */
1. Di-pd←predeal(Di); //数据预处理
2. for each k∈[1,m] do
3. for each <key,[value]>∈Di-pddo
4. if m(key)==k-1 //m(key)为散列函数
5.
6. end for;
7.
8. end for;
9. H←{H1,…,Hm};
10. H'←Desc(H); //依据数据规模大小降序排列
11. 假定H'={H1',…,Hm'},其中,|H1'|≥…≥|Hm'|
12. for each φ∈[1,m] do
13. if H'¹{}
14. if 节点Si分配任务最少
15. A(i)←A(i)∪Hj'; //A(i)为Si负载
16. H'←H'\Hj';
17. end if;
18. end if;
19. end for;
20. return
根据函数依赖的定义,对函数依赖X→Y,当出现多个元组X属性值相同、Y属性值不同的情况,表明函数依赖冲突存在.在算法2中,经过散列和数据迁移后,任一执行节点上的数据块内的元组有着相同的散列值.由于散列函数本身是稳定的,同一散列函数,相同的输入,其输出也是相同的,因此对于有着相同X属性值的元组来说,其散列后的值是相同的.因此在算法2中,有着相同X属性值的元组会被迁移到相同的节点,这保证了算法结果的正确性.
2.2 多个函数依赖的检测算法下面给出分布式环境下检测水平切分数据多个函数依赖冲突的算法.
· 算法SuccDetect
该算法检测多个函数依赖的冲突时,顺序对多个函数依赖中的每一个函数依赖进行检测,对单个函数依赖进行检测的时候,使用前面提到的算法SingleFdDetRT.算法SuccDetect对多个函数依赖不一致性进行检测的时候,采用流水线处理方式,在检测完一个函数依赖的不一致性之后,接着检测下一个函数依赖的不一致性,直到所有函数依赖全部检测完为止.
算法SuccDetect在对多个函数依赖不一致性进行检测的时候,会产生过多的网络负载:检测每一个函数依赖不一致性的时候,通常都要进行数据迁移,同一个元组,在检测不同的函数依赖不一致性的时候可能会被多次迁移,这样就产生了较多的负载.由于对每个函数依赖进行检测的时候都要对全部数据扫描一遍,而数据的扫描是十分耗时的,特别是在数据量比较大的情况下,因此算法SuccDetect的响应时间比较长.
函数依赖冲突检测是一个耗时的工作,特别是大数据的背景下,扫描数据的时间开销比较大,如果能够一次扫描数据库,实现对多个函数依赖不一致性的检测,则可以有效提高检测效率.算法MultiFdDetRT可以对多个函数依赖冲突进行批量检测,检测时只需扫描一次数据库.
· 算法MultiFdDetRT
该算法利用输入的多个函数依赖的LHS部分的结构特点,通过对数据的一次扫描,实现对多个函数依赖不一致性的批量检测,可以有效减少函数依赖不一致性检测的响应时间.
定义2. 关系r上基于LHS(φ1)∩…∩LHS(φn)不为空的函数依赖集合F={φ1,φ2,…,φn}的属性集Attr(F)= LHS(φ1)∪…∪LHS(φn)∪RHS(φ1)∪… ∪RHS(φn)将r中所有元组分成不同的等价类,称为r在Attr(F)上的一个划分,用PAttr(F)表示.等价类划分的原则是同一个等价类内有着相同的LHS(φ1)∩…∩LHS(φn)属性值,且去除冗余.
算法MultiFdDetRT首先依据定义2并行地对各个节点的数据进行等价类划分,进一步将划分好的等价类转换成<key,value>键值对的形式,key值为LHS(φ1)∩…∩LHS(jn)属性值,value为Attr(F)\LHS(φ1)∩…∩LHS(jn)去重后的属性值.进行数据重分布时,以键值对的key值为散列函数的输入,每一个键值对对应一个散列值,然后,将有着相同散列值的键值对迁移到同一个执行节点.由于有着相同散列值的键值对包含了所有的潜在违反多个FD的情况,因此可以在各个节点并行进行多个函数依赖的不一致性检测.
与直接散列相比,先进行等价类的划分,再进行数据迁移和不一致性检测,其优势在于:
1) 有效消除冗余数据,减少数据迁移量;
2) 冗余数据的消除可以减少数据迁移时间,同时将潜在冲突的元组划分到相同的等价类,可以减少不一致性检测的响应时间;
3) 冗余数据的消除可以减少不一致检测时的数据规模,提高检测效率;
4) 一个等价类内的元组仅需散列一次,无需每个元组单独散列一次,可以减少总的散列时间.
数据预处理后,在各个节点以键值对的key值为散列函数的输入计算其散列值,将key值转换为0~m1的整数值.与算法SingleFdDetRT类似,根据各个键值对的key值对应散列值的不同,散列函数将D的任一切分Di分成m块,分别为
算法3. MultiFdDetRT.
Input:函数依赖集合S={φ1,…,φn};D=(D1,…,Dn).
Output:ViotP(φ1,D),ViotP(φ2,D),…,ViotP(φn,D).
1. Compute s(S); //计算S中函数依赖LHS部分交集
/* 在任一节点Si,并行执行以下程序: */
2. Di-pd←predeal(Di); //数据预处理
3. for each k∈[1,m] do
4. for each <key,[value]>∈Di-pd do
5. if m(key)==k1 //m(key)为散列函数
6.
7. end for;
8.
9. end for;
10. H←{H1,…,Hm};
11. H'←Desc(H); //依据数据规模大小降序排列
12. 假定H'={H1',…,Hm'},其中,|H1'|≥…≥|Hm'|
13. for each φ∈[1,m] do
14. if H'¹{}
15. if 节点Si分配任务最少
16. A(i)←A(i)∪Hj'; //A(i)为Si负载
17. H'←H'\Hj';
18. end if;
19. end if;
20. end for;
21. return
显然,LHS(φ1)∩…∩LHS(jn)为LHS(φ1),…,LHS(jn)的子集.根据散列函数的定义,有着相同s(S)属性值的元组被散列到相同的数据块.对于∀i∈[1,n],D中有着相同LHS(ji)属性值的元组是有着相同s(S)属性值的元组集合的子集合.因此经过散列函数m()散列后,对集合S中所有的函数依赖,其存在潜在冲突的元组都被散列到相同的数据块中,这保证了算法MultiFdDetRT不一致性检测结果的准确性.接下来在各个节点统计各散列子数据块的元组个数,节点之间交换统计数据,汇总后根据前面算法SingleFdDetRT中提到的执行节点分配策略,将数据块分配到相应的执行节点,各节点并行进行数据的迁移.数据迁移完成后,函数依赖集合S中所有函数依赖存在潜在冲突的元组都被分配到相同的节点,根据引理2,对∀i∈[1,n],为计算ViotP(ji,D),可以通过在任一执行节点Sj计算
引理4. 给定关系R的一个实例D,假定存在函数依赖X→Y,X'→Y,XX',∀ti,tj∈D,如果ti[X']=tj[X']且ti[Y]¹ tj[Y],i¹φ,则必然有ti[X]=tj[X]且ti[Y]¹tj[Y].
证明:已知ti[X']=tj[X']且ti[Y]¹tj[Y],i¹φ.又XX',即,属性集合X为X'的真子集.对于元组ti,tj来说,其属性集合X'的属性值相同,去掉属性集合X'\X,剩余属性集合为X.假设ti[X]¹tj[X],由XX'可知,ti[X']=ti[X]∪ti[X'\X],tj[X']=tj[X]∪tj[X'\X].由ti[X]¹tj[X]可知,ti[X]∪ti[X'\X]¹tj[X]∪tj[X'\X],即ti[X']¹tj[X'],与已知ti[X']=tj[X']矛盾.故假设不成立,ti[X]=tj[X]成立.
算法MultiFdDetRT在检测多个函数依赖的不一致性时,根据多个函数依赖的LHS部分以及RHS部分所包含的属性情况的不同,实现了中间计算结果的共享,可以有效减少检测的计算量,提高检测效率.前面提到,多个函数依赖不一致性检测中,散列函数的key为LHS(φ1)∩…∩LHS(jn)属性值,value为Attr(F)\LHS(φ1)∩…∩ LHS(jn)去重后的属性值.在数据迁移之后,可能存在冲突的元组都被散列到相同的节点.根据待检测多个函数依赖的LHS部分及RHS部分所包含的属性情况,检测过程中可以实现如下的中间计算结果共享:
(1) 待检测的多个函数依赖LHS部分与LHS(φ1)∩…∩LHS(jn)相同,则在不一致性检测过程中,所有节点在处理各元组数据时,这些函数依赖的LHS部分属性值为<key,value>键值对的key值,因此无需计算.只需根据其RHS所包含属性情况,对元组所对应的键值对的value部分进行切分,进而得到相关的属性值,合并去重后可以得到各函数依赖的冲突元组.
(2) 待检测的多个函数依赖LHS部分相同且与LHS(φ1)∩…∩LHS(jn)不同,检测时,多个函数依赖的LHS部分属性值的计算结果可以共享,即,只需计算一遍,无需每个FD都单独计算一遍.每个待检测FD的RHS部分可由<key,value>键值对的value部分切分得到.
(3) 待检测的多个函数依赖RHS部分相同,则根据<key,value>键值对进行计算时,RHS部分的属性值计算中间结果可以共享,无需每个FD都单独计算一遍,因此可以有效提高计算效率.
(4) 如果待检测的多个函数依赖存在LHS包含的情况,假定LHS存在包含情况的多个待检测函数依赖中LHS包含属性最多的函数依赖为φ,由引理4,违反该函数依赖的元组必然违反LHS为其子集合的其他函数依赖,故在不一致性检测时,违反φ的元组必然违反LHS部分为LHS(φ)子集合的其他函数依赖,因此对于这些函数依赖来说,违反φ的元组无需重复验证.
算法MultiFdDetRT的前提是给定的多个函数依赖LHS部分的交集不为空.然而通常情况下,给定一个函数依赖集合S,其LHS部分不一定有公共属性,这种情况下不能直接使用算法MultiFdDetRT.为了将算法MultiFdDetRT应用到多个函数依赖的不一致性检测,考虑将函数依赖集合S中的多个函数依赖进行分组.分组的依据是组内的函数依赖LHS部分有公共属性,同一分组内的函数依赖可使用前面提到的批量并行检测算法MultiFdDetRT进行不一致性检测,从而提高分布式环境下函数依赖不一致性检测的效率,同时减少网络负载.
例2:以表 1中实例D0上定义的函数依赖集合S={φ1,φ2,φ3}为例,函数依赖φ2和φ3的LHS部分存在公共属性CNo,而φ1与φ2和φ3在LHS部分没有公共属性,因此可以将S={φ1,φ2,φ3}分成两组:{φ1}和{φ2,φ3},组内的函数依赖可以使用批量并行检测算法MultiFdDetRT进行不一致性检测,有效提高检测效率.
由于对函数依赖进行不一致性检测的时候需要扫描全部数据,在大数据背景下,扫描全部数据是一个十分耗时的工作.而前面提到,算法MultiFdDetRT在对多个函数依赖进行不一致性检测的时候只需要对全部数据进行一次扫描,因此在对函数依赖集合S中的多个函数依赖进行分组的时候,要满足组内的函数依赖LHS部分有公共元素,而且分组的个数尽可能地少,这个问题可以划归为最小集合覆盖(minimal set cover,简称MSC)问题.根据文献[6],最小集合覆盖问题是一个NP-完全问题,不存在一个多项式时间的解,除非P=NP,但是可以在多项式时间内得到该问题的近似解.算法4是一个最小集合覆盖问题的贪心算法.
算法4. GreedyMSC.
Input:集合X={1,2,…,n};X的子集合构成的集合F=(S1,S2,…,Sn).
Output:X的具有最小势的集合覆盖C.
1. Initialize: C←{},U←X;
2. while U¹{} do
3. Select S where S∈F and S is a set such that |S∩U| is maximized; //S覆盖U中最多的元素
4. C←C∪{S}; //将S并入覆盖C
5. U←U\S; //从U中移除被S覆盖的所有元素
6. return C.
算法4初始化时U←X,然后逐步从U中减去新增到覆盖C中的集合中的元素,直到C包含X中全部元素为止.算法的时间复杂度主要取决于F的情况.然而,贪心算法并不总是能得到最优解.
例3:假定X={1,2,3,4,5,6,7,8,9,10},F=(S1,S2,…,S5),S1={1,2,5,7,9,10},S2={1,2,3,4,5},S3={3,4,8},S4={4,6,8},S5= {6,7,8,9,10}.贪心算法在执行的时候首先选择包含最多元素的集合S1,剩余的集合在去掉S1中元素后为{3,4},{3,4,8},{4,6,8},{6,8}.要想最终得到X的一个覆盖,至少还要选取S2和S3中的至少一个以及S4和S5中的至少一个.因此,最终选取的集合X的覆盖至少包含F中的3个元素.而该问题的最优解可以通过选择S2和S5共2个子集合得到.
为得到该问题的最优解,可以考虑将该问题表述为如下的(0-1)-规划问题:
任给集合S,S的子集合S1,S2,…,Sn,求解以下(0-1)-规划:
求最小值c(x)=x1+x2+…+xn,
满足条件S1xx1∪S2xx2∪…∪Snxxn=S;x1,x2,…,xn∈{0,1}.
令opt为目标函数最优值,则opt≤n.对于子集合I⊆{1,2,…,n},令SI表示编号在I中的S的子集合的并集,
算法5. OptimalMSC.
Input:集合S={1,2,…,n};S1,S2,…,SnS.
Output:S的具有最小势的集合覆盖C.
1. Initialize: C←{};
2. for (int i=1; i≤n; i++)
3. for (int φ=0; φ≤i; φ++)
4. if (c(i-1,φ)=nil && Sc(i-1,φ)S)
5. c(i,φ)=c(i-1,φ)+{i};
6. else if (c(i,φ)¹nil);
7. c(i,φ)=c(i-1,φ);
8. end for;
9. end for;
10. return C=min{φ|c(n,φ)¹nil}.
对于任意一个子集合I⊆{1,2,…,n},计算SI需要时间O(n2),因此,算法5的时间复杂度为O(n4).该算法为一个伪多项式时间算法,如果问题的最大输入值比较大,则算法的效率会比较低.
通常情况下,得到的一个函数依赖集合的最小集合覆盖不是一个最小精确覆盖(minimum exact cover),意味着所得到的最小集合覆盖中通常存在冗余元素.假定函数依赖集合S的元素个数为n,所得到的最小集合覆盖为C=(C1,C2,…,Ck),则出现C中任意2个子集合有交集或者满足|C1|+|C2|+…+|Ck|>n,意味着C中存在S的冗余元素.冗余元素的存在,使得对多个函数依赖进行不 一致性批量检测的时候出现重复检测的问题.
为解决所得到的最小集合覆盖存在冗余元素的问题,需要对最小集合覆盖进行预处理.算法6用来去除最小集合覆盖中冗余元素.在算法6中,多个函数依赖的最小集合覆盖用包含0,1元素的矩阵M表示,矩阵的行为X中的所有元素,列为最小集合覆盖中的元素.如果矩阵的任一列值为1的元素个数大于1,则意味着在最小集合覆盖中该列所代表的元素出现了冗余.
算法6. MSCRedundantEliminate.
Input:集合X={1,2,…,n};X的最小集合覆盖C=(C1,C2,…,Ck).
Output:每一列元素值为1的元素个数不超过1个的矩阵M.
1. If the matrix M is empty,terminate;
2. Otherwise:
3. for (int i=0; i<|X|,i++)
4. for (int φ=0,counter=0; φ<|C|,φ++)
5. if (Mj,i==1 && counter<1)
6. counter++;
7. else if (Mj,i==1 && counter==1)
8. Mj,i=0; /*修改当前值为0*/
9. end for;
10. end for;
11. return M.
例4:给定X={1,2,3,4,5,6,7},C={A,B,C}是X的一个最小集合覆盖,其中,A={1,2,4},B={2,3,5},C={4,6,7},用矩阵表示的X的最小覆盖如图 2(a)所示.
算法6对图 2(a)的矩阵M进行扫描,发现第2列和第4列分别有2个值为1的元素,因此算法分别修改M[B][2]以及M[C][4]的值为0,修改后的矩阵如图 2(b)所示.根据图 2(b)的矩阵可以得到X的一个最小精确覆盖,C'={{1,2,4},{3,5},{6,7}}.
通过算法6求解最小精确覆盖的方法,可以得到一个函数依赖集合S的最小精确覆盖.基于该最小精确覆盖对S中的多个FD进行分组,实现任意情况的多个FD在分布式环境下不一致性的并行检测.
3 实 验为了验证文中提出的分布式环境下函数依赖不一致性检测算法的有效性,本文使用真实数据集和合成数据集对算法进行了实验验证,测试了算法在不同节点个数、不同数据集规模以及不同函数依赖个数等情况下的响应时间以及数据迁移量情况.
· 实验设置
本实验中使用了由10台服务器通过局域网连接构成的一个集群,每一台机器配备了主频为1.87G的Intel Xeon 2处理器和16G内存,操作系统为Ubuntu10.4.所有算法均由Java实现,算法运行平台为分布式系统架构Hadoop平台与基于BSP(bulk synchronous parallel)并行计算框架的Hama平台.
(a) 数据集.本文中使用了2种不同类型的数据集:一种是TranStats data library提供的Airline On-Time Statistics统计数据[8],这是一个真实的数据集;另外一种是人工生成的数据集.第一种数据集简称“OTPF”,包含了64个属性,如airline ID,flight number等.数据集的规模为35GB,包含了15亿条元组.本文使用该数据集生成一个包含4 000万条元组的数据库实例otpf4,一个包含8 000万条元组的数据库实例otpf8,一个包含1.2亿条元组的数据库实例otpf12.另外一种数据集是一个人工生成的前文提到的STUDENT表的数据集,简称“STUD”,包含了2亿条元组.利用该数据集生成一个包含4 000万条元组的数据库实例stud4,一个包含8 000万条元组的数据库实例stud8,一个包含1.2亿条元组的数据库实例stud12.
(b) 函数依赖.对于数据集OTPF,找出一组反映真实约束关系的函数依赖,函数依赖个数为8个,每个包含了2~5个属性.对于STUD,定义了10个函数依赖,为了验证实验效果,数据集中人为增加了噪声.
· 实验结果
本文设计了5组实验,分别对单个函数依赖的集中式算法CetDetect、基于Hadoop的Naïve算法SingleFdDetHadoop以及本文提出的SingleFdDetRT、基于多个函数依赖的顺序检测算法SuccDetect、基于Hadoop的多函数依赖不一致性检测Naïve算法MultiFdDetHadoop以及本文提出的MultiFdDetRT进行测试,并对近似最优算法与真正最优方案的执行时间进行了比较.在实验中,分别改变节点的个数(|S|)、数据的规模(|D|),每一组实验均在相同条件下运行3次,取实验结果的平均值为最终结果值.
首先评估基于单个函数依赖的检测算法,对每一个数据集选取一个函数依赖进行检测.
· 实验1:改变数据的分片个数
为了评价算法在不同分块数(节点数)情况下的扩展性,本文在数据规模固定的情况下增加节点数|S|从2到8,分别基于数据集otpf8和stud8,对算法的执行时间进行测试.图 3和图 4反映了算法CetDetect,SingleFdDetHadoop,SingleFdDetRT在不同节点下响应时间情况.跟预想的情况类似,算法SingleFdDetHadoop与SingleFdDetRT的响应时间随着节点的增加呈现减少的趋势.由于算法CetDetect随着节点的增加,数据迁移量相应增加,相应数据传输时间增加,而集中检测的检测时间在每种情况下基本相同,因此算法总的响应时间有增加的趋势.由于算法SingleFdDetRT可以进行并行检测,因此响应时间明显比算法CetDetect要小.算法SingleFdDetHadoop与SingleFdDetRT相比,由于本身Hadoop任务启动存在一定的耗时,且数据未经过去重等预处理,数据迁移量及数据规模相对较大,因此响应时间比SingleFdDetRT要长.
· 实验2:改变数据的规模
为评价算法在不同数据规模情况下的扩展性,本文在节点个数固定(4个节点)的情况下,增加数据规模|D|从2 000万条元组到1.2亿条元组,分别基于数据集otpf12和stud12,对算法的响应时间进行测试.图 5和图 6反映了算法CetDetect,SingleFdDetHadoop,SingleFdDetRT在不同数据规模下响应时间情况.
从图中可以看出,3种算法的响应时间随着数据规模的增加而增大,数据规模的增大直接影响到检测的时间消耗及数据传输时间,因此数据规模与算法响应时间成正相关.从图 5和图 6不难看出,算法SingleFdDetHadoop,SingleFdDetRT比算法CetDetect的响应时间少很多,说明分布式并行算法SingleFdDetHadoop,SingleFdDetRT的检测效率明显高于集中式算法CetDetect.而且从图 5和图 6可以看出,随着数据规模的不断增大,算法Single FdDetHadoop,SingleFdDetRT与CetDetect相比,在响应时间方面优势明显;而算法SingleFdDetRT与Single FdDetHadoop相比,随着数据规模的增加,减少的响应时间呈增加的趋势.
其次评估基于多个函数依赖的检测算法,对数据集OTPF和STUD,分别选取LHS包含公共属性的3个FD进行检测.
· 实验3:改变数据的分片数
为评价多个FD的检测算法在不同分块数情况下的扩展性,本文在数据规模固定的情况下增加节点数|S|从2到8,分别基于数据集otpf8和stud8,对算法的执行时间进行测试,实验结果如图 7和图 8所示.从实验结果可以看出:随着节点数的不断增加,算法的响应时间呈减少的趋势.与顺序检测的算法SuccDetect相比,批量检测算法MultiFdDetHadoop,MultiFdDetRT的响应时间还不到其一半,说明批量检测算法在检测多个FD不一致性时优势明显.随着节点数的增加,MultiFdDetRT响应时间均明显少于MultiFdDetHadoop,说明本文提出的检测算法与基于Hadoop的Naïve方法相比在响应时间方面优势明显.
· 实验4:改变数据的规模
为评价多个FD的检测算法在不同数据规模下的扩展性,本文在节点个数固定(4个节点)的情况下增加数据规模|D|从2 000万条元组到1.2亿条元组,对算法的响应时间进行测试.图 9和图 10反映了算法SuccDetect,MultiFdDetHadoop,MultiFdDetRT在不同数据规模下响应时间情况.
不难看出,随着数据规模的不断增加,3种算法的响应时间也不断增加.与分布式并行算法MultiFdDetHadoop,MultiFdDetRT相比,算法SuccDetect的响应时间更长,说明MultiFdDetHadoop,MultiFdDetRT的检测效率更高.而就分布式并行算法来看,本文提出的算法MultiFdDetRT与Naïve算法MultiFdDetHadoop相比,在响应时间方面优势明显.随着数据规模的不断增加,算法MultiFdDetRT的效率优势呈现出不断扩大的趋势.
· 实验5:近似算法与最优算法比较
为了评价本文提出的近似最优的分布式环境不一致性检测算法与真正最优方案的响应时间差距情况,增加节点数|S|,基于数据集otpf8和stud8,分别对单个函数依赖以及多个函数依赖情况下近似最优算法与真正最优方案的执行时间进行测试.图 11和图 12是单个函数依赖情况下近似最优检测算法SingleFdDetRT和真正最优检测算法SingleFdDetOPT在不同节点下响应时间情况.不难看出,在节点个数为2个时,近似最优算法与真正最优方案的执行时间基本相同;随着节点各种的增加,与近似最优算法相比,真正最优方案的执行时间相对较少,但是总体来说相差不大.图 13和图 14是多个函数依赖情况下近似最优检测算法MultiFdDetRT和真正最优检测算法MultiFdDetOPT在不同节点下响应时间情况.可以看出,与单个函数依赖情况类似,在节点个数较少的情况下,近似最优算法与真正最优方案的耗时基本相同;随着节点数的增加,真正最优方案与近似最优算法在执行时间方面相比优势有增加的趋势,但是并不十分明显.
4 相关工作
函数依赖的概念最早由Armstrong提出[1].Fan提出了一种基于SQL技术检测集中式环境中条件函数依赖冲突的方法[2].然而在分布式环境下对函数依赖冲突进行检测,文献[2]中的方法并不适用.Fan等人对分布式环境下条件函数依赖冲突检测进行了研究,利用条件函数依赖的结构减少数据迁移或响应时间[4].文献[9]研究了分布式环境下条件函数依赖不一致性的增量检测.与条件函数依赖不同,函数依赖没有条件函数依赖特有的模式元组,因此,文献[2, 9]中提到的算法不适合分布式环境下对函数依赖进行检测.
文献[5, 10]研究了分布式数据库中完整性约束的检测问题.文献[10]中给出了检测的本地条件,满足这些条件,不用进行数据的迁移,减少了通信代价.文献[5]研究了在不访问全部基本关系的情况下对基本关系更新时全局不一致性检测问题.在某些条件下,条件函数依赖可以在不进行数据迁移的情况下进行不一致性检测[4].与文献[5, 10]不同,在分布式环境下检测函数依赖的不一致性的时候,通常需要数据迁移.
文献[11, 12]对分布式数据源的异常检测问题进行了研究.文献[11]提出了一种分布式环境中检测流量异常的框架,避免了全局通信和集中决策.文献[12]提出了一种针对包含混合属性数据集的快速分布式异常检测策略.这些方法主要针对的是异常检测,而函数依赖冲突检测主要是检测函数依赖约束的违反情况.
文献[13]对数据融合中数据冲突的解析进行了研究,主要针对的是集中式环境下的冲突问题.文献[14]中对约束的冲突情况进行了研究,主要研究了分布式系统中使用本地约束检测全局约束违反的情况.
文献[15-17]对函数依赖冲突的修复进行了相关研究.为了对存在违反函数依赖情况的不一致数据进行修复,通常采用对属性值进行修改的方法.与本文工作不同,这些文献主要关注的是函数依赖冲突的修复问题.文献[18, 19]研究了函数依赖发现的问题,主要是研究给定一个模式,如何发现隐含的约束关系.文献[20]研究了分布式环境函数依赖发现问题.
5 结论和下一步工作本文研究了分布式背景下函数依赖冲突检测的问题,给出了分布式环境下单个函数依赖和多个函数依赖不一致性并行检测的算法,并利用函数依赖的结构特征对多个函数依赖实现批量并行检测.为实现对多个函数依赖的批量检测,考虑对多个函数依赖进行分组,组内的可以进行批量不一致性检测.将多个函数依赖的分组问题划归为最小集合覆盖问题,给出了得到问题近似解的贪心算法.为了消除最小集合覆盖中存在的冗余元素导致的重复检测问题,给出了消除最小集合覆盖中冗余元素得到一个最小精确覆盖的算法.基于真实数据集和人工数据集对本文提出的检测算法进行了验证,实验结果表明,算法在数据规模和节点个数方面扩展性良好,而且在减少响应时间方面优势明显.限于篇幅,本文仅对分布式环境下水平切分的数据不一致性检测进行了研究,下一步考虑对分布式环境下垂直切分的数据不一致性检测问题进行研究.
[1] | Armstrong WW. Dependency structures of data base relationships. Processings of IFIP Congress 74, 1974, 74 :580–583. |
[2] | Fan W, Geerts F, Jia X, Kementsietsidis A. Conditional functional dependencies for capturing data inconsistencies. ACM Trans. on Database Systems, 2008, 33 (2) :1–48. [doi:10.1145/1366102.1366103] |
[3] | Beskales G, Ilyas I, Golab L. Sampling the repairs of functional dependency violations under hard constraints. Proc. of the VLDB Endowment, 2010, 3 (1-2) :197–207. [doi:10.14778/1920841.1920870] |
[4] | Fan W, Geerts F, Ma S, Muller H. Detecting inconsistencies in distributed data. In: Proc. of the IEEE ICDE. Long Beach, 2010. [doi: 10.1109/ICDE.2010.5447855] |
[5] | Huyn N. Maintaining global integrity constraints in distributed databases. Constraints, 1997, 2 (3-4) :377–399. [doi:10.1023/A:1009703814570] |
[6] | Garey M, Johnson D. Computers and Intractability: A Guide to the Theory of NP-Completeness.. W. H. Freeman and Company. 1979 : 32 -38. |
[7] | Kleinberg J, Tardos É. Algorithm Design. New York: Pearson Education, 2006 : 600 -622. |
[8] | http://apps.bts.gov/xml/ontimesummarystatistics/src/index.xml |
[9] | Fan W, Li J, Tang N, Yu W. Incremental detection of inconsistencies in distributed data. In: Proc, 2012 :318–329. [doi:10.1109/ICDE.2012.82] |
[10] | Gupta A, Widom J. Local verification of global integrity constraints in distributed databases. In: Proc. of the 1993 ACM SIGMOD Int'l Conf. on Management of Data. Washington, 1993 . [doi:10.1145/170035.170048] |
[11] | Chhabra P, Scott C, Kolaczyk ED, Crovella M. Distributed spatial anomaly detection. In: Proc. of the INFOCOM 2008, 2008 :1705–1713. |
[12] | Koufakou A, Georgiopoulos M. A fast outlier detection strategy for distributed high-dimensional data sets with mixed attributes. Data Mining and Knowledge Discovery, 2010, 20 (2) :259–289. [doi:10.1007/s10618-009-0148-z] |
[13] | Dong X, Naumann F. Data fusion—Resolving data conflicts for integration. of the VLDB Endowment, 2009, 2 (2) :1654–1655. [doi:10.14778/1687553.1687620] |
[14] | Agrawal S, Deb S, Naidu KVM, Rastogi R. Efficient detection of distributed constraint violations. In: Proc. of the Int'l Conf.. on Management of Data (COMAD 2006). Delhi, 2006 . [doi:10.1109/ICDE.2007.369002] |
[15] | Kolahi S, Lakshmanan L. On approximating optimum repairs for functional dependency violations. In: Proc. of the 4th Int'l Conf. on Digital Telecommunications. Colmar, 2009 :53–62. [doi:10.1145/1514894.1514901] |
[16] | Bohannon P, Fan W, Flaster M. A cost-based model and effective heuristic for repairing constraints by value modification. In: Proc. of the 2005 ACM SIGMOD Int'l Conf. on Management of Data. Baltimore, 2005 . [doi:10.1145/1066157.1066175] |
[17] | Lopatenko A, Bravo L. Efficient approximation algorithms for repairing inconsistent databases. In: Proc. of the IEEE ICDE. Turkey, 2007 . [doi:10.1109/ICDE.2007.367867] |
[18] | Huhtala Y, Karkkainen J, Porkka P, Toivonen H. Tane: An efficient algorithm for discovering functional and approximate dependencies. Computer Journal, 1999, 42 (2) :100–111. |
[19] | Novelli N, Cicchetti R. Fun: An efficient algorithm for mining functional and embedded dependencies. In: Proc. of the 8th Int'l Conf. on Digital Telecommunications, 2001 :189–203. [doi:10.1007/3-540-44503-X_13] |
[20] | Li W, Li Z, Chen Q, Jiang T, Liu H. Discovering functional dependencies in vertically distributed big data. In: Proc. of the 16th Int'l Conf. on Web Information System Engineering, 2015 . [doi:10.1007/978-3-319-26187-4_15] |