`
datamachine
  • 浏览: 163440 次
社区版块
存档分类
最新评论

集算器序表和SQL数据表的异同

    博客分类:
  • DB
阅读更多

  集算器序表和SQL数据表都是有结构的二维数据对象,都有记录、索引、主键的概念,都可以应用于结构化数据的计算。虽然都可以应用于结构化数据的计算,但两者的应用场景却有明显的区别,序表适合解决较复杂但数据量不是很大的计算问题,而数据表适合进行常规但可能数据量巨大的计算。

  两者的不同是由底层机制决定的。

  序表具有有序的特点,每条记录、每列数据都有确定的序号;序表支持显式集合,序表之间可以直接进行集合运算;序表也是泛型集合,其基本元素既可以是数值也可以是引用或者另一个集合。

  SQL数据表缺乏上述特点,但它对内外存透明,可以用一致的语法来访问内存、外存或混合数据。

  下面,我们将深入讨论两者的共同点和区别。

相同的基本功能

  集算器序表和SQL数据表都是有结构的二维数据对象,即以记录为基础,多条记录形成行式的二维表,二维表配合列名形成完整的数据结构。因为结构上大体相似,所以两者的基本用法区别不大。

  例1:查询对象中的数据。找到Freight大于100,并且是2013年以前的订单。

  SQL:SELECT * FROM Orders WHERE Freight > 100 AND OrderDate < ’1998-01-01′

  序表:= Orders.select(Freight > 100 && OrderDate < date(“1998-01-01″))

  注:本例使用的数据对象名为订单(Orders),后面还会用到客户(Customers)。

  例2:排序。将订单按EmployeeID正序排序,再按Freight逆序排序。

  SQL:SELECT * FROM Orders ORDER BY EmployeeID ,Freight DESC

  序表:=Orders.sort(EmployeeID,Freight:-1)

  例3:分组汇总。按员工汇总,对运货费求和,对订单计数。

  SQL:SELECT EmployeeID, COUNT(OrderID), SUM(Freight) FROM Orders GROUP BY EmployeeID

  序表:= Orders.groups(EmployeeID;sum(Freight),count(OrderID))

  例4:连接。将订单和客户这两个数据对象连接成新的数据对象,使用左连接,连接字段为CustomerID。

  SQL:Select * from Orders left join Customers on Orders.CustomerID =Customers.CustomerID

  序表:=join@1(Orders:, CustomerID;  Customers:, CustomerID)

  除了上述几种基本用法,集算器序表和SQL数据表在唯一值、计数、求和、平均、最大、最小值等算法上也非常相似,这里不再一一举例。

有序性的区别

  序表的记录集合是有序的,因此可以轻松解决和顺序有关的计算。SQL数据表缺乏序号及序号相关的访问方法,这使它在序运算上不够方便。

  例1:针对sales数据对象,计算每个月的销售额比上个月增长了百分之几。

  SQL:

    select salesAmount, salesMonth,

         (case when

    prev_price !=0 then ((salesAmount)/prev_price)-1

    else 0

    end) compValue

    from (select salesMonth, salesAmount,

    lag(salesAmount,1,0) over(order by salesMonth) prev_price

    from sales) t

  序表:

    sales.derive(salesAmount / salesAmount [-1]-1: compValue)

  比较:

  每个月的销售额和序无关,在序表和数据表中的表示方法一样,都是salesAmount。和序有关的是:上个月的销售额,即相对于当前记录的上一条记录中的salesAmount。序表有序,可以用salesAmount[-1]来直接表示上个月的销售额。SQL数据表无序,在SQL2003标准后添加了窗口函数补充了一些序运算功能,但仍然比较繁琐,需要用lag(salesAmount,1,0) over(order by salesMonth)这种复杂的方法来计算出上个月的销售额。

  序表还可以轻松表达相对区间,比如相对于当前月份的前两个月及后两个月共五个月的销售额,序表可以这样表达:salesAmount{-2,2}。在SQL中使用窗口函数也可以表达区间的汇总运算,但要麻烦得多。

  例2:针对sales数据表,找出每种产品里销售额最高的前10条的记录。

  SQL:

    select salesMan, product ,amount

    from ( select salesMan, product ,amount, rank() over (partition by product order by amount desc ) ranking from sales)

    where ranking <=10

  序表:

    = sales.group(product).(~.top(-amount;10))

  比较:

  实现本例最直观的思路是将数据按产品分组,然后再进行分组内的序运算,简单的方法是直接取组内amount最小的前十条记录,直观的方法是按照amount对组内数据逆序排序,再取组内序号是1到10的记录。

  序表对序运算支持良好,可以用top函数实现第一种算法(如例子中),也可以用sort函数和记录序号实现第二种算法,即:=sales.group(product).(~.sort(Amount:-1)).(~([to(10)]))。

  SQL数据表记录没有次序,必须先计算出一个序号或者可代替序号功能的字段,比如排名。上述例子的算法就是先计算出组内数据的排名,再取排名前十的记录。显而易见,SQL算法有点曲折,语法也难懂,要用到复杂的窗口函数over (partition by…… order by……),以及难以跟踪调试的子查询。

  相比之下,序表更加直接简便,也容易跟踪调试。比如程序员可以先写出=sales.group(product)这句代码进行测试,这句代码表示将数据分组,它可以独立运行并独立显示结果。如果分组结果符合预期,程序员可以继续加入第二段代码:对组内数据逆序排序,即.(~.sort(Amount:-1)),这里的“.”表示把前面的计算结果作为一个整体继续加工,“~”表示当前的组内数据,“-1”表示逆序。现在的代码是=sales.group(product).(~.sort(Amount:-1)),它仍然可独立运行并独立显示结果。观察或调试后,程序员可以加入第三段代码:取组内序号是1到10的记录,即.(~([to(10)]))。

  可以看到,序表的计算过程可以步步递进,在解决复杂的计算问题时简化计算防止出错。事实上,上述连续的三段代码可以写成逐步引用的三行代码,这可以更加清晰地分解计算目标:

  值得注意的是,SQL无法对数据先分组再执行有序计算,即使用临时表也无法实现,它必须将这两步合二为一,产生这一现象的原因是数据表不支持显式集合和泛型集合,语法表达能力较弱。

  另外,SQL使用的窗口函数虽然是ansi标准,但数据库厂商并未完全按标准实现,不同的数据库里写法也会不同,有些数据库根本不提供窗口函数。而序表的函数语法独立于数据源,不论哪种数据源(包括数据库、Txt文件、Excel文件、二进制文件等),使用序表计算时都无需修改代码。

显式集合的区别

  SQL有集合的概念,但不提供显式的集合,不能作为独立的变量存在,只能借助临时表来实现集合运算。而序表是真正的显式集合,可以实现集合运算。

  例子:针对Contract数据对象进行计算,假设业务上将订购数量大于40的合同称为大合同,单价大于2000的合同称为重要合同,请找出既是大合同又是重要合同的当年合同,以及除此之外的其他合同。

  SQL

    select SellDate,Quantity,Amount,Client from Contract where to_char(SellDate,’yyyy’)=’2014′ and quantity>=40 and AMOUNT>=2000

    select SellDate,Quantity,Amount,Client from Contract where not(to_char(SellDate,’yyyy’)=’2014′ and quantity>=40 and AMOUNT>=2000)

  序表

    =thisYear= Contract.select(year(SellDate)=2014)

    =big= Contract.select(Quantity>40)

    =importance = Contract.select(AMOUNT>2000)

    =answer=thieYear^big^ importance

    =others= Contract\answer

  比较分析

  既是大合同又是重要的当年合同,这是比较典型的自然思考方式,使用交集运算最为直观。如果将大合同定义为big,重要合同定义为importance,当年的合同定义为thisYear,那我们可以很容易写出伪代码:big∩importance∩thiYear。序表是显式集合,可以很直观地表达等价的算法,即:thieYear^big^ importance。SQL不能用集合变量来表示,因此只能寻求其他方式,比如转换为布尔条件来表示,即例子中的: to_char(SellDate,’yyyy’)=’2014′ and quantity>=40 and AMOUNT>=2000。

  第一问比较简单,因此两者的开发难度并没有太大的区别。随着问题的深入,两者的区别才会明显起来。

  第二问:“除此之外的其他合同”,这也是典型自然思考方式,使用差集可以一步算出。序表的算法是:Contract\answer,非常直观。使用布尔条件,SQL也可以计算出答案,但表达式的写法和业务描述相差甚远,即:not(to_char(SellDate,’yyyy’)=’2014′ and quantity>=40 and AMOUNT>=2000)。

  SQL也可以用集合运算来解答,算法也很直观,但是因为数据表不能用集合变量来表示,代码会显得非常冗长:

    (select SellDate,Quantity,Amount,Client from Contract)

    minus

    (Select select SellDate,Quantity,Amount,Client from Contract from(

    (select SellDate,Quantity,Amount,Client from Contract where to_char(SellDate,’yyyy’)=’2012′)

    Intersect

    (select SellDate,Quantity,Amount,Client from Contract where quantity>=40)

Intersect

(select SellDate,Quantity,Amount,Client from Contract where AMOUNT>=2000))

  因为代码太冗长,所以很多人宁可使用布尔条件来间接实现集合运算。

  当然,很多情况下数据表使用集合运算会比布尔条件更加方便,比如多个物理表之间的集合运算,或多层子查询之间的集合运算。这种情况下,将集合运算转化为布尔条件的代价就太高了,程序员必须接受冗长的集合运算。

泛型集合的区别

  序表是泛型集合,除了存储实体数据,还可以存储指向关联数据的引用,这就使序表可以通过直观的对象引用实现关联计算。数据表只能存储实体数据,需要用复杂的关联语句才能完成等价的计算。

  例子

  请计算获得总裁奖的部门经理们,其下属的年度优秀员工们都有谁。这里涉及两个数据对象:department和employee,其中,department的deptName字段和employee的empDept是一对一的关系,department中的manager字段和employee中的empName也是一对一的关系。另外,总裁奖的代码是PA;年度优秀员工的代码是EOY。

  SQL

    SELECT A.*

    FROM employee A,department B,employee C

    WHERE A.empDept=B.deptName AND B.manager=C.empName AND A.empHonor=‘EOY’ AND C.empHornor=‘PA’

  序表:

    employee.select(empHonor: “EOY”,empDept.manager.empHornor:”PA”)

  比较分析

  SQL的解法无疑是正确的,但其中的关联语句比较复杂,普通程序员理解费力。序表的解法比较直观,empHonor:”EOY”是条件之一:“年度优秀员工们都有谁”,而empDept.manager.empHornor表示员工的“所属部门.该部门的经理.该经理的获奖情况”,显然,这个值为PA就符合题目中的条件二:“获得总裁奖的部门经理们”。这就是对象引用。

  对象引用允许程序员使用“.”操作符来引用相关数据,这可以将业务中的关联关系直观地翻译为计算机语言,可以方便地表达多层关系,可以直观地进行关联计算。

对内外存透明的区别

  SQL

  SQL数据表因为不支持泛型和集合数据,内存中的数据写到外存时不会丢失信息,因而具有对内外存运算的透明性。首次访问数据表时,数据通常来自外存;之后再访问同样的数据表时,数据就可以来自内存缓存;对于数据量较大的数据表,其一部分数据来自外存,而另一部分会来自于内存。无论数据是来自于内存还是外存,无论数据量是大还是小,数据表的访问语法并无区别,程序员无需为此书写不同的SQL语句。

  序表

  序表支持了泛型(特别是引用)和集合数据,内存中的数据写到外存时会丢失信息,不能再读入,这导致其运算无法对内外存透明。序表是纯内存数据对象,所能计算的数据量受到内存限制,不能太大;如果数据量较大,那就应当使用游标(集算器的另一种数据对象)来进行外存计算,而游标和序表的语法是不同的;如果想提高性能或进行业务逻辑复杂的计算,程序员还必须将数据在游标和序表之间进行转换。

  比较

  序表对内外存不透明,程序员需要书写不同的代码来适应内存、外存或混合计算,还需要为将来数据量的增长而修改代码,因此前期设计和后期维护的工作量较大。而SQL数据表对内外存透明,程序员只需书写一套代码就能适应不同规模的数据,设计和维护的工作量较小。

  通过上述比较分析我们可以看出:数据有序、显示集合、泛型集合,序表的这些特点使它可以轻松解决和顺序有关的复杂问题,可以简化集合运算的复杂度,可以用直观的对象引用来处理复杂的多表关联。而SQL数据表对内外存透明,代码通用性更好。 

  • 大小: 10.1 KB
0
0
分享到:
评论

相关推荐

    首届中文NL2SQL挑战赛数据集

    【首届中文NL2SQL挑战赛数据集】是一个专注于自然语言处理与数据库查询的竞赛,其主要目标是将中文的自然语言问题(NL)转化为结构化的SQL(Structured Query Language)查询,以此来解决表格数据的问题。...

    全球大洲国家地区SQL数据表含中英文名称以及地区代码和关联ID

    标题中的“全球大洲国家地区SQL数据表含中英文名称以及地区代码和关联ID”指出,这个资源是一个SQL数据表,包含了全球所有大洲、国家和地区的相关信息。这些信息不仅有中文名称,也有英文名称,这表明数据表设计时...

    SQL数据生成器

    SQL数据生成器是一种工具,主要用于在数据库环境中快速创建和填充大量的测试或示例数据。它对于软件开发、性能测试、数据库设计验证等场景非常有用。通过使用这种工具,用户可以自定义数据规则,生成符合特定业务...

    数据库系统概念表SQL数据

    在书中的例题和习题中,你会接触到如何使用SQL语句进行数据操作,包括SELECT语句用于查询,INSERT语句用于插入新数据,UPDATE语句用于修改现有数据,以及DELETE语句用于删除不需要的数据。 表是数据库中的核心组成...

    spider 数据集——Text-to-SQL

    一个大规模复杂跨域语义解析和 text-to-SQL 数据集 Spider。该数据集由 11 名耶鲁大学学生标注,包含 10181 个问题和 5693 个独特的复杂 SQL 查询、200 个具备多个表的数据库,覆盖 138 个不同领域。

    全国四级地区(省市县)数据表sql

    全国四级地区(省市县)数据表sql

    sqlserver 循环临时表插入数据到另一张表

    sqlserver 循环临时表插入数据到另一张表 -- 声明变量 DECLARE @SupCode as varchar(100), @ProdCode as varchar(50), @PackLayer as varchar(50), @CodeStatus as varchar(50), @ProductId as varchar(50), @...

    查询sql数据库每张表包含的数据条数

    查询sql数据库每张表包含的数据条数 sql server 数据库 表 数据量

    省市区管理sql数据表设计、以及全国省市区全部最新数据

    省市区管理sql数据表设计、以及全国省市区全部最新数据,省市区管理sql数据表设计、以及全国省市区全部最新数据,省市区管理sql数据表设计、以及全国省市区全部最新数据,

    SQL SERVER脚本表结构和数据导出工具

    对于初学者来说,SSMS的脚本功能是一个很好的起点,而熟悉T-SQL和BCP则能更好地掌控数据操作。对于复杂场景,可以考虑使用专门的数据库迁移或管理工具,如SqlDataToScript这样的工具,它们通常提供了更多定制化的...

    sqlserver表数据插入到oracle表中的一种实现方式(表结构相同)

    最近由于应急,需要把sqlserver表和表数据在oracle中复制一份。表结构的创建比较简单,但是表的数据量太大,一时也想不到怎么把sqlserver表数据复制到oracle中,于是请教公司主管,用存储过程实现可以查询出所有数据...

    关联表数据集SQL查询

    关联表数据集SQL查询

    数据库表数据转为insert sql语句

    Data row to insert sql是一个小的工具软件,可以将数据库表中指定数据转换成相应的insert sql语句。目前支持的数据库类型为oracle,db2,ms sql server。 目前还有一些缺陷,还有待完善,具体如下: 1、对ms sql ...

    本人收集的所有SQL数据集(也是本人从事这么多年的软件开发)

    标题中的“所有SQL数据集”指的是一个集合,包含了与SQL(结构化查询语言)相关的各种数据和示例,这是数据库管理和软件开发中的基础工具。SQL是用于管理关系数据库的标准编程语言,包括创建、更新、查询和操作数据...

    SQL Server表数据导出成Insert语句的工具

    "SQL Server表数据导出成Insert语句的工具"是一个专门为此目的设计的应用程序,它能帮助数据库管理员和开发人员高效地生成插入语句,以便在其他数据库中重建同样的数据结构和内容。 1. **数据导出的需求**:在不同...

    Excel VBA+SQL 数据管理与应用模板开发.rar

    在Excel VBA(Visual Basic for Applications)和SQL(Structured Query Language)的结合使用中,我们可以创建高效、自动化的数据管理与应用模板。这样的模板对于处理大量数据和执行复杂的计算任务非常有用,尤其在...

    sql-server中复制数据库某一个表到另一个数据库中

    在SQL Server环境中,有时我们需要将一个数据库中的某个表复制到另一个数据库中,这可能是为了备份、数据迁移或创建测试环境等目的。根据提供的标题、描述和部分代码内容,我们可以整理出一套较为完整的操作流程和...

    百万级数据在Excel和Sql数据库之间相互导入、导出

    3. **T-SQL语句**:使用Transact-SQL(T-SQL)可以直接从Excel文件导入数据到SQL Server表,或者将数据导出到CSV文件,再由Excel打开。例如,BULK INSERT命令适用于大批量导入,而SELECT INTO语句可用于创建新表并...

    sql server 数据表结构导出

    导出数据的表名称,主键,长度,默认值说明,创建时间等信息内容

    通过解析sql语句获取表血缘关系项目

    "通过解析SQL语句获取表血缘关系项目"是一个针对数据库管理的实用技术,主要用于理解和跟踪数据的来源与流向,即血缘关系。血缘关系追踪在数据质量、合规性、审计和数据治理中扮演着关键角色。以下是关于这个主题的...

Global site tag (gtag.js) - Google Analytics