重要
1、什么是SQL?
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。

SQL通用语法
1、SQL语句可以单行或多行书写,以分号结尾。
2、不区分大小写,关键字建议使用大写。

SQL分类:
1、DDL数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create、drop、alter等
2、DML数据操作语言
用来对数据库中表的数据进行增删改查。关键字:insert、delete、update等
3、DQL数据查询语言
用来查询数据库中表的记录(数据)。关键字: select、where等
4、DCL数据控制语言
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT、REVOKE等

1、定义
#####DDL:操作数据库、表
1、操作数据库:CRUD
C:创建
创建数据库:
create database 数据库名称;
创建数据库,判断不存在,再创建
create database if not exists 数据库名称;
创建数据库,并指定字符集
create database 数据库名称 character set 字符集名;
R:查询
查询所有数据库的名称:show databases;
U:修改
修改数据库字符集
alter database 数据库名称 character set 字符集名称;
D:删除
删除数据库:
drop database 数据库名称;

使用数据库:
use 数据库名称;

2、操作表
C:创建
create table 表名(
    列名1 数据类型1,
    列名2 数据类型2,
    。。。
    列名n 数据类型n
);
注意:最后一列,不需要加逗号(,)
数据库类型:
1、int:整数类型
2、double:小数类型
3、data:日期,只包含年月日,yyyy-MM-dd
4、datatime:日期,包含年月日时分秒,yyyy-MM-dd HH:mm:ss
5、varchar:字符串

例子:创建表:学生信息表(编号,姓名,年龄,分数,出生日期)
create table student(
    id int,
    name varchat(32),
    age int,
    score double(4,1),
    birthday data
);
R:查询
查询某个数据库中所有的表名称
show tables;
3、U修改
    1。修改表名
        alter table 表名 rename to 新的表名;
    2。修改表的字符集
        alter table 表名 character set 字符集名称;
    3、添加一列
        alter table 表名 add 列名 数据类型;
    4、修改列名称 类型
        alter table stu change gender sex varchar(20);
        alter table 表名 change 列名 新列名 新数据类型;
        alter table 表名 modify 列名 新数据类型;
    5、删除列
        alter table 表名 drop 列名;
4、D删除
drop table 表名;
drop table if exists 表名;

######DML:增删改表中的数据
1、添加数据
    语法:
        INSERT INTO 表名(列名1,列名2,...,列名n) VALUES(值1,值2,...,值n);
    注意:
        1、列名和值要一一对应。
        2、如果表名后,不定义列名,则默认给所有列添加值。
           INSERT INTO 表名 VALUES(值1,值2,...,值n);
        3、除了数字类型,其他类型需要使用引号(单双都可以)引起来。
2、删除数据
        语法:
            DELETE FROM 表名 【where 条件】
        注意:
            1、如果不加条件,则删除表中所有记录。
            2、如果要删除所有记录
                        1、delete from 表名;--不推荐使用。有多少条记录就会执行多少次删除操作,效率比较低
                        2、TRUNCATE TABLE 表名;--先删除表,然后再创建一张一样的表。推荐使用,效率更高。
3、修改数据
        语法:
            update 表名 set 列名1=值1,列名2=值2,...【where 条件】;
            UPDATE stu SET  age=18,score=100 WHERE id =2;
        注意:1、如果不加任何条件,则会将表中所有记录全部修改。

######DQL:查询表中的记录
        select * from 表名; 
        1、语法:
            select 字段列表
            from 表名列表
            where 条件列表
            group by 分组字段
            having 分组之后的条件
            order by 排序
            limit 分页限定
        2、基础查询
            1、多个字段查询
查询姓名和年龄
SELECT name,age FROM student;
 注释(“--”)
SELECT 
                name,--姓名
                age     --年龄
FROM 
                student;--学生表

SELECT address FROM student;
--去除重复大的结果集
SELECT DISTINCT address FROM student;
student表(id、name、age、sex、address、math、english)
--计算math和english分数之和
SELECT name,math,english,math+english FROM student;
--如果有null参与的运算,计算结果都为null
SELECT name,math,english,math+IFNULL(english,0) FROM student;
--起别名
SELECT name,math,english,math+IFNULL(english,0) AS 总分 FROM student;
AS不写用空格替代也可以。
SELECT name,math 数学,english 英语,math+IFNULL(english,0) AS 总分 FROM student;

select 字段名1,字段名2。。。from 表名;
注意:如果查询所有字段,则可以使用*来代替字段列表。
            2、去除重复
                distinct
            3、计算列
                一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
                ifnull(表达式1,表达式2):null参与的运算,计算结果都为null
                    表达式1:哪个字段需要判断是否为null
                    如果该字段为null后的替换值。
            4、起别名
                as:as也可以省略

3、条件查询
1、where子句后跟条件
2、运算符
>、<、<=、>=、=、<>
BETWEEN...AND
IN(集合)
LIKE:模糊查询
IS NULL
and 或 &&
or 或 ||
not 或 !
--查询年龄大于20岁
SELECT * FROM student WHERE age>20;
SELECT * FROM student WHERE age>=20;
--查询年龄等于20岁
SELECT * FROM student WHERE age=20;
--查询年龄不等于20岁
SELECT * FROM student WHERE age! =20;
SELECT * FROM student WHERE age<>20;
查询年龄大于等于20,小于等于30
SELECT * FROM student WHERE age>=20 AND age<=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;
查询年龄22岁,19岁,25岁的信息
SELECT * FROM student WHERE age=22 OR age=19 OR age=25;
SELECT * FROM student WHERE age IN(22,18,25);

查询英语成绩为null
SELECT * FROM student WHERE english=NULL;--不对的,null值不能使用=(!=)判断
SELECT * FROM student WHERE english IS NULL;

查询英语成绩不为null
SELECT * FROM student WHERE english IS NOT NULL;

 LIKE:模糊查询
占位符:
_:单个任意字符
%:多个任意字符
--查询姓马的有哪些?like
SELECT * FROM student WHERE NAME LIKE '马%';
--查询第二个字是“化”的人?
SELECT * FROM student WHERE NAME LIKE '_化%';
--查询姓名是3个字的人?
SELECT * FROM student WHERE NAME LIKE '___';
--查询姓名中包含德的人?
SELECT * FROM student WHERE NAME LIKE '%德%';

今日内容
1、DQL:查询语句
    1、排序查询
语法:order by 子句
            order by 排序字段 排序方法
SELECT * FROM student ORDER BY math DESC;正序
SELECT * FROM student ORDER BY math DESC;倒序
--按照数学成绩排名,如果数学成绩一样,则按照英语成绩排名
SELECT * FROM student ORDER BY math ASC,english ASC;
如果有多个排序条件,则当前面的条件值一样时,才会判断第二条件。
    2、聚合函数:将一列数据作为一个整体,进行纵向的计算。
        1、count:计算个数
COUNT(*)
SELECT COUNT(name) FROM student;
SELECT COUNT(IFNULL(english,0))) FROM student;
聚合函数的计算,排斥null值。
        2、max:计算最大值
SELECT MAX(math) FROM student;
        3、min:计算最小值
SELECT MIN(math) FROM student;
        4、sum:计算和
SELECT SUM(math) FROM student;
        5、avg:计算平均值
SELECT AVG(math) FROM student;
    3、分组查询
1、语法:group by 分组字段;
--按照性别分组,分别查询男、女同学的平均分
SELECT sex,AVG(math) FROM student GROUP BY sex;
--按照性别分组,分别查询男、女同学的平均分,人数
SELECT sex,AVG(math),COUNT(id) FROM student GROUP BY sex;
--按照性别分组,分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组
SELECT sex,AVG(math),COUNT(id) FROM student WHERE math>70 GROUP BY sex;
--按照性别分组,分别查询男、女同学的平均分,人数 要求:分数低于70分的人,不参与分组,分组之后,人数要大于2个人。
SELECT sex,AVG(math),COUNT(id) FROM student WHERE math>70 GROUP BY sex HAVING COUNT(id)>2;
where和having的区别?
where在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来
where后不可以跟聚合函数,having可以进行聚合函数的判断。
SELECT sex,AVG(math),COUNT(id)  人数 FROM student WHERE math>70 GROUP BY sex HAVING 人数>2;
    4、分页查询
    1、语法:limit开始的索引,每页查询的条数;
--每页显示3条记录
SELECT * FROM student LIMIT 0,3;--第1页
SELECT * FROM student LIMIT 3,3;--第2页
SELECT * FROM student LIMIT 6,3;--第3页
limit是一个MySQL“方言”
2、约束
概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性。
分类:
    1、主键约束:primary key
1、注意
非空且唯一
一张表只能有一个字段为主键
主键就是表中记录的唯一标识
CREATE TABLE stu(
            id INT PRIMARY KEY;
            name VARCHAR(20) NOT NULL;  --name为非空
);
自动增长:如果某一列是数值类型的,使用auto_increment可以来完成值的自动增长。
创建表时,添加主键约束,并且完成主键自增长
id int primary key auto_increment,--给id添加主键约束
删除自动增长
ALTER TABLE stu MODIFY id INT;

    2、非空约束:not null,值不能为空
CREATE TABLE stu(
            id INT;
            name VARCHAR(20) NOT NULL;  --name为非空
);
--删除name的非空约束
ALTER TABLE stu MODIFY name VARCHAR(20);
--创建表完后,添加非空约束
ALTER TABLE stu MODIFY name VARCHAR(20) NOT NULL;
    3、唯一约束:unique,值不能重复
注意mysql中,唯一约束限定的列的值可以有多个null
删除唯一约束
ALTER TABLE stu DROP INDEX id;
--创建表完后,添加 唯一约束
ALTER TABLE stu MODIFY id INT UNIQUE;

    4、外键约束:foreign key

CREATE TABLE employee(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20),
    age INT,
    dep_id INT,
    CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id)
)
外键列
constraint 外键名称 foreign key(外键列名称)references 主表名称(主表列名称)
删除外键
ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
添加外键创建表之后,添加外键
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id);
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
级联操作
添加外键,设置级联更新
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE;
级联删除:ON DELETE CASCADE
3、多表之间的关系
一对一
一对多
多对多
4、范式
概念:设计数据库时,需要遵循的一些规范。
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
分类:
第一范式(1NF):数据库表的每一列都是不可分割的原子数据项
第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
5、数据库的备份和还原


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第三天
1、多表查询
2、事务
3、DCL(控制权限,管理用户)

两张表
emp(id,name,gender,salary,join_date,dept_id)
dept(id,name)
SELECT * FROM emp,dept;
笛卡尔积
有两个集合A,B,取这两个集合的所有组成情况,
要完成多表查询,需要消除无用的数据。
多表查询的分类:
1、内连接查询
2、外连接查询
3、子查询

内连接查询
隐式内连接:使用where条件消除无用数据
查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.'dept_id' = dept.'id';
查询员工表的名称,性别,部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.'dept_id' = dept.'id';
如果觉得表名太长可以替换
SELECT 
            t1.name,t1.gender,t2.name 
FROM 
            emp t1,dept t2 
WHERE  
            t1.'dept_id' = t2.'id';
显示内连接
语法:select 字段列表 from 表名1 [inner] join 表明2 on 条件
例如:
SELECT * FROM emp INNER JOIN dept ON emp.'dept_id'=dept.'id'; 
SELECT * FROM emp JOIN dept ON emp.'dept_id'=dept.'id'; 
内连接查询:
1、从哪些表中查询数据
2、条件是什么
3、查询哪些字段

外连接查询
1、左外连接
select 字段列表 from 表1 left 【outer】 join 表2 on 条件;
查询的是左表所有数据以及其交集部分。 
右外连接
select 字段列表 from 表1 right 【outer】 join 表2 on 条件;
查询的是右表所有数据以及其交集部分。 

子查询
查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);