MySQL数据库学习笔记(六)----MySQL多表查询以外键、表链接、子查询、索引

本章主要内容:html

  • 1、外键
    面试

  • 2、表链接
    sql

  • 3、子查询
    数据库

  • 4、索引ide

1、外键:函数

  • 一、什么是外键工具

  • 二、外键语法 性能

  • 三、外键的条件学习

  • 四、添加外键ui

  • 五、删除外键

一、什么是外键:

主键是惟一标识一条记录,不能有重复的,不容许为空,用来保证数据完整性

外键:是另外一表的主键, 外键能够有重复的, 能够是空值,用来和其余表创建联系用的。因此说,若是谈到了外键,必定是至少涉及到两张表。例以下面这两张表:

上面有两张表:部门表(dept)、员工表(emp)。Id=Dept_id,而Dept_id就是员工表中的外键:由于员工表中的员工须要知道本身属于哪一个部门,就能够经过外键Dept_id找到对应的部门,而后才能找到部门表里的各类字段信息,从而让两者相关联。因此说,外键必定是在从表中建立,从而找到与主表之间的联系;从表负责维护两者之间的关系。

咱们先经过以下命令把部门表和职工表建立好,方便后面的举例:

复制代码

create table department(
            id int primary key auto_increment,
            name varchar(20) not null,
            description varchar(100)
);create table employee(
            id int primary key auto_increment,
            name varchar(10) not null,
            gender varchar(2) not null,
            salary float(10,2),
            age int(2),
            gmr int,
            dept_id int);

复制代码

而后把两张表的数据填好,显示效果以下:

部门表:

员工表:

 

二、外键的使用须要知足下列的条件:(这里涉及到了InnoDB的概念)

1. 两张表必须都是InnoDB表,而且它们没有临时表。

注:InnoDB是数据库的引擎。MySQL常见引擎有两种:InnoDB和MyISAM,后者不支持外键。

2. 创建外键关系的对应列必须具备类似的InnoDB内部数据类型。

3. 创建外键关系的对应列必须创建了索引。

4. 假如显式的给出了CONSTRAINT symbol,那symbol在数据库中必须是惟一的。假如没有显式的给出,InnoDB会自动的建立。

面试题:你的数据库用什么存储引擎?区别是?

答案:常见的有MyISAM和InnoDB。

MyISAM:不支持外键约束。不支持事务。对数据大批量导入时,它会边插入数据边建索引,因此为了提升执行效率,应该先禁用索引,在彻底导入后再开启索引。

InnoDB:支持外键约束,支持事务。对索引都是单独处理的,无需引用索引。

 

三、添加外键的语法:

有两种方式:

  • 方式一:在建立表的时候进行添加

  • 方式二:表已经建立好了,继续修改表的结构来添加外键

【方式一】在建立表的时候进行添加

复制代码

[CONSTRAINT symbol] FOREIGN KEY [id] (从表的字段1)REFERENCES tbl_name (主表的字段2)[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}][ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}

复制代码

上面的代码是同一行,中括号里的内容是可选项。

解释以下:

CONSTRAINT symbol:能够给这个外键约束起一个名字,有了名字,之后找到它就很方便了。若是不加此参数的话,系统会自动分配一个名字。

FOREIGN KEY:将从表中的字段1做为外键的字段。

REFERENCES:映射到主表的字段2。

ON DELETE后面的四个参数:表明的是当删除主表的记录时,所作的约定。

  • RESTRICT(限制)若是你想删除的那个主表,它的下面有对应从表的记录,此主表将没法删除。

  • CASCADE(级联)若是主表的记录删掉,则从表中相关联的记录都将被删掉。

  • SET NULL:将外键设置为空。

  • NO ACTION:什么都不作。

注:通常是RESTRICT和CASCADE用的最多。

 

【方式二】表已经建立好了,继续修改表的结构来添加外键

咱们在第一段中内容中已经将表建好了,数据也填充完了,如今来给从表(员工表)添加外键,让它与主表(部门表)相关联。代码举例以下:

ALTER TABLE employee ADD FOREIGN KEY(dept_id) REFERENCES department(id);

代码解释:

ALTER TABLE employee:在从表employee中进行操做;

ADD FOREIGN KEY(dept_id):将从表的字段dept_id添加为外键;

REFERENCES department(id):映射到主表department当中为id的字段。

运行上方代码后,咱们经过navicat来看一下外键有没有添加成功:

上图中,选中表employee,单击红框部分的“设计表”按钮,界面以下:

上图中就能够看到咱们新建的外键了,并且系统默认给这个外键起了个名字:employee_ibfk_1。默认规则是RESTRICT。紧接着来给外键设置值:

上图中,咱们打开员工表,而后给外键设置值,1表明宣传部,2表明秘书部。

而后咱们回到主表(部门表),此时若是想删除id为1的宣传部,会弹出以下提示:(由于外键的默认规则为RESTRICT)

四、删除外键:(经过sql语句的方式)

咱们在navicat中能够经过图形界面的方式删除外键,也能够经过sql语句来删除。

(1)获取外键名:

若是在命令行中不知道外键的名字,能够经过查看表的定义找出外键的名称:

show create table emp;

运行效果以下:

其实咱们在表的信息中也能够看到:(注意书写命令的格式)

(2)删除外键:

alter table emp drop foreign key 外键名;

 

2、表链接(join)

咱们如下面的两张表举例:做为本段内容的例子

department部门表:

employee员工表:

其中,外键对应关系为:employee.dept_id=department.id。employee.leader中的数字的含义为:生命壹号的leader是生命二号,生命二号没有leader,生命叁号的leader是生命壹号。

一、内链接:只列出匹配的记录

语法:

SELECT … FROM join_table[INNER] JOIN join_table2 
[ON join_condition]WHERE where_definition

解释:只列出这些链接表中与链接条件相匹配的数据行。INNER能够不写,则默认为内链接。[ON join_condition]里面写的是链接的条件。

举例:

select e.name,d.name from employee e inner join department d on e.dept_id=d.id;

等价于:

select e.name,d.name from employee e,department d where e.dept_id=d.id;

运行效果:

二、外链接:

外链接分类:

  • 左外链接(LEFT [OUTER] JOIN)

  • 右外链接(RIGHT [OUTER] JOIN)

  • 全外链接(FULL [OUTER] JOIN)  注:MySQL5.1的版本暂不支持

语法:

复制代码

SELECT … FROM join_table1

(LEFT | RIGHT | FULL) [OUTER] JOIN join_table2ON join_conditionWHERE where_definition

复制代码

解释:

不只列出与链接条件(on)相匹配的行,还列出左表table1(左外链接)、或右表table2(右外链接)、或两个表(全外链接)中全部符合WHERE过滤条件的数据行。通常都是用左链接或者外链接。

其中,[OUTER]部分能够不写,(LEFT | RIGHT | FULL)部分要写其中一个。

二、1左外链接:左表列出所有,右表只列出匹配的记录。

举例:

二、2右外链接:右表列出所有,左表只列出匹配的记录。

举例:

三、交叉链接:

语法:

SELECT … FROM join_table1 CROSS JOIN join_table2;

没有ON子句和WHERE子句,它返回的是链接表中全部数据行的笛卡尔积

笛卡尔积举例:假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}

其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

等价于:(荐)

SELECT … FROM table1, table2;

举例:

四、自链接参与链接的表都是同一张表。(经过给表取别名虚拟出两张表)

注:很是重要,在JavaWeb中的目录树中用的特别多。

举例:查询出员工姓名和其leader的姓名(相似于求节点及其父节点)

咱们来详细解释一下上面的代码。对于同一张employee表,咱们把e1做为员工表,e2做为领导表。首先把所有的员工列出来(基于左外链接),而后找到咱们所须要的条件:员工的经理id(e1.leader)等于经理表的id(e2.id)

 

举例:查询出全部leader的姓名。

分析的道理同上。

其实,上面的两个查询结果都是下面这个查询结果的一部分:

 

3、子查询:

做用:某些状况下,当进行查询的时候,须要的条件是另一个select 语句的结果,这个时候,就要用到子查询。

定义:为了给主查询(外部查询)提供数据而首先执行的查询(内部查询)被叫作子查询。也就是说,先执行子查询,根据子查询的结果,再执行主查询

关键字:用于子查询的关键字主要包括 IN、NOT IN、EXIST、NOT EXIST、=、<>等(符号“<>”的意思是:不等于)。

备注:MySQL从4.1开始才支持SQL的子查询。通常说子查询的效率低于链接查询(由于子查询至少须要查询两次,即至少两个select语句。子查询嵌套也多,性能越低)。表链接均可以用子查询替换,但反过来讲却不必定。

咱们一下面的这张员工表举例:

一、举例:查询月薪最高的员工的名字

上面的例子中,咱们就是先经过聚合函数查出最高的月薪,而后根据这个值查出对应员工的名字。

二、举例:查询出每一个部门的平均月薪

上面的例子中,先将部门进行分类(前提是部门不能为空),而后分别单独求出各种中的薪水平均值。

注:这里咱们没有用到子查询,由于比较麻烦。

三、举例:查询月薪比平均月薪高的员工的名字(咱们知道,总体的平均工资是250)

疑问:若是要查询比部门平均工资高的员工,该怎么写呢?下面的这种写法是错误的:

 

4、索引

主要内容以下:

  • 一、索引的概念

  • 二、普通索引

  • 三、惟一索引

  • 四、主键索引

  • 五、全文索引

  • 六、删除、禁用索引

  • 七、设计索引的原则

关于索引,推荐的学习连接:

http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html(大牛)

http://blog.csdn.net/cuidiwhere/article/details/8452997

http://www.cnblogs.com/cq-home/p/3482101.html

 

一、索引的概念:

索引是数据库中用来提升查询性能的最经常使用工具。

全部MySQL列类型均可以被索引,对相关列使用索引是提升SELECT操做性能的最佳途径。索引用来快速地寻找那些具备特定值的记录,全部MySQL索引都以B-树的形式保存。

在使用如下操做符时,都会用到相关列上的索引:

  • >、<、>=、<=、<>、IN、 BETWEEN

  • LIKE 'pattern'(pattern不能以通配符开始,即通配符不能放前面,即便放在了前面,索引也无效)

注:索引的值由于不断改变,因此是它须要维护的。若是数据量较少,建议不用索引。

二、normal普通索引(第一种索引)

  • 方式一:直接建立索引:

语法:

CREATE INDEX 索引名 ON 表名(列名[(length)]…);

举例:

而后,咱们在表中能够看到新建立的索引:(咱们能够在这个navicat的可视化界面中修改索引类型)

 

  • 方式二:修改表时添加索引

语法:

ALTER TABLE 表名 ADD INDEX [索引名] (列名[(length)]…);

 

  • 方式三:建立表的时候指定索引:

CREATE TABLE 表名 ( 表名 ([...],INDEX [索引名] (列名[(length)]…);

注意:若是要建立索引的列的类型是CHAR、VARCHAR类型,length能够小于字段实际长度;若是是BLOB和TEXT类型,必须指定length。

 

三、unique 惟一索引:(第二种索引)

这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的全部值都必须惟一。例如能够将×××号做为索引。

建立方式和上方的普通索引相似。即:将普通索引的“index”改成“unique index”。

 

四、主键索引(一种特殊的惟一索引)

主键是一种特殊的惟一索引,通常在建立表的时候指定。在 MYSQL 中,当你创建主键时,主键索引同时也已经创建起来了,没必要重复设置

记住:一个表只能有一个主键,也即只有一个主键索引。

 

五、FULLTEXT全文索引:(第三种索引)

MySQL从3.2版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。

MySQL5.0版本只有MyISAM存储引擎支持FULLTEXT,而且只限于CHAR、VARCHAR和TEXT类型的列上建立。

注:全文索引维护起来很吃力,因此了解便可。

建立方式和上方的普通索引相似。即:将普通索引的“index”改成“fulltext index”

 

六、删除、禁用索引:

通常使用“删除”,不使用“禁用”。

删除索引:

语法:

DROP INDEX 索引名 ON 表名

对于MyISAM表在作数据大批量导入时,它会边插入数据边建索引。因此为了提升执行效率,应该先禁用索引,在彻底导入后,再开启索引。而InnoDB表对索引都是单独处理的,无需禁用索引。

禁用索引:

ALTER TABLE 表名 DISABLE KEYS;

打开索引:

ALTER TABLE 表名 ENABLE KEYS;

 

七、设计索引的原则:

  • 最适合索引的列是出如今WHERE子句中的列,或链接子句(on语句)中指定的列,而不是出如今SELECT后的列。

  • 索引列的值中,不相同的数目越多,索引的效果越好。

  • 使用短索引:对于CHAR和VARCHAR列,只用它的一部分来建立索引,能够节省索引空间,也会使查询更快捷。

如:CREATE INDEX part_of_name ON employees(name(10));  这个句子中指定的length长度为10,就是使用短索引,也就是说取name的前十个字符。

  • 利用最左前缀。

  • 根据搜索的关键字创建多列索引。

  • 不要过分索引。维护索引须要成本。

相关文章
相关标签/搜索