加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql体系化之JOIN的语法简化

发布时间:2024-01-01 01:42:35 所属栏目:MySql教程 来源:DaWei
导读: 如何利用关联都涉及主键这个特征来简化JOIN的代码书写?

外键属性化
例子,设有如下两个表:

employee 员工表
id 员工编号
name 姓名
nationality 国籍
departm
如何利用关联都涉及主键这个特征来简化JOIN的代码书写?

外键属性化
例子,设有如下两个表:

employee 员工表
    id 员工编号
    name 姓名
    nationality 国籍
    department 所属部门

department 部门表
    id 部门编号
    name 部门名称
    manager 部门经理
employee表和department表的主键都是其中的id字段,employee表的department字段是指向department表的外键,department表的manager字段又是指向employee表的外键(因为经理也是个员工)。这是很常规的表结构设计。

首先要FROM employee用于获取员工信息,然后这个employee表要和department做JOIN获取员工的部门信息,接着这个department表还要再和employee表JOIN要获取经理的信息,这样employee表需要两次参与JOIN,在SQL语句中要为它起个别名加以区分,整个句子就显得比较复杂难懂。

如果我们把外键字段直接理解成它关联的维表记录,就可以换一种写法:
SELECT * FROM employee
WHERE nationality='USA' AND department.manager.nationality='CHN'
当然,这不是标准的SQL语句了。

外键属性化:这种对象式的理解方式即为外键属性化,显然比笛卡尔积过滤的理解方式要自然直观得多。外键表JOIN时并不会涉及到两个表的乘法,外键字段只是用于找到维键表中对应的那条记录,完全不会涉及到笛卡尔积这种有乘法特性的运算。

我们前面约定,外键关联时时维表中关联键必须是主键,这样,事实表中每一条记录的外键字段关联的维表记录就是唯一的,也就是说employee表中每一条记录的department字段唯一关联一条department表中的记录,而department表中每一条记录的manager字段也唯一关联一条employee表中的记录。这就保证了对于employee表中的每一条记录,department.manager.nationality都有唯一的取值,可以被明确定义。

但是,SQL对JOIN的定义中并没有主键的约定,如果基于SQL的规则,就不能认定与事实表中外键关联的维表记录有唯一性,有可能发生与多条记录关联,对于employee表的记录来讲,department.manager.nationality没有明确定义,就不能使用了。

事实上,这种对象式写法在高级语言(如C,Java)中很常见,在这类语言中,数据就是按对象方式存储的。employee表中的department字段取值根本就是一个对象,而不是编号。其实许多表的主键取值本身并没有业务意义,仅仅是为了区分记录,而外键字段也仅仅是为了找到维表中的相应记录,如果外键字段直接是对象,就不需要再通过编号来标识了。不过,SQL不能支持这种存储机制,还要借助编号。

我们说过外键关联是不对称的,即事实表和维表是不对等的,只能基于事实表去找维表字段,而不会有倒过来的情况。

同维表等同化
同维表的情况相对简单,还是从例子开始,设有两个表:

employee 员工表
    id 员工编号
    name 姓名
    salary 工资
    ...

manager 经理表
    id 员工编号
    allowance 岗位津贴
    ....
两个表的主键都是id,经理也是员工,两表共用同样的员工编号,经理会比普通员工多一些属性,另用一个经理表来保存。

现在我们要统计所有员工(包括经理)的总收入(加上津贴)。用SQL写出来还是会用到JOIN:
SELECT employee.id, employee.name, employy.salary+manager.allowance
FROM employee
LEFT JOIN manager ON employee.id=manager.id

而对于两个一对一的表,我们其实可以简单地把它们看成一个表:
SELECT id,name,salary+allowance
FROM employee

类似地,根据我们的约定,同维表JOIN时两个表都是按主键关联的,相应记录是唯一对应的,salary+allowance对employee表中每条记录都是唯一可计算的,不会出现歧义。这种简化方式称为同维表等同化。

同维表之间的关系是对等的,从任何一个表都可以引用到其它同维表的字段。

主子表关系是不对等的,不过两个方向的引用都有意义,上面谈了从主表引用子表的情况,从子表引用主表则和外键表类似。
我们改变对JOIN运算的看法,摒弃笛卡尔积的思路,把多表关联运算看成是稍复杂些的单表运算。这样,相当于把最常见的等值JOIN运算的关联消除了,甚至在语法中取消了JOIN关键字,书写和理解都要简单很多。

另外,目前这些简化语法仍然是示意性,需要在严格定义维度概念之后才能相应地形式化,成为可以解释执行的句子。
我们把这种简化的语法称为DQL(Dimensional Query Languange),DQL是以维度为核心的查询语言。我们已经将DQL在工程上做了实现,并作为润乾报表的DQL服务器发布出来,它能将DQL语句翻译成SQL语句执行,也就是可以在任何关系数据库上运行。
 

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章