跨库数据表的运算

本文深入探讨了跨库数据表运算的多种方法,包括简单合并、WHERE过滤、ORDER BY与LIMIT OFFSET、聚合运算、GROUP BY、DISTINCT、HAVING以及JOIN ON。重点介绍了集算器在处理跨库数据时的优势,如使用游标和序表进行高效运算,并提供了实际操作示例,展示了如何在不同场景下优化运算性能。
摘要由CSDN通过智能技术生成

1.    简单合并(FROM)

       所谓跨库数据表,是指逻辑上同一张数据表被分别存储在不同数据库中。其原因有可能是因为数据量太大,放在一个数据库难以处理,也可能在业务上就需要将生产库和历史库分开。而不同的数据库,可能只是部署在不同的机器上的同种数据库,也可能是连类型都不同的数据库系统。

       在面对跨库数据表,特别是数据库类型都不相同的情况时,数据库自带的工具往往就力所不及了,一般都需要寻找能够很好地支持多数据源类型的第三方工具,而集算器,可以说是其中的佼佼者了。下面,我们就针对几种常见的跨库混合运算情况详细讨论一下:

       跨库运算,简单粗暴的思路就是把散布在各个库里的逻辑上相同的数据表合并成一个表,然后在这一个表上进行运算。

       例如,在两个数据库 HSQL 和 MYSQL 中,分别存储了一张学生成绩表,两者各自保存了一部分学生信息,如下图所示:

       

       

       利用集算器,我们可以很容易地将这两个结构相同的表合并为一个表,集算器的 SPL 脚本如下:

 

A

B

1

=connect("org.hsqldb.jdbcDriver","jdbc:hsqldb:hsql://127.0.0.1/demo?user=sa")

=connect("com.mysql.jdbc.Driver","jdbc:mysql://127.0.0.1:3306/demo?user=root&password=password")

2

=A1.query("select * from 学生成绩表")

=B1.query("select   * from 学生成绩表")

3

=A2 | B2

       A1、A2 和 B1、B2 分别读取了两个库里的学生成绩表,而 A3 用一种简单直观的方式就把两个表合并了。

       这种方式实际上是把两个表都读入了内存,分别生成了集算器的序表对象,然后利用序表的运算“|”完成了合并。可能有的同学会问:如果我的数据量比较大,无法全部读入内存怎么办?没关系,专为处理大数据而生的集算器,决不会被这么简单的小问题难住。我们可以使用游标,同样可以实现表的快速拼接:

 

A

B

2

=A1.cursor("select * from 学生成绩表")

=B1.cursor("select   * from 学生成绩表")

3

=[A2, B2] .conjx()

       A2、B2 分别用游标打开两个库里的学生成绩表,A3 则使用 conjx() 函数将这两个游标合并,形成了一个新的可以同时访问两个表的游标。

       对应于 SQL,这种简单合并好比只是完成了 from 工作,让结构相同的跨库表的数据“纵向”拼接成了一个可以访问的序表或者游标,而实际运算中,还会涉及过滤 (where/having)、分组聚合 (group+sum/count/avg/max/min)、连接 (join+on)、去重 (distinct)、排序 (order)、取部分数据 (limit+offset),等等操作,下面我们就将对这些运算一一展开讨论。

       当然,我们在处理这些运算的需求时,不能只是简单的实现功能,我们还需要考虑实现的效率和性能,因此原则上,我们会尽量利用数据库的计算能力,而集算器主要负责混合运算。不过,有时也需要由集算器负责几乎所有的运算,数据库仅仅负责存储数据。

 

2.    WHERE

       where 过滤的本质是通过比较计算,去除比较的结果是 false 的记录,因此 where 只作用于一条记录,不涉及记录之间的运算,也不需要考虑数据位于哪个数据库。比如,在前面的例子中,我们要统计出“一班”所有同学的“数学”成绩,单库中的 SQL 是这样的:

       SELECT 学生 ID, 成绩 FROM 学生成绩表 WHERE 科目 =’数学’ AND 班级 =‘一班’

       多库时,也只要将 where 子句直接写在 SQL 中,让各个数据库去并行处理过滤就可以了:

 

A

B

2

=A1.query("select 学生 ID, 成绩 from 学生成绩表   where 科目 =' 数学 'and 班级 =' 一班 ' ")

=B1.query("select   学生 ID, 成绩 from 学生成绩表 where 科目 =' 数学 'and   班级 =' 一班 ' ")

3

=A2 | B2

       我们也可以让集算器负责所有过滤运算,数据库仅存储数据。这时可以使用集算器的 select 函数(与 SQL 的 select 关键字不同)

 

A

B

2

=A1.query("select 学生 ID, 成绩, 科目, 班级 from 学生成绩表")

=B1.query("select   学生 ID, 成绩, 科目, 班级 from 学生成绩表")

3

=A2.select(科目 =="数学" && 班级 =="一班").new(学生 ID, 成绩)

=B2.select(科目 =="数学" && 班级 =="一班").new(学生 ID, 成绩)

4

=A3 | B3

       数据量较大时,同样也可以将序表换成游标,使用 conjx 函数进行连接:

 

A

B

2

=A1.cursor("select 学生 ID, 成绩 from 学生成绩表   where 科目 =' 数学 'and 班级 =' 一班 ' ")

=B1.cursor("select   学生 ID, 成绩 from 学生成绩表 where 科目 =' 数学 'and   班级 =' 一班 ' ")

3

=[A2, B2].conjx()

 

3.    ORDER BY 和 LIMIT OFFSET

       order by 是在结果集产生后才进行的处理。在上面的例子中,如果我们要按数学成绩排序,对于单数据库,只需要加上 order by 子句:

       SELECT 班级, 学生 ID, 成绩 FROM 学生成绩表 WHERE 科目 =’数学’ AND 班级 =‘一班’ ORDER BY 成绩

       而对于多数据库,可以让数据库先分别排序,然后由集算器归并有序数据。这样可以最大的发挥数据库与并行服务器的性能。

 

A

B

2

=A1.query("select 班级, 学生 ID, 成绩 from 学生成绩表   where 科目 =' 数学 'and 班级 =' 一班 'order by 成绩")

=B1.query("select   班级, 学生 ID, 成绩 from 学生成绩表 where 科目 =' 数学 'and 班级 =' 一班 'order by 成绩")

3

=[A2, B2].merge(成绩)

       也可以倒序排序,归并时在排序字段前加“-”(merge 函数可以不加“-”,不过按标准写法是加上的)

 

A

B

2

=A1.query("select 班级, 学生 ID, 成绩 from 学生成绩表   where 科目 =' 数学 'AND 班级 =' 一班 'order by 成绩 desc")

=B1.query("select   班级, 学生 ID, 成绩 from 学生成绩表 where 科目 =' 数学 'AND 班级 =' 一班 'order by 成绩 desc")

3

=[A2, B2].merge(- 成绩)

       当然也可以完全由集算器来排序:

 

A

B

2

=A1.query("select 班级, 学生 ID, 成绩 from 学生成绩表 where 科目 =' 数学 'AND

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值