Mysql体系化之JOIN的语法简化
发布时间:2023-12-23 16:49:16 所属栏目:MySql教程 来源:DaWei
导读: 如何利用关联都涉及主键这个特征来简化JOIN的代码书写?
外键属性化
例子,设有如下两个表:
employee 员工表
id 员工编号
name 姓名
nationality 国籍
departm
外键属性化
例子,设有如下两个表:
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语句执行,也就是可以在任何关系数据库上运行。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐