一对一
一对一关系的实现,可以在任意一方添加外键指向两一方的主键,让外键唯一UNIQUE
一对多
员工跟部门的关系
在多的一方建立外键关联一的一方的主键
多对多
学生跟课程的关系
多对多关系实现需要借助第三章中间表,中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
多对多中间表的设计:
Create table stu_course{
stuId int ,—学生id
DATE DATETIME,
courseId int, —课程id
-创建复合主键
PRIMARY KEY(stuId,courseId),--联合主键
FOREIGN KEY(stuId) REFERENCES student(sId),
FOREIGN KEY(courseId) REFERENCES course(cId)
}
概念:设计数据库时,需要遵循的一些规则。
第一范式(1NF):每一列都是不可分割的原子数据项
第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
概念:
1.函数依赖:A-->B,如果通过A属性的值(属性组)的值,可以确定唯一B属性的值,则称B依赖于A.
例如:学号-->姓名。 (学号,课程名称)-->分数
2.完全依赖函数:A-->B,如果A是一个属性组,则B属性值的确定需要依赖A属性组中所有的属性值。
例如:(学号,课程名称)-->分数
3.部分依赖函数:A-->B,如果A是一个属性组,则B属性值的确定只需要依赖A属性组中某一些属性值即可。
例如:(学号,课程名称)-->姓名
4.传递函数依赖:A-->B,B-->C,如果通过A属性的值(属性组)的值,可以确定唯一B属性的值,再通过B属性的值(属性组)的。 值,可以确定唯一C属性的值,则称C传递函数依赖于A.
例如:学号-->系名,系名-->系主任
5.码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
例如:该表中码为(学号,课程名称)
主属性:码属性组中的所有属性
非主属性:除过码属性组的属性
第三范式(3NF):在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)
1.命令行的方式:
语法:
备份:mysqldump -u用户名 -p密码 数据库名称 > 保存的路径
还原:
1.登陆数据库
2.创建数据库
3.使用数据库(use 数据库名称)
4.执行sql (source sql的保存的路径)
笛卡尔积:
有两个集合A,B,取这两个集合的所有组成情况
要完成多表查询,需要消除无用的数据
多表查询的分类:
1.内连接查询:
1>隐式内连接:
语法: select 字段列表 from 表名 表名2 where 条件
select t1.name,t1.gender,t2.name from emp t1,dept t2 where t1.dept_id=t2.id
2>显式内连接:
语法: select 字段列表 from 表名 [inner] join 表名2 on 条件. (中括号表示可以省略)
select t1.name,t1.gender,t2.name from emp t1 inner join dept t2 on t1.dept_id=t2.id
3>内连接查询:
1)从哪些表中查询数据
2)条件是什么
3)查询哪些字段
2.外连接查询:
1>左外连接:
语法:select 字段列表 from 表1 left [outer] join 表2 on 条件
查询的是左表所有数据以及其交集部分
2>右外连接:返回所有右表数据,即使没有与左表匹配的信息
语法:select 字段列表 from 表1 right [outer] join 表2 on 条件
查询的是右表所有数据以及其交集部分
3.子查询:
概念:查询中嵌套查询,称嵌套查询的语句为子查询
例子:
--查询工资最高的员工信息
--1 查询最高的工资是多少 9000
select max(salary) from emp;
--2 查询员工信息,工资等于 9000
select * from emp where emp.salary=9000;
--一条sql就完成这个操作
select * from emp where emp.salary=(select max(salary) from emp);
子查询的不同情况:
1.子查询的结果是单行单列
子查询可以作为条件,使用运算符去判断。运算符:<,>,=>,<= 等
例子:
--查询员工工资小于平均工资的人
select * from emp where emp.salary<(select avg(salary) from emp);
2.子查询的结果是多行单列的
例子:
--查询财务部和市场部所有的员工信息
--1 查询财务部和市场部的部门id
select * from dept where name=“财务部” OR name=“市场部”;
--2根据部门id查询员工
select * from emp where dept_id=3 OR dept_id=2;
--3组合查询
select * from emp where dept_id IN(select * from dept where name=“财务部” OR name=“市场部”;)
3.子查询的结果是多行多列的
--查询2011-11-11之后入职的员工信息和部门信息
select * from dept t1 ,(select * from emp where emp.join_data > ‘2011-11-11’) t2 where t1.id=t2.dept_id
select * from emp t1,dept t2 where t1.dept_id=t2.id AND emp.join_data > ‘2011-11-11’;
1.事务的基本介绍
1.概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么全部成功,要么全部失败
2.操作:
1.开启事务:start transaction
2.回滚:rollback
3.提交: commit
4. mySql数据库中事务默认自动提交
一条DML语句自动提交一次事务
自动提交 :mysql自动提交
手动提交:需要先开启事务,在提交;oracle默认手动提交
查看提交方式:select @@autocommit; 1代表自动提交,0代表手动提交
修改提交方式:set @@autocommit =0;改为手动提交
2.事务的四大特征
1.原子性:是不可再分割的最小操作单位,要么同时成功,要么同时失败
2.持久性:当事务提交或会滚后,数据库会持久化的保存数据
3.隔离性:多个事务之间。相互独立。
4.一致性:事务操作前后,数据总量不变。
3.事务的隔离级别(了解)
概念:多个事务之间是隔离的,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在问题:
1.脏读:一个事务,读取到另一个事务中没有提交的数据
2.不可重复读:在同一个事务中,两次读取到的数据不一样。
3.幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
隔离级别:
1.read uncommitted:读未提交:
同时开启两个事务,A事务执行操作未提交,B事务可以读到一执行操作的结果
产生的问题:脏读,不可重复读,幻读
2.read committed:读已提交(Oracle)
产生的问题:不可重复读,幻读
3.repeated read :可重复读(MySql默认)
产生的问题:幻读
4.serializable :串行化
可以解决所有的问题
注意:隔离级别从小到大安全性越来越高,但是效率越来越低
数据库查询隔离级别:
select @@tx_islation
数据库设置隔离级别:
set global transaction isolation level 级别字符串;例如:级别字符串为read committed
演示:
set global transaction isolation level read uncommitted;
start transaction;
update account set balance =balance-500 where id=1;
update account set balance =balance+500 where id=2;
read uncommitted情况下:A执行上述操作未提交,则B事务可以查看到已经发生的转账情况账户1,账户2的金额已经变化。
read committed情况下:A执行上述操作未提交,则B事务可以查看到已经发生的转账情况账户1,账户2的金额未发生变化。
repeated read情况下:A执行上述操作,B事务在不提交的情况下读取多次读到的数据都是同一个结果,不会重复去读数据,只有提交结束当前的事务,重新查询才可查询到变化的数据。
serializable情况下:A执行上述操作,B事务执行查询,不会出现数据表,只有当A提交数据或者回滚之后,B事务会同时显示出查询结果。
DCL:
SQL分类:
1.DDL:操作数据库和表
2.DML:增删改表中的数据
3.DQL:查询表中数据
4.DCL:管理用户,授权 :数据库管理员(DBA)来操作
DCL:管理用户,授权
1.管理用户
1.添加用户
语法: CREATE USER ‘用户名’@‘主机名’ IDENTIFIED BY ‘密码’;
例如:
CREATE USER ‘zhangsan’@‘localhost’ IDENTIFIED BY ‘123’;//在当前本机可以登录
CREATE USER ‘lisi’@‘%’ IDENTIFIED BY ‘123’;//在任意主机可以登录
2.删除用户
语法: DROP USER ‘用户名’@‘主机名’;
3.修改用户
语法: UPDATE USER SET PASSWORD =PASSWORD(‘新密码’) WHERE USER=‘用户名’;//方法1
SET PASSWORD FOR ‘用户名’@‘主机名’ =PASSWORD(‘新密码’);//DCL特有方式方法2
mysql中忘记root用户的密码?
1.cmd. —>net stop mysql //停止mysql服务 必须以管理员身份运行改cmd
2.使用无验证方式启动mysql服务:mysqld --skip grant -tables
3.再打开一个新的cmd窗口(上一个cmd窗口不关闭),直接按Enter键则可直接进入MySql,
4.user mysql;
5.update user set password=password(‘新密码’) where user=‘root’;
6.关闭两个窗口
7.打开任务管理器,手动结束mysql.exe的进程
8.打开新的cmd任务窗口手动启动mysql:net start mysql
9.使用新密码登陆
4.查询用户
1>切换到mysql数据库
USE mysql
2>查询user表
SELECT * from user;
通配符:%表示可以在任意主机使用用户登录数据库
2.权限管理:
1.查询权限
语法:SHOW GRANTS FOR ‘用户名’@‘主机名’;
例如:SHOW GRANTS FOR ‘zhangsan’@‘%’;
2.授予权限
语法:grant 权限列表 on 数据库名.表名 TO ‘用户名’@‘主机名’;
例如:
//lisi可对数据库db3的account表可查询,删除
grant SELECT,DELETE on db3.account TO ‘lisi’@‘%’;
//给lisi用户授予所有权限,在任意数据库任意表上
grant ALL on *.* TO ‘lisi’@‘%’;
3.撤销权限
语法:revoke 权限列表 on 数据库名.表名 FROM ‘用户名’@‘主机名’;
例如:
//lisi可对数据库db3的account表可查询,删除
revoke SELECT,DELETE on db3.account FROM ‘lisi’@‘%’;
//给lisi用户授予所有权限,在任意数据库任意表上
revoke ALL on *.* FROM ‘lisi’@‘%’;