外键约束

如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表。

外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作。外键主要用来保证数据的完整性和一致性。

两个表必须是InnoDB表,MyISAM表暂时不支持外键。

外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以。

创建外键

#每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任

#主表
CREATE TABLE ClassCharger(
id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean -- show create table ClassCharger: tinyint(1)
); INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
("丹丹",14,0),
("歪歪",22,0),
("姗姗",20,0),
("小雨",21,0); #子表
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT, --切记:作为外键一定要和关联主键的数据类型保持一致
-- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id) #创建关联 ) ENGINE=INNODB; INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
("alvin2",4),
("alvin3",1),
("alvin4",3),
("alvin5",1),
("alvin6",3),
("alvin7",2); DELETE FROM ClassCharger WHERE name="冰冰";
INSERT student (name,charger_id) VALUES ("yuan",1);
-- 删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的; -----------增加外键和删除外键---------
ALTER TABLE student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
ALTER TABLE student DROP FOREIGN KEY abc;

INNODB支持的ON语句

--外键约束对子表的含义:   如果在父表中找不到候选键,则不允许在子表上进行insert/update
--外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对
-- 应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的
-- on update/on delete子句 -----------------innodb支持的四种方式---------------------------------------
-----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录
-----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除-------- FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE ------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null
-- 要注意子表的外键列不能为not null FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL ------Restrict方式 :拒绝对父表进行删除更新操作(了解)
------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键
-- 进行update/delete操作(了解)

多表查询

准备表

-- 准备两张表
-- company.employee
-- company.department create table employee(
emp_id int auto_increment primary key not null,
emp_name varchar(50),
age int,
dept_id int
); insert into employee(emp_name,age,dept_id) values
('A',19,200),
('B',26,201),
('C',30,201),
('D',24,202),
('E',20,200),
('F',38,204); create table department(
dept_id int,
dept_name varchar(100)
); insert into department values
(200,'人事部'),
(201,'技术部'),
(202,'销售部'),
(203,'财政部'); mysql> select * from employee;
+--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | A | 19 | 200 |
| 2 | B | 26 | 201 |
| 3 | C | 30 | 201 |
| 4 | D | 24 | 202 |
| 5 | E | 20 | 200 |
| 6 | F | 38 | 204 |
+--------+----------+------+---------+
6 rows in set (0.00 sec) mysql> select * from department;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 200 | 人事部 |
| 201 | 技术部 |
| 202 | 销售部 |
| 203 | 财政部 |
+---------+-----------+
4 rows in set (0.01 sec)

连接查询

1、迪尔卡积查询:这种查询本身是没有意义的

mysql> SELECT * FROM employee,department;

--        select employee.emp_id,employee.emp_name,employee.age,
-- department.dept_name from employee,department; +--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 1 | A | 19 | 200 | 201 | 技术部 |
| 1 | A | 19 | 200 | 202 | 销售部 |
| 1 | A | 19 | 200 | 203 | 财政部 |
| 2 | B | 26 | 201 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技术部 |
| 2 | B | 26 | 201 | 202 | 销售部 |
| 2 | B | 26 | 201 | 203 | 财政部 |
| 3 | C | 30 | 201 | 200 | 人事部 |
| 3 | C | 30 | 201 | 201 | 技术部 |
| 3 | C | 30 | 201 | 202 | 销售部 |
| 3 | C | 30 | 201 | 203 | 财政部 |
| 4 | D | 24 | 202 | 200 | 人事部 |
| 4 | D | 24 | 202 | 201 | 技术部 |
| 4 | D | 24 | 202 | 202 | 销售部 |
| 4 | D | 24 | 202 | 203 | 财政部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| 5 | E | 20 | 200 | 201 | 技术部 |
| 5 | E | 20 | 200 | 202 | 销售部 |
| 5 | E | 20 | 200 | 203 | 财政部 |
| 6 | F | 38 | 204 | 200 | 人事部 |
| 6 | F | 38 | 204 | 201 | 技术部 |
| 6 | F | 38 | 204 | 202 | 销售部 |
| 6 | F | 38 | 204 | 203 | 财政部 |
+--------+----------+------+---------+---------+-----------+

2、内连接

-- 查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。
select * from employee,department where employee.dept_id = department.dept_id;
--select * from employee inner join department on employee.dept_id = department.dept_id;(推荐使用方法) +--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技术部 |
| 3 | C | 30 | 201 | 201 | 技术部 |
| 4 | D | 24 | 202 | 202 | 销售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
+--------+----------+------+---------+---------+-----------+

3、外连接

--(1)左外连接:在内连接的基础上增加左边有右边没有的结果

 select * from employee left join department on employee.dept_id = department.dept_id;

     +--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技术部 |
| 3 | C | 30 | 201 | 201 | 技术部 |
| 4 | D | 24 | 202 | 202 | 销售部 |
| 6 | F | 38 | 204 | NULL | NULL |
+--------+----------+------+---------+---------+-----------+ --(2)右外连接:在内连接的基础上增加右边有左边没有的结果 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id; +--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技术部 |
| 3 | C | 30 | 201 | 201 | 技术部 |
| 4 | D | 24 | 202 | 202 | 销售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| NULL | NULL | NULL | NULL | 203 | 财政部 |
+--------+----------+------+---------+---------+-----------+ --(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果 -- mysql不支持全外连接 full JOIN
-- mysql可以使用此种方式间接实现全外连接 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id
UNION
select * from employee LEFT JOIN department on employee.dept_id = department.dept_id; +--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
| 1 | A | 19 | 200 | 200 | 人事部 |
| 2 | B | 26 | 201 | 201 | 技术部 |
| 3 | C | 30 | 201 | 201 | 技术部 |
| 4 | D | 24 | 202 | 202 | 销售部 |
| 5 | E | 20 | 200 | 200 | 人事部 |
| NULL | NULL | NULL | NULL | 203 | 财政部 |
| 6 | F | 38 | 204 | NULL | NULL |
+--------+----------+------+---------+---------+-----------+ -- 注意 union与union all的区别:union会去掉相同的纪录

4、复合条件连接查询

-- 查询员工年龄大于等于25岁的部门

    SELECT DISTINCT department.dept_name
FROM employee,department
WHERE employee.dept_id = department.dept_id
AND age>25; --以内连接的方式查询employee和department表,并且以age字段的升序方式显示 select employee.emp_id,employee.emp_name,employee.age,department.dept_name
from employee,department
where employee.dept_id = department.dept_id
order by age asc;

5、子查询(嵌套查询)

-- 子查询是将一个查询语句嵌套在另一个查询语句中。
-- 内层查询语句的查询结果,可以为外层查询语句提供查询条件。
-- 子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
-- 还可以包含比较运算符:= 、 !=、> 、<等 -- 1. 带IN关键字的子查询 ---查询employee表,但dept_id必须在department表中出现过 select * from employee
where dept_id IN
(select dept_id from department); +--------+----------+------+---------+
| emp_id | emp_name | age | dept_id |
+--------+----------+------+---------+
| 1 | A | 19 | 200 |
| 2 | B | 26 | 201 |
| 3 | C | 30 | 201 |
| 4 | D | 24 | 202 |
| 5 | E | 20 | 200 |
+--------+----------+------+---------+
5 rows in set (0.01 sec) -- 2. 带比较运算符的子查询
-- =、!=、>、>=、<、<=、<> -- 查询员工年龄大于等于25岁的部门
select dept_id,dept_name from department
where dept_id IN
(select DISTINCT dept_id from employee where age>=25); -- 3. 带EXISTS关键字的子查询 -- EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
-- 而是返回一个真假值。Ture或False
-- 当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询 select * from employee
WHERE EXISTS
(SELECT dept_name from department where dept_id=203); --department表中存在dept_id=203,Ture select * from employee
WHERE EXISTS
(SELECT dept_name from department where dept_id=205); -- Empty set (0.00 sec) ps: create table t1(select * from t2);

Linux-数据库3的更多相关文章

  1. mysql for linux 数据库的安装过程

    mysql for linux 数据库的安装过程 l  安装版本:mysql-advanced-5.6.12-linux-glibc2.5-x86_64.tar.gz ,此版本是绿色版本,只需要将其解 ...

  2. 使用c语言实现linux数据库的操作

    前言:上一篇讲解了linux下使用命令行操作数据库,这篇继续讲解怎么使用c语言实现linux数据库的操作. 使用c语言实现环境搭建:既然我们要使用c语言实现linux数据库操作,那么首先我们得先把数据 ...

  3. linux数据库备份

    linux数据库备份 服务端启用二进制日志 如果日志没有启开,必须启用binlog,要重启mysql,首先,关闭mysql,打开/etc/my.cnf,加入以下几行: [mysqld] log-bin ...

  4. DELPHI10.2的LINUX数据库开发环境配置

    DELPHI10.2的LINUX数据库开发环境配置 ubuntu使用firedac访问mysql1.安装mysql-client包sudo apt-get install mysql-client m ...

  5. Linux数据库的导入导出

    Linux数据库的导入导出 1.导入数据库 mysql -u username -p test < /home/data/test.sql 说明:username是数据库用户名,test为目标数 ...

  6. linux数据库常用指令

    linux数据库环境搭建好之后,我们就可以创建数据库了,如果不是 很了解linux数据库环境搭建的话,可以到看看我上一篇文章linux数据库环境搭建 首先我们来创建一个数据库:使用指令sqlite3 ...

  7. linux数据库

    sudo apt-get install mysql-server ---------Centos7下安装mysql 开始-------------下载mysql的repo源# yum install ...

  8. 讲解Linux数据库安装

    学习了linux这门课之后,就开始实践过程了,这样比较记得牢固,学以致用. 有了基本的命令,就可以试着安装数据库了. 企业环境 需要安装VMWare ESXi虚拟机,然后再在里面新建虚拟机. 镜像vm ...

  9. kali linux 数据库分析工具简述

    bbqsql SQL盲注可能很难被利用. 当可用的工具工作时,它们运行良好,但是当它们不工作时,您必须编写自定义的东西. 这是耗时且乏味的. BBQSQL可以帮助你解决这些问题. BBQSQL是一个用 ...

  10. Linux数据库的创建 导入导出 以及一些基本指令

    首先linux 下查看mysql相关目录 查看 mysql 的安装路径 执行查询 SQL mysql>show variables like '%dir%'; datadir 就是数据路径 确定 ...

随机推荐

  1. Codeforces 221 E. Little Elephant and Shifts

    E. Little Elephant and Shifts time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  2. 2-sat基础题 BZOJ 1823

    http://www.lydsy.com/JudgeOnline/problem.php?id=1823 1823: [JSOI2010]满汉全席 Time Limit: 10 Sec  Memory ...

  3. 不修改代码优化 ASP.NET 网站性能的一些方法

    本文将介绍一些方法用于优化ASP.NET网站性能,这些方法都是不需要修改程序代码的.它们主要分为二个方面:1. 利用ASP.NET自身的扩展性进行优化.2. 优化IIS设置. 配置OutputCach ...

  4. 【BZOJ】1901: Zju2112 Dynamic Rankings

    [题意]带修改的查询区间第k小 [算法]树状数组套可持久化线段树 [题解]对于树状数组上的每个节点,维护可持久化权值线段树(节点为权值),从而达到查询前缀和的目的. 对于每次修改,在待修改线段树基础上 ...

  5. https://segmentfault.com/bookmark/1230000008276077

    https://segmentfault.com/bookmark/1230000008276077

  6. OGG相关操作

    参数文件详解: 1)truncate ogg 进程: Manager进程:manager进程是配置在源端和目标端 Extract(抽取)进程:部署在源端,用于捕获数据表或者日志中的数据文件: Pump ...

  7. openjudge-NOI 2.6-1768 最大子矩阵

    题目链接:http://noi.openjudge.cn/ch0206/1768/ 题解: 如果用O(n4)的算法肯定会炸,需要压缩掉一维的空间,只需要简单加和就好啦 例如,我们要对样例中第2-4行D ...

  8. MySQL 视图、触发器、函数、存储过程

    1. 视图 1.1 什么是视图 通俗来讲,视图就是一条 select 语句执行后返回的结果集.所有我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上. 1.2 视图的特性 视图是对若干张基 ...

  9. php琐碎

    1.类中的常量,可以用类来引用: class MyClass() { const SUCCESS ="success"; const FAIL ="fail"; ...

  10. tcgetattr函数与tcsetattr函数控制终端

    6.4.4  使用tcgetattr函数与tcsetattr函数控制终端 为了便于通过程序来获得和修改终端参数,Linux还提供了tcgetattr函数和tcsetattr函数.tcgetattr用于 ...