[email protected] MYSQL基础、分页查询

数据库介绍

DB:数据库(database):用于存储和管理数据的“仓库”。

保存数据的容器有:数组(临时性保存数据),集合,(数组或集合中数据,在程序运行结束后,在堆或栈中空间被java回收机制回收了)文件(检索数据不方便)等。

数据库:文件夹;表:文件;数据:数据。
集合,数组,都存储在内存中,程序关闭,数据消失。
文件,读写很不方便。

数据库的好处

1.实现数据持久化,其实数据库就是一个文件系统。

2.使用完整的管理系统统一管理,方便存储和管理数据。

3.使用了统一的方式操作了数据库-SQL。

内存中数据不是持久化,电脑一关机就没了。持久化就是能保存到硬盘中实际存储下来,硬盘不坏数据都在。

持久化操作有:文件,数据库(都是将数据保存到硬盘中)

把内存中数据放到文件或数据库中的过程叫做持久化过程,在java中有个持久化层。

数据库的特点

1.将数据放到表中,表再放到库中。

2.一个数据库中可以有多个表,每个表都有一个名字,用来标识自己,表名具有唯一性。

3.表具有一些特性,这些特性定义了数据在表中如何存储,类似java中“类”的设计。

4.表由列(字段)组成。所有表都是由一个或多个列组成的,每一列类似java中的“属性”。

5.表中的数据是按行存储的,每一行类似于java中的“对象”。

DBMS:数据库管理系统(Database Management System)

指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的表内数据。

数据库管理系统(DBMS)可以管理多个数据库。一般开发人员会针对每个应用建立一个数据库。一个DBMS有多个数据库,一个数据库中建多张表,表中插入多条数据。

常见的数据库管理系统(DBMS)有:MySQL(大型的免费开源,适用于企业,oracle公司) SqlServer(小型的开源免费,适用于练习,微软,微软产品特点只能在windows系统下使用) Oracle(付费) DB2(付费)等。

MYSQL是一种大型数据库管理软件,开源免费,执行效率高,适用于企业开发。

MYSQL使用的图形化界面工具有多种,有Navicat premium和SQLyog等,它们界面不一样,但操作形式一样。

SQLyog 是业界著名的 Webyog 公司出品的一款简洁高效、功能强大的图形化 MySQL 数据库管理工具。使用SQLyog 可以快速直观地让您从世界的任何角落通过网络来维护远端的 MySQL 数据库。

MySQL安装和启动:

1.安装mysql后配置环境变量(安装5.5版本稳定)(数据库卸载干净要百度)

(此电脑,属性,高级系统设置,环境变量,系统变量path, D:\MyApp\Mysql\bin)

2.mysql启动:

1.手动启动,找到任务管理器,选择里面的服务,找到mysql启动就行了,系统默认开机就启动mysql服务。

(此电脑,管理,服务和应用程序,服务,找到Mysql服务,点击开启,默认电脑开机就自动开启mysql服务)

2.通过cmd命令行方式开启服务 (要以管理员身份打开cmd才能开启mysql服务)

启动mysql服务:net start mysql服务名(不一定是mysql)(net start MySQL都行,mysql中不区分大小写)

关闭mysql服务:net stop mysql服务名(不一定是mysql)(net stop MySQL)

cmd运行方式:要以管理员身份打开cmd才能进行启动mysql服务,然后再以普通用户身份即可操作命令行。
一般电脑开机系统就会自动打开启动mysql服务,可直接进行命令行操作mysql

3,MySQL服务端的登入和退出。(用cmd登入mysql服务端,管理员或普通身份打开cmd都行)

登入:全写:mysql -h 主机名localhost(本机) -P 端口号 -u用户名 -p密码(端口号是大P)

简写:mysql -u用户名 -p密码(密码回车不可见,不回车可见)mysql -uroot -p3306

退出:exit或quit,exit是退出cmd命令行页面窗口,不用加分号;。

4.通过cmd命令行方式进入mysql后,敲每条sql语句后一定要加上英文分号;结束

查看数据库版本信息:select version();
查看数据库中有哪些数据库:show databases;

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

新建一个数据库: create database 数据库名;

删除数据库:drop database 数据库名;

查看指定数据库中有哪些数据表 :show tables;

查看表结构:desc 表名;

删除表结构:drop table 表名;

删除表数据:delete table 表名;

SQL:结构化查询语言(Structure Query Language)

专门用来与数据库通信的语言。

SQL的优点:

1.不是某个特定数据库供应商专有的语言,几乎所有DBMS都支持SQL

2.简单易学,灵活使用其语言元素,所有DB都支持SQL。

SQL使用语法规范:

1.SQL语句不区分大小写,关键字建议大写(SQLyog里面操作会自动将关键字转化为大写的)

可以使用着重号``将所写单词括起来,以避免和关键字产生冲突。

2.SQL语句可以单行或多行书写,以分号(;)结尾。

3.各子句一般分行写 ,可用空格和缩进提高语句的可读性。

4.有三种注释,单行注释: --注释内容 或 # 注释内容(mysql 特有) 。多行注释: /* 注释 */。

SQL语言分类:

1.DDL(Data Definition Language):数据定义语句,用来定义数据库对象:数据库,表,列等。库和表的创建、修改、删除,关键字:create,alter, drop 等。 drop删库, drop删除表结构,delete删除表数据。

2.DML(Data Manipulation Language):数据操作语句,用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等。

3.DQL(Data Query Language)数据查询语句,用来查询数据库中表的数据。关键字:select。

4.DCL(Data Contron Language):数据控制语句(DCL用来控制数据库的访问,了解),用于定义用户的访问权限和安全级别,及创建用户。关键字:GRANT:授予访问权限,REVOKE:撤销访问权限,COMMIT:提交事务处理,ROLLBACK:事务处理回退,SAVEPOINT:设置保存点,LOCK:对数据库的特定部分进行锁定等。

5.TCL:事务控制,管理事务。

DQL(Data Query Language)数据查询语句

用来查询数据库中表的数据。关键字:select。

SELECT
			字段
		FROM
			表名
		WHERE
			条件
		GROUP BY(每个、每组、各个)
			分组字段
		HAVING
			分组之后的条件筛选
		ORDER BY(asc默认升序,desc降序,一般排序放最后,除非有分页)
			排序字段  排序方式(升或降)
		LIMIT
			分页限定
			
分页查询(limit语句放在查询的最后)实际开发中,分页查询都是一页一页的查询数据。
	1. 语法:limit 开始的索引,每页查询的条数;
	2. 公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数
		          -- 每页显示3条记录 

		SELECT * FROM student LIMIT 0,3; -- 第1页
		
		SELECT * FROM student LIMIT 3,3; -- 第2页
		
		SELECT * FROM student LIMIT 6,3; -- 第3页
	 3. limit 是一个MySQL"方言"
#如果只有一个参数,则是从第一页第一条数据开始取数据
SELECT * FROM employees 
LIMIT 10;

SELECT * FROM employees 
ORDER BY salary
LIMIT 0,10; #第一页,每页10笔数据。
/*
   页数  取数据  limit
     1     10    0,10
     2     10    10,10
     3     10    20,10
     n     m     (n-1)*m,m
*/

oracle数据库中没有直接提供分页的命令。
数据伪列:数据库表中不存在的列,但是又可作为普通的数据列进行查询。
常用的数据伪列:rownum,表示的是每笔数据的行号。
虚拟表,先排序,再查行号。
select id,name,salary from (select id,name,salary,rownum aa from(select id,name,salary from emp order by salary desc))
where aa >0 and aa <=10;
实际开发中,分页查询都是一页一页的查询数据。
需求:要求查询第二页,每页显示10笔数据。
select id,name,salary from (select id,name,salary,rownum aa from(select id,name,salary from emp order by salary desc))
where aa >10 and aa <=20;
规律:
实际开发中对于分页的参数:每页显示的数据笔数【pageSize】,和需要显示的页数【pageCurrent】
需求:显示第n页,每页显示m笔数据。
select id,name,salary from (select id,name,salary,rownum aa from(select id,name,salary from emp order by salary desc))
where aa >(n-1)*m and aa <=(n*m);
带有查询条件的分页查询(查询条件放最里面那个层)
需求:查询name中带有字母A的,并且显示第2页,每页显示10笔数据。
select name rownum from emp where name like '%A%'; 查询到13笔数据。
select id,name,salary from (select id,name,salary,rownum aa from(select id,name,salary from emp where name like '%A%' order by salary desc))
where aa >(2-1)*10 and aa <=(2*10);
#使用着重号``将字段名包起来,避免字段名和关键字重名起冲突。
#mysql中用单引号或双引号括起字符串都行,一般数据库用单引号''将字符串括起来。mysql中不区分字母大小写。

进阶一、基本查询:(列起别名,显示表结构(DESC),去重(distinct ),字符串拼接函数concat(),
使用ifnull()函数,将用一个新的值替代为null的值)

语法:select 查询列表 from 表名;
特点:1.查询列表可以来自表中的字段、常量值、表达式、函数。 2.查询的结果是一个虚拟的表格。
#查看employees表中的姓
SELECT last_name FROM employees;
#查看employees表中的姓、工资、邮箱
SELECT last_name,salary,email FROM employees;
#查看表中所有字段信息
SELECT * FROM employees;
#说明:在开发中,尽量不要使用select *,除非是查询所有的列。

#查询常量值
SELECT 100;
SELECT 'java20200929';
SELECT "mpp马鹏鹏"; #在数据库中一般用单引号''将字符串括起来,也可用双引号
#说明:在oracle数据库中,查看常量值也需要from 表名(可以是dual虚拟表)
SELECT 100 FROM DUAL;
SELECT 'java20200929' FROM DUAL;

#查询表达式
SELECT 100%98; #取模求余数
SELECT 100+98;
#说明:在oracle数据库中,表达式不能使用%运算符,查看表达式也需要from 表名(可以是dual虚拟表)
SELECT 100/50 FROM DUAL;
SELECT 100%50 FROM DUAL; #报错

#查询函数的返回结果
SELECT VERSION(); #查看数据库版本
SELECT SYSDATE(); #查看系统当前时间,等同于SELECT NOW();


起别名,列的别名:便于理解,一般省略as和单引号。
#方式一:使用AS关键字
SELECT 100/50 AS 结果;
SELECT 100/50 AS "结果";
SELECT 100/50 AS '结果'; #在mysql中一般用单引号将字符串括起来
#方式二:省略AS关键字
SELECT 100/50  结果;
SELECT 100/50  "结果";
SELECT 100/50  '结果'; 
#案例:查询salary显示结果字段名为 out put(别名包含空格、关键字必须用单引号括起来)
SELECT salary 'out put' FROM employees;

显示表结构(DESC),去重(distinct 字段名):
DESC `employees`;#显示表的具体字段信息,即表中有哪些列和列的数据类型主外键等信息
SELECT DISTINCT location_id  FROM departments;#去掉所查询字段中重复的数据


在数据库中,+号的作用只有一个:运算符
在java中的+号:1.运算符。2.连接符,+号前后至少要有一个字符串。
SELECT 100+20; #操作的两个数据都是数值型,则做加法运算
#操作的两个数据如果是字符串,会将字符串转换成数字
#转换成功,继续进行加法运算
#转换失败,字符串失败部分则表示0,0和剩余值继续进行加法运算
SELECT '100'+123;
SELECT 'abc' +123;
SELECT 'abc' + 'efg'; #结果为0,就是两个字符串都转换失败,就是0+0
SELECT NULL + 123; #如果有一方为null,则结果肯定为null
#说明:oracle中如果字符串转换失败,直接报错


字符串拼接函数concat()
#这不是连接字符串查看完整名字,用逗号是分隔开了,查看两个列信息。
SELECT last_name , first_name
FROM employees;
#查看完整名字,字符串连接
SELECT CONCAT(last_name,first_name) 姓名
FROM employees;
#CONCAT可以连接多个字符串,用逗号隔开
SELECT CONCAT(last_name,'-',first_name) 姓名
FROM employees;
SELECT CONCAT(last_name,'-',first_name,`employee_id`) 姓名
FROM employees;
#错误,非名字之间不能用'-'连接
SELECT CONCAT(last_name,'-',first_name,'-'`employee_id`) 姓名
FROM employees;
#说明:oracle中字符串拼接用 || ,也可以用concat()函数
SELECT ename || job FROM emp;
SELECT CONCAT(ename,job) FROM emp;



#使用ifnull()函数,将用一个新的值替代为null的值
SELECT IFNULL(commission_pct,0) is_new,commission_pct FROM employees;
#在oracle数据库中,不是使用ifnull()函数进行替换,而是用nvl()函数进行替换。
进阶二、带WHERE子句的过滤查询,WHERE子句紧随FROM子句
语法:SELECT  查询列表 FROM  表名  WHERE  过滤条件;
分类:
一、按照条件表达式进行筛选,> < >= <= != <>[mysql推荐使用<>不等于]
数据库中的等于操作符是=不是==,不等于操作符是<>也可以是!=,赋值使用:=符号
二、按照逻辑表达式进行筛选
   &&   ||    !
   AND   OR    NOT  [mysql推荐使用]
三、其他筛选条件
	1.like(模糊查询)mysql中不区分大小写
     #%代表0个或多个字符(任意个字符) _代表一个字符
     #LIKE's%'以s开头,LIKE'%a%'中间是a,LIKE'%b'以b结尾
	2.between  AND  区间范围查询,包含两边的区间值,在两个值之间(重点记住:闭区间,包含边界)
	3.IN/NOT IN  精确值范围查询,等于括号值列表中的任意一个值就行
	4.IS NULL/IS NOT NULL  是否为空值 
	5.<=> 安全等于,相当于=和IS NULL的综合【效率低,使用较少】
1.按照条件表达式查询
#案例1:查询工资大于12000的雇员信息
SELECT * FROM employees WHERE salary > 12000;
#案例2:查询部门编号不为90的雇员信息
SELECT * FROM employees WHERE department_id <> 90; #推荐使用<>不等于
SELECT * FROM employees WHERE department_id != 90;
#案例3:查询工资在8000到12000之间的雇员信息(包含8000和12000)
SELECT * FROM employees WHERE salary >= 8000 AND salary <=12000; #推荐使用AND逻辑表达式
SELECT * FROM employees WHERE salary >= 8000 && salary <=12000;

2.按照逻辑表达式进行筛选
#案例1:查询工资在8000到12000之间的雇员信息(包含8000和12000)
SELECT * FROM employees WHERE salary >= 8000 AND salary <=12000; 
#案例2:查询部门编号不是90到110之间,或者工资高于15000的雇员信息(高于就是大于)
#方式一,该写法不推荐
SELECT * FROM employees 
WHERE department_id < 90 OR department_id > 110 OR salary > 15000;
#方式二,求反NOT,推荐写法,求反!也行但不推荐
SELECT * FROM employees  
WHERE NOT(department_id >= 90 AND department_id <= 110) OR salary > 15000;

3其他筛选条件
3.1 like  模糊查询
like特点:一般和通配符结合使用,
% 代表0个或多个字符(任意个字符) _代表匹配一个字符
#范例1:查询雇员名字中包含a的所有雇员信息,mysql不区分大小写。
#mysql模糊查询默认不区分大小写,在like后面加上binary这个关键字就区分大小写。
SELECT * FROM employees WHERE first_name LIKE 'a'; #没有用通配符就是相等的意思
SELECT * FROM employees WHERE first_name LIKE '%a%';
#范例2:查询雇员名字中第三个字符为e,第五个字符为a的雇员的姓,名和工资
SELECT last_name,first_name,salary FROM employees
WHERE first_name LIKE '__e_a%';
#范例3:查询雇员姓第2个字符为_的雇员的姓,名和工资
SELECT last_name,first_name,salary FROM employees
WHERE last_name LIKE '_\_%'; #[\ 表示转义,不推荐方式]
SELECT last_name,first_name,salary FROM employees
WHERE last_name LIKE '_$_%' ESCAPE '$'; #[推荐使用任意字符表示转义,去掉特殊字符如%]

3.2 between  and  区间范围查询,闭区间,包含临界值
between min and max,两个临界值min和max不能颠倒顺序
#案例1:查询工资在8000到12000之间的雇员信息(包含8000和12000)
#方式一、使用条件表达式
SELECT * FROM employees WHERE salary >= 8000 AND salary <=12000; 
#方式二、使用between and 
SELECT * FROM employees WHERE salary BETWEEN 8000 AND 12000; 
#案例2:查询受雇日期在 1995-1-1 到2005-1-1之间的雇员信息
SELECT * FROM employees WHERE hiredate BETWEEN '1995-1-1' AND '2005-1-1';

3.3 in/not in  精确值范围查询
判断某个字段的值是否属于in列表中的某一项
in列表中的数据类型必须保证一致。in列表不支持通配符。in列表中支持子查询【子查询再讲】
#范例1:查询员工的岗位编号为:AD_VP,IT_PROG,ST_MAN的雇员信息
#方式一、使用or进行连接筛选
SELECT * FROM employees WHERE job_id = 'AD_VP' OR job_id = 'IT_PROG' OR job_id = 'ST_MAN';
#方式二、使用in
SELECT * FROM employees WHERE job_id IN( 'AD_VP', 'IT_PROG' , 'ST_MAN');

3.4 is null/is not null  是否为空值 
在数据库中,不能使用= null和<> null来表示
#范例1:查询奖金率为null的雇员信息
SELECT * FROM employees WHERE commission_pct = NULL; #错误的,不能写= null
SELECT * FROM employees WHERE commission_pct IS NULL; 
#范例2:查询奖金率不为null的雇员信息
SELECT * FROM employees WHERE commission_pct IS NOT NULL; 

3.5 <=> 安全等于,相当于=和IS NULL的综合【效率低,使用较少】
#范例:查询员工的姓名和奖金率,筛选条件没有奖金率的员工
SELECT CONCAT(last_name,first_name) 姓名,commission_pct FROM employees WHERE commission_pct IS  NULL; 
SELECT CONCAT(last_name,first_name) 姓名,commission_pct FROM employees WHERE commission_pct <=>  NULL; 
#范例:查询雇员信息,要求last_name为K_ing
SELECT * FROM employees WHERE last_name <=> 'K_ing';
进阶三、排序查询
select 查询列表
from  表名
[where  子句筛选]
[group by 子句 having]
order by 排序的字段或者表达式
order by子句一般放在查询的最后,除了limit子句,如果有limit子句,limit子句一定放在最后。
排序order by:asc升序【默认不写asc就是升序】,desc降序
order by 子句中可以跟上字段、表达式、别名、函数、多个字段
order by子句也可以按照字符串和日期进行排序
如果排序列出现null值,升序排列null值排在最前面,降序排列null值放最后,可理解为null值最小

#案例1:按照工资升序排列【按照单个字段排序】
SELECT * FROM employees ORDER BY salary;
#案例2:查询部门编号大于90的雇员信息,并按照雇员编号升序排列【按照单个字段排序并加上筛选条件】
SELECT * FROM employees WHERE department_id >90
ORDER BY department_id ASC;
#案例3:查询年薪,按照年薪降序排列【按照表达式进行排序】
SELECT salary*12+salary*12*IFNULL(commission_pct,0) FROM employees
ORDER BY salary*12+salary*12*IFNULL(commission_pct,0) DESC;
SELECT salary*12+salary*12*IFNULL(commission_pct,0) 年薪 FROM employees
ORDER BY 年薪 DESC;
#按别名排序:
SELECT `employee_id`,`last_name`,`salary`*12 年薪
FROM `employees`
ORDER BY 年薪;
#案例4:查询员工信息,并按照last_name的长度升序排列【按照函数进行排序】
SELECT LENGTH(last_name) 字节数,last_name FROM employees;
SELECT last_name FROM employees ORDER BY LENGTH(last_name);
#案例5:查询员工信息,按照部门编号升序排列,并且同时按照工资降序排列【按照多个字段排序】
order by 排序字段1 排序方式1 ,排序字段2 排序方式2...
注意:如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件,即在前者相同的基础上再排序。
SELECT * FROM employees ORDER BY department_id,salary DESC;
#多个列排序,后面列在前面列的基础上进行排序,如,在部门编号相同的情况下,再对工资降序排列。
#案例6:order by字句可以按照字符串和日期进行排序
#查询员工信息,按照last_name升序排列(一个个字母排序)
SELECT * FROM employees ORDER BY last_name;
#查询雇员信息,入职日期越晚放在最前面
SELECT * FROM employees ORDER BY hiredate DESC;
#案例7:如果排序列出现null值,升序排列null值排在最前面,降序排列null值放最后,可理解为null值最小
#查询雇员信息,按照奖金率升序排列
SELECT * FROM employees ORDER BY commission_pct DESC;
进阶四、常见函数
函数的概念和java中的方法是一致的,将一组逻辑语句封装在一个方法体中,对外暴露方法的名称和形参
目前学习的常见函数是数据库提供的函数,后期需要自己编写函数
好处:隐藏了方法的细节,提高了代码的重用性
函数的调用:select 函数名(参数列表)[from tableName]
函数的特点:1.叫什么(函数名)2.能做什么(函数的功能)
函数的分类:
1.单行函数:length(),ifnull(),concat()
2.分组函数:count(*),sum(),avg(),min(),max() 
分组函数的作用就是用来统计的,又称为统计函数,聚合函数,组函数 
1.单行函数
字符函数:length(),concat(),substr(),instr(),trim(),lpad(),rpad(),upper(),lower(),replace()
数学函数:round(),ceil(),floor(),truncate(),mod()
日期函数:datediff(),now(),curdate(),curtime(),year(),month(),monthname(),day(),hour(),minute(),second()
将字符串转日期:str_to_date(), 将日期转字符串:date_format()(日期的格式化)
其它函数:version()(获取当前数据库版本),database()(获取当前使用的数据库是哪个),user()(当前用户是哪个)
控制流程函数:if case
注意点,在数据库中索引都是从1开始的,java中索引是从0开始的。

#字符函数
#substr()截取
#substr()(字符串,位置从1开始,截取长度)/substring()(字符串,位置从1开始,截取长度)
#含两个参数就不同,substr(a,b)从a位置开始截取包含a,第二个参数是截取的长度。substring(a,b)从a位置开始截取包含a,截取到b位置不含b,左闭右开。
SELECT SUBSTR('我是马冬梅了',3,3); #表示从第三个开始截取 3位
SELECT SUBSTR('我是马冬梅了',3); #表示从第三个开始截取 到最后
SELECT SUBSTRING('我是马冬梅了',3);
SELECT SUBSTRING('我是马冬梅了',3,3); 
#instr(),取得指定字符串在前面字段中出现的索引位置
#INSTR(字段,'索引字符串'):返回位置 
SELECT INSTR('我是马冬梅了','马冬梅');
#索引某个字段中是否有某个字符串,不存在返回0,JAVA中返回-1
SELECT INSTR(last_name,'o'),last_name,employee_id
FROM employees
WHERE last_name='K_ing';

#trim()去空格。 trim('字符串' from 字段)去掉字段中指定的字符串
SELECT TRIM('   马冬梅     '); #去除前后空格
SELECT TRIM('ab' FROM 'abababab马ababab冬梅abababababab'); #去掉字段中指定的字符串
#lpad(),用指定的字符填充左边指定的长度。LPAD(字段,长度总数,填充内容):左填充
SELECT LPAD('马冬梅',10,'*'); #在左边添加7个*
#rpad(),用指定的字符填充右边指定的长度
#upper() 小写变大写,lower() 大写变小写
SELECT UPPER('china');
SELECT LOWER('JOIN');
#replace(字段,'被替换字符串,旧','替换字符串,新') 替换成指定的字符串
SELECT REPLACE('我是马冬梅了','马冬梅','马鹏鹏');

#LENGTH()是指字节长度,不是指字符串长度,一个英文字母就是一个字节
SELECT LENGTH(last_name) 字节长度,last_name
FROM employees;
#英文看不出字节差别,UTF8通用编码格式一个中文字代表3个字节,GBK国标编码格式一个中文字代表2个字节
SELECT LENGTH(`boyName`) 字节长度,`boyName`
FROM `boys`;
#查询邮箱中包含 e 的员工信息,并先按邮箱的字节数降序,再按部门号升序
SELECT *
FROM employees
WHERE email LIKE '%e%'
ORDER BY LENGTH(email) DESC, department_id ASC;


#数学函数,round(),ceil(),floor(),trucate(),mod()
#round(字段,保留小数位数)四舍五入保留小数,后面哪个数字就保留多少位小数。
SELECT ROUND(-1.5); #结果为-2
SELECT ROUND(1.5);
SELECT ROUND(3.1415926,4); #保留四位小数,第二个参数表示保留小数位数
#ceil() 向上取整,floor() 向下取整
SELECT CEIL(-1.5); 
SELECT FLOOR(-1.5);
#truncate(),截取多少位小数,不会四舍五入,而是直接将小数部分丢掉
SELECT TRUNCATE(10.888,2); #第二个参数表示截取小数位数
#说明:oracle中此函数为trunc(),select trunc(10.888,2) from dual;
#mod(),取模(求余数)
SELECT MOD(10,3);

#datediff():相差多少天。mysql只提供相差多少天
SELECT DATEDIFF('2020-1-2 ','2019/12/12 '); #()括号里不用写时分秒,计算天数写到具体日期就行。
#日期函数:now(),curdate(),curtime()
SELECT NOW(); #获取系统当前时间和日期
SELECT CURDATE(); #获取系统当前日期
SELECT CURTIME(); #获取系统当前时间
#year(),month(),monthname(),day(),hour(),minute(),second()取得指定日期的每个日历字段的值
SELECT YEAR(NOW());
SELECT YEAR('2008-08-08');
SELECT MONTH(NOW());
SELECT MONTHNAME(NOW());
#将字符串转日期:str_to_date(), 将日期转字符串:date_format()(日期的格式化)与java中的格式化规则不同。
#这两个转换的方法都需要指定的日期格式
SELECT STR_TO_DATE('2008-08-08 20:08:08','%Y-%m-%d %H:%i:%s');
#查询入职时间为2004-02-06的雇员信息
SELECT * FROM employees WHERE hiredate = '2004-02-06';
#将字符串转换成日期类型,注意参数里的符号一一对应(-或/)
SELECT STR_TO_DATE('2017-09-08','%Y-%m-%d');
SELECT STR_TO_DATE('2017/09/08','%Y/%m/%d');

#将日期转字符串:date_format()
SELECT DATE_FORMAT('2019-09-09','%Y年%m月%d日');
SELECT DATE_FORMAT('2019/09/09','%Y年%m月%d日');
SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日');
SELECT NOW() + 10; #在mysql中日期不能相加
#而在oracle中能进行日期相加,select sysdate + 10 from dual;其中sysdate表示当前系统时间的表达式


#其它函数:version()(获取当前数据库版本),database()(获取当前使用的数据库是哪个),user()(当前用户是哪个)
SELECT VERSION();
SELECT DATABASE();
SELECT USER();


#控制流程函数:if case
#if函数,if else 效果 (oracle中没有if)
SELECT IF(10<5,20,30); 
#类似三目运算符,第一个表达式的值为true,则取第二个表达式的值,否则取第三个表达式的值
SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金','有奖金') FROM employees;
#case 函数使用,效果和java中switch case一致(oracle只能写在PLSQL程序中,不能写在select字句中)
/*在java中
switch(变量或表达式){
	case 值1:语句1;break;
	case 值2:语句2;break;
}
在mysql中
case 要判断的表达式
when 值1 then 语句1
when 值2 then 语句2
....
else 语句3
end*/
/*案例:
查询雇员薪资,要求
部门号为30的,显示的工资为原始的1.1倍
部门号为40的,显示的工资为原始的1.2倍
部门号为50的,显示的工资为原始的1.3倍
其他部门,显示的工资为原始工资*/
SELECT salary 原始工资,department_id,
CASE department_id 
WHEN 30 THEN salary*1.1
WHEN 40 THEN salary*1.2
WHEN 50 THEN salary*1.3
ELSE salary 
END AS 新工资 FROM employees;
/*案例:
查询工资的情况,要求
大于20000的员工薪资,显示A
大于15000的员工薪资,显示B
大于10000的员工薪资,显示C
否则显示D*/
SELECT salary,
CASE
WHEN salary >20000 THEN 'A'
WHEN salary >15000 THEN 'B'
WHEN salary >10000 THEN 'C'
ELSE 'D'
END AS 工资级别 FROM employees;
进阶五、分组函数(很重要)
分组函数的作用就是用来统计的,又称为统计函数,聚合函数,组函数,分组函数一般处理数值型的数据。
聚合函数:将一列数据作为一个整体,进行纵向的计算。count可以使用任意类型作为参数,但一般用count(*)统计。
注意:聚合函数的计算,排除null值。所有的分组函数都能和去重distinct搭配使用。
count()数据笔数,sum()求和,avg()平均数,min()最小数,max()最大数 
语法:select 查询列表 from 表名 【where字句】 【group by字句】 【order by字句】
分组函数一般会和having()结合使用,跟上group by子句一起使用。
在开发中最好使用count(*),count(*)查询数据笔数效率高于count(字段)。

非法使用聚合函数:不能在WHERE子句中使用聚合函数。可以在HAVING子句中使用聚合函数。
注意: where 和 having 的区别?
1. where 在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来。HAVING一般和GROUP BY一起使用并放在GROUP BY后使用
2. where 后不可以跟聚合函数,having可以进行聚合函数的判断。HAVING(聚合函数)


#查询部门号为90的部门人数,可使用统计函数count()获取数据笔数
SELECT COUNT(*) FROM employees WHERE department_id = 90;
#查询50号部门的员工平均工资
SELECT AVG(salary) FROM employees WHERE department_id = 50;
#查询所有雇员的平均薪资,薪资总和,最高工资,最低工资,雇员数量
SELECT AVG(salary) 平均工资,SUM(salary) 薪资总和,MAX(salary) 最高工资,MIN(salary) 最低工资,COUNT(*) 雇员数量 FROM employees;
#统计函数count()可以使用任意类型作为参数
SELECT COUNT(hiredate) FROM employees;
SELECT COUNT(employee_id) FROM employees;
SELECT COUNT(last_name) FROM employees;
#所有的分组函数都忽略null值
SELECT COUNT(commission_pct) FROM employees;
SELECT MAX(commission_pct) FROM employees;
SELECT MIN(commission_pct) FROM employees;
SELECT SUM(commission_pct) FROM employees;
SELECT AVG(commission_pct) FROM employees;
#分组函数和去重distinct搭配使用
SELECT COUNT(DISTINCT manager_id) FROM employees;
SELECT SUM(salary),SUM(DISTINCT salary) FROM employees;
#count(*)统计有多少条数据,一条数据就是一行数据。(统计行数)
#count(first_name) 统计first_name字段的非空值个数。
#count()函数的单独介绍
SELECT COUNT(*),COUNT(employee_id) FROM employees;
#如果使用count(字段),那么为null的是统计不到的
#count(*),表示所有字段,只要是表中的数据不可能统计不到,可理解为统计行数。
#在开发中最好使用count(*),count(*)查询数据笔数效率高于count(字段)
#查询每个部门的平均工资【每个,要用到group by分组】
#分组函数一般会跟上group by字句一起使用。
SELECT AVG(salary),department_id FROM employees GROUP BY department_id;
进阶六、分组查询。分组查询数据:用GROUP BY子句将表中的数据分成若干组。group by 各个 每个 每组 就用分组
select 查询列表
[where 字句]
group by 
[having(分组函数)]
[order by 字句] 
分组前和分组后的筛选
分组前的筛选,在group by前用where字句
分组后的筛选,在group by后用having字句,分组聚合函数跟着having使用

#1.简单分组
#案例:查询每个部门的雇员人数
SELECT COUNT(*),department_id
FROM employees 
GROUP BY department_id;
#案例:查询每个工种的平均工资
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;
#案例:查询每个位置的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;

#2.分组前的筛选
#案例:查询邮箱中包含a字母的每个部门的最高工资
SELECT MAX(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
#案例:查询有奖金的每个领导手下雇员的平均工资
SELECT AVG(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;

#3.分组后的筛选
#案例:查询每个部门的雇员个数,并且雇员个数要>5
SELECT COUNT(*),department_id
FROM employees 
GROUP BY department_id
HAVING COUNT(*) >5;
#案例:查询编号大于102的每个领导的下属的最低工资大于5000的领导编号和最低工资
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) > 5000;

#4.添加排序
#案例:查询编号大于102的每个领导的下属的最低工资大于5000的领导编号和最低工资,并且按照最低工资降序排列
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) > 5000
ORDER BY MIN(salary) DESC;

#5.多个分组字段
#案例:查询每个工种,每个部门的平均工资,并且按照平均工资升序排列
SELECT AVG(salary),job_id,department_id
FROM employees   #在相同工号字段一个组下,再以部门号分组,在前者相同的基础上再分组
GROUP BY job_id,department_id
ORDER BY AVG(salary);

DDL(Data Definition Language):数据定义语句

用来定义数据库对象:数据库,表,列(字段)等。库和表的创建、修改、删除,关键字:create,alter, drop 等。 添加字段,给字段加约束,drop删库, drop删除表结构,delete删除表数据。

DDL操作数据库对象:库表列的创建、修改或删除。
1. 操作数据库:
创建数据库:CREATE DATABASE 数据库名称;
创建数据库,判断不存在,再创建:CREATE DATABASE IF NOT EXISTS 数据库名称;

创建数据库,并指定字符集:CREATE DATABASE 数据库名称 CHARACTER SET 字符集名;
* 练习: 创建db4数据库,判断是否存在,并制定字符集为utf8,java用utf-8,mysql用uft8
* CREATE DATABASE IF NOT EXISTS db4 CHARACTER SET utf8;
数据库名命名规则:不能重名 / 和关键词不一致 / 数字英文字母_ / 建议采用驼峰式命名法/有语义
显示所有数据库:SHOW DATABASES;
使用某个数据库: USE 数据库名;
使用库名.表名:SELECT * FROM girls.boys;
修改库名:rename database 旧库名 to 新库名;
修改数据库的字符集:ALTER DATABASE 数据库名称 CHARACTER SET 字符集名称;
删除数据库:DROP DATABASE 数据库名称;
判断数据库存在,存在再删除:DROP DATABASE IF EXISTS 数据库名称;

2. 操作表:
1.表的创建:
create table 表名(
	字段1 类型[(int长度可省略) 约束],
	字段1 类型[(varchar()长度不能省略) 约束],
	字段1 类型[(长度) 约束]
	...
);
CREATE TABLE 表名(
      字段 类型() 约束(主键约束PRIMARY KEY,唯一UNIQUE, AUTO_INCREMENT, NOT NULL,DEFAULT),
      字段 类型() 约束(外键FOREIGN KEY,唯一UNIQUE, AUTO_INCREMENT, NOT NULL,DEFAULT)
);

mysql数据库中常见的数据类型有:数值 / 字符 / 日期
数值型:int和double不用给括号里范围值,它会有默认值的。
   整形:int(),()里可以不写范围,它会默认0到12之间自动匹配,就是直接写int不用写括号()。
   整型分类:
   TINYINT : 叫做微小整型,占1个字节长度
   SMALLINT :小整型 ,占2个字节长度
   MEDIUMINT : 中间整型,占3个字节长度
   INT/INTEGER :整型,占4个字节长度(推荐)
   BIGINT : 大整型,占8个字节长度
  说明:如果插入的数据大于类型最大长度,会提示OUT of RANGE 异常,而且会插入临界值
   小数:(四舍五入,有精度问题)
	浮点型:FLOAT(m,n),double(M,D),一般使用double
	定点型decimal(M,D)  M:整数位+小数位最大的长度,D:小数位的长度
	如果是decimal类型的话,默认的M为10,默认的D为0,M和D可以省略但一般不省略
	如果是double会自动的根据数据的精度进行确定,但M和D一般不省略。
	定点型的精度会比浮点型的精度更高,如果数据对精度要求高的话使用定点型(像银行的数据用decimal)
非数值型:
	字符型:
   较短的文本:CHAR VARCHAR
   较长的文本:TEXT BLOB(二进制数据,存放较长文件、图片、视频、音频等等都可以)
		char  char(M)  M是最大的字符数,可以省略,默认为1   固定长度的字符
		sex CHAR(1) DEFAULT '女'
		varchar  varchar(M)  M是最大的字符数,不能省略      可变长度的字符
		字符串一般用varchar(M),char的空间耗费了比较高,varchar比较低。
较短的文本
   char  (固定长度数据推荐)
   varchar (推荐)
 较长的文本
   text 
   blob (较大的二进制,不推荐使用)
 其他的文本
   binary 和 varbinary 存放较短的二进制
   enum 存放枚举
   set 保存集合
 说明:
   建议超过100个字符的使用text类型
		
	日期型:日期型后面不加括号(),一般使用datetime,日期型内容用单引号括起来。
		date 只保存日期
		time 只保存时间
		datetime 保存时间和日期
       `borndate` DATETIME DEFAULT '1987-01-01 00:00:00',
#严谨的建库表方式:
CREATE DATABASE `girls` ;
USE `girls`;
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(10) NOT NULL,
  `password` VARCHAR(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT  INTO `admin`(`id`,`username`,`password`) 
VALUES (1,'john','8888'),(2,'lyt','6666');

DROP TABLE IF EXISTS `beauty`;

CREATE TABLE `beauty` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL,
  `sex` CHAR(1) DEFAULT '女',
  `borndate` DATETIME DEFAULT '1987-01-01 00:00:00',
  `phone` VARCHAR(11) NOT NULL,
  `photo` BLOB,
  `boyfriend_id` INT(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

INSERT  INTO `beauty`(`id`,`name`,`sex`,`borndate`,`phone`,`photo`,`boyfriend_id`) 
VALUES (1,'柳岩','女','1988-02-03 00:00:00','18209876577',NULL,8),
(2,'苍老师','女','1987-12-30 00:00:00','18219876577',NULL,9),
(3,'Angelababy','女','1989-02-03 00:00:00','18209876567',NULL,3),
(4,'热巴','女','1993-02-03 00:00:00','18209876579',NULL,2),
(5,'周冬雨','女','1992-02-03 00:00:00','18209179577',NULL,9),
(6,'周芷若','女','1988-02-03 00:00:00','18209876577',NULL,1),
(7,'岳灵珊','女','1987-12-30 00:00:00','18219876577',NULL,9),
(8,'小昭','女','1989-02-03 00:00:00','18209876567',NULL,1),
(9,'双儿','女','1993-02-03 00:00:00','18209876579',NULL,9),
(10,'王语嫣','女','1992-02-03 00:00:00','18209179577',NULL,4),
(11,'夏雪','女','1993-02-03 00:00:00','18209876579',NULL,9),
(12,'赵敏','女','1992-02-03 00:00:00','18209179577',NULL,1);

DROP TABLE IF EXISTS `boys`;

CREATE TABLE `boys` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `boyName` VARCHAR(20) DEFAULT NULL,
  `userCP` INT(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT  INTO `boys`(`id`,`boyName`,`userCP`) 
VALUES (1,'张无忌',100),(2,'鹿晗',800),(3,'黄晓明',50),(4,'段誉',300);
#显示表结构用 DESC
DESC girls;

#常用的建库表方式:

CREATE DATABASE girl;
#使用着重号``将字段名包起来,避免字段名和关键字重名起冲突。
#数据库中一般用单引号''将字符串括起来。
USE girl;

CREATE TABLE admin(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20) NOT NULL,
	`password` VARCHAR(20) NOT NULL
);

INSERT INTO admin VALUES (1,'mpp','mpp123'),(2,'jjm',‘jjm123’);
INSERT INTO admin(username,password) VALUES ('zs',‘zs123’);
CREATE TABLE beauty(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20) NOT NULL,
	sex CHAR(1) DEFAULT '女',
	borndate DATETIME DEFAULT '1987-01-01 00:00:00',
	phone VARCHAR(11),
	boyfriend_id INT(11) 
);

2表的修改:
alter table 表名 add|drop|modify|change column 列名 类型[(长度) default 默认值 约束]
MODIFY : 修改列数据类型或者约束。CHANGE : 修改列名。
1.修改列名:alter table book change column 旧列名 新列名 数据类型
2.添加新列(删除列就是把add换成drop):alter table book add column 列名 数据类型
3.修改列的数据类型:alter table book modify column 列名 数据类型
4.修改表名:alter table book rename to booK_a;
5.修改表的约束:alter table book_a modify column price double not null;

#修改表的字符集:ALTER TABLE 表名 CHARACTER SET 字符集名称;
# 范例:将departments 表结构复制到 departments20201120 表中 (仅仅复制的是表结构)
CREATE TABLE departments20201120 LIKE departments;
# 范例:将departments 表结构及数据复制到 departments20201121 表中
CREATE TABLE departments20201121 
SELECT * FROM departments;
#创建表并拷贝所有数据  AS
CREATE TABLE dat1 AS SELECT * FROM dat;
DESC dat1;
SELECT * FROM dat1;
#创建表并拷贝部分数据,某个字段 AS(AS可省略)
CREATE TABLE departments20201123
SELECT department_id,department_name FROM
departments WHERE department_id < 50;
#创建表并拷贝部分数据,多个字段,多个字段间用逗号隔开,并且重新定义字段名和字段数据类型 AS
CREATE TABLE dat3(newNum VARCHAR(11),newScore FLOAT(3,1)) AS SELECT num,score FROM dat;
DESC dat3;
SELECT * FROM dat3;

约束:是一种限制,限制表中的数据,是为了保证数据的完整和可靠。
约束可以在创建表,或者修改表的方式进行创建
约束的分类:
	非空约束:not null,用于保证字段的值不能为null。姓名
	主键约束:primary key,主键唯一不为空。学号
	唯一约束:unique,唯一可为空。座位号
	检查约束:check,检查字段的合理性。性别只能为男或女,mysql不支持检查约束,where子句中的筛选条件都可作为检查约束条件。
	外键约束:用于限制两个表之间的关系,设置外键的字段的值必须来自另外一个表的主键或者唯一约束列的值,比如雇员表中的部门编号全部来自部门表的主键
	【默认约束】:default,用于保证设置默认值约束的字段有默认值。性别默认为男
约束的使用规则:
一张表只能添加一个主键约束,主键唯一不为空。
一个表可以设置任意个外键。
添加约束的时机:
	1.创建表时:
	2.修改表时:	
修改约束:
alter table 表名 modify column 列名 类型 约束;
alter table 表名 add [constraint 约束名] 约束类型(列名) [外键引用]
删除约束:
删除非空约束:
alter table info modify column name varchar(20);
删除默认值约束【假设name有默认值约束】:
alter table info modify column name varchar(20);
删除主键约束:
alter table info drop primary key;
删除唯一约束【假设name有唯一约束】:
alter table info drop index 唯一约束名;
删除外键约束:
alter table info drop foreign key 外键约束名;


约束:对表中的数据进行限定,保证数据的正确性、有效性和完整性。	
分类:1. 主键约束:PRIMARY KEY,主键唯一且不为空,一般主键设置自动增长AUTO_INCREMENT。
      2. 非空约束:NOT NULL,值不能为空。NULL为默认,不用写。
      3. 唯一约束:UNIQUE(唯一键)允许插入空值,如果为非空值必须是唯一的不允许重复。注意mysql中,唯一约束限定的列的值可以有多个NULL,即空值NULL可重复,非空值不能重复。
      4. 外键约束:FOREIGN KEY。两个表之间存在关系的情况下才会设置外键约束,外检约束要求创建在多的一端的表中【一的一端表示主表,多的一端是从表】从表通过外键关联主表的列必须是一个主键列或者唯一约束的列,创建表时,先创建主表,再创建从表。新增数据时,要先新增主表的数据,再新增从表的数据。删除数据时,要先删除从表的数据,再删除主表的数据。

#修改列。修改表数据中字段约束modify(用modify修改表中字段数据类型),modify约束:修改的意思
ALTER TABLE  dat MODIFY num INT(5);
#修改字段不为空(非空)
ALTER TABLE dat MODIFY num VARCHAR(11) NOT NULL;
#修改字段为空
ALTER TABLE dat MODIFY num VARCHAR(11) NULL;

1. 创建表时添加非空约束
	CREATE TABLE stu(
		id INT,
		NAME VARCHAR(20) NOT NULL -- name为非空
	);
2. 创建表完后,添加非空约束
	ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;
3. 删除NAME的非空约束
	ALTER TABLE stu MODIFY NAME VARCHAR(20);
	
主键约束:PRIMARY KEY。唯一性且不能为空。会和AUTO_INCREMENT自增结合使用。
主键非空且唯一,一张表只能有一个字段为主键,主键就是表中记录的唯一标识。
1.在创建表时,添加主键约束
CREATE TABLE stu(
	id INT PRIMARY KEY,-- 给id添加主键约束
	NAME VARCHAR(20)
);
3. 删除主键
-- 错误 alter table stu modify id int ;
ALTER TABLE stu DROP PRIMARY KEY;
4. 创建完表后,添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY;
5. 自动增长:
1.  概念:如果某一列是数值类型的,使用 AUTO_INCREMENT 可以来完成值得自动增长
2. 在创建表时,添加主键约束,并且完成主键自增长
CREATE TABLE stu(
	id INT PRIMARY KEY AUTO_INCREMENT,-- 给id添加主键约束,并且完成主键自增长
	NAME VARCHAR(20)
);
3. 删除自动增长
ALTER TABLE stu MODIFY id INT;
4. 添加自动增长
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
#标识列:就是自动增长的列,是数据库默认提供的序列。mysql有自动增长oracle没有
#可以在建表的同时,设置主键列为自动增长的列,auto_increment
自动增长默认起始值为1,步长为1。一个表中只能设置一个自动增长的列。
除了主键列之外,还有唯一键约束可以设置自动增长,但只有一个自动增长的列
自动增长的列只支持数值型
在oracle中没有自动增长的列,不管是主键列还是唯一约束列,都不能自动增长。
但是在oracle中提供了一个机制,叫做序列,如果需要使用,必须手动创建 
create sequence 序列名;  创建序列
而后在主键列或者唯一约束列,可以使用序列的值。
insert into info(id,name,name1) values (序列名.nextval,'张无忌','张三');
create sequence java1003; 创建序列
select java1003.nextval from dual;
insert into info(id,name,name1) values (java1003.nextval,'张无忌','张三');



外键约束:FOREIGN KEY,让表与表产生关系,从而保证数据的正确性。
#不能两个表都在创建表时添加外键,另一个表都没有怎么关联得上,会出现引用外键失败。
1. 在创建表时,可以添加外键
语法:
CREATE TABLE 表名(
	....
	外键列
	CONSTRAINT 外键名称 FOREIGN KEY (外键列名称) REFERENCES 主表名称(主键列名称)
);
#constraint约束(为外键取个别名)
CREATE TABLE inn(
  id INT,
  CONSTRAINT abc UNIQUE(id)
);
2. 删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
#删除外键
CREATE TABLE a (
	id INT PRIMARY KEY,
	num FLOAT
);
CREATE TABLE b (
	bid INT ,
	bnum FLOAT,
	CONSTRAINT jkd FOREIGN KEY(bid) REFERENCES a(id)
);
ALTER TABLE b DROP FOREIGN KEY jkd;
3.创建表之后,添加外键
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主键列名称);
#删除外键约束
CREATE TABLE stu2(
	id INT PRIMARY KEY,
	num INT
);
DESC stu2;
CREATE TABLE stu3(
	id INT,
	num INT,
	CONSTRAINT other FOREIGN KEY(id) REFERENCES stu2(id)
);
DESC stu3;
#分两步:先删除外键,再删除索引
ALTER TABLE stu3 DROP FOREIGN KEY other;
ALTER TABLE stu3 DROP INDEX other;

#主键约束:唯一性且不能为空。会和auto_increment自增结合使用。
CREATE TABLE mis(
    phone INT(12) PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(12)
);
#外键约束 foreign key,删除表需要先删除外键约束所在表再删除主键表,先删除外键表再删除主键表
CREATE TABLE class(
	classId  INT PRIMARY KEY,
	className VARCHAR(20)
);
CREATE TABLE student(
	number BIGINT PRIMARY KEY,
	`name` VARCHAR(6),
	score FLOAT,
	id INT,
	FOREIGN KEY(id) REFERENCES class(classId)
);
DROP TABLE student;
DROP TABLE class;

#删除添加和修改主键和unique写法一致	
1. 创建表时,添加唯一约束
CREATE TABLE stu(
	id INT,
	phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束
);
2. 删除唯一约束
ALTER TABLE stu DROP INDEX phone_number;
#错误 ALTER TABLE stu MODIFY phone_number VARCHAR(20);
DESC stu;	
3. 在创建表后,添加唯一约束
#用MODIFY添加唯一约束
ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
#或者用add添加唯一约束
ALTER TABLE stu ADD UNIQUE(id);

#pri/uni/索引(index)。
#建立普通索引方式index ,索引方便查询。 
CREATE TABLE stu1(
	id INT UNIQUE,
	num INT ,
	INDEX(num)
);
ALTER TABLE stu1 DROP INDEX num;
DESC stu1;

#给字段添加注释。COMMENT
CREATE TABLE c (
	id INT COMMENT '员工编号',
	num FLOAT COMMENT '编号记录'
);
#default:设置字段的默认值
CREATE TABLE class1(
    classId INT PRIMARY KEY AUTO_INCREMENT,
    className VARCHAR(20),
    sex CHAR(1) DEFAULT '女'
);
INSERT INTO class1(classId,className) VALUES(NULL,'二班');
SELECT * FROM class1;
#修改表中字段顺序
CREATE TABLE d(
	id INT,
	`name` VARCHAR(6),
	score DOUBLE
);
#修改表。向表中添加字段add 字段名 字段数据类型
ALTER TABLE dat ADD sex CHAR(1);
#添加字段,默认在结尾处追加。要加在什么后面用AFTER
ALTER TABLE d ADD sex CHAR(1) DEFAULT '男';
ALTER TABLE d ADD birthday DATE AFTER score;
DESC d;
#修改顺序modify/after
ALTER TABLE d MODIFY birthday DATE AFTER `name`;

#删除列(字段)。用drop column 列名;  删除表中某个字段列。COLUMN是列的意思
ALTER TABLE dat DROP COLUMN sex;
#修改字段名 change修改列名。CHANGE 旧列名 新列名  数据类型一致
#修改字段名。 用change 不用 modify。
ALTER TABLE dat CHANGE  num xuehao  INT(5)
#修改表名。修改表中字段名用change,修改表名用rename to
ALTER TABLE dat RENAME TO dateki;
DESC dateki; 

1.为student表添加national(民族)字段,char(10),允许为空。
alter table student add national char(10) null;
2.将student表的birthday字段的字段类型改为date。
alter table student modify birthday date;
3.为student表添加主键snumber
alter table student add primary key(snumber);
4.添加唯一约束
alter table student modify sid varchar(20) unique;
或者  alter table student add unique(sid);
删除唯一约束
alter table student drop index sid;
5.为course表的字段“cname”创建索引idx_CName,该索引为唯一索引。
create unique index idx_cname on course(cname);
	

DML(Data Manipulation Language):数据操纵语句

用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等。

DML增删改表中的数据:
增:INSERT INTO TABLE(字段) VALUES(),()..
改:UPDATE TABLE SET 字段=新值 WHERE
删:DELETE  FROM TABLE WHERE
1.添加数据:
语法:INSERT INTO 表名(列名1,列名2,...列名n) VALUES(值1,值2,...值n);
注意:
1. 列名和值要一一对应。
2. 如果表名后,不定义列名,则默认给所有列添加值
	INSERT INTO 表名 VALUES(值1,值2,...值n);
3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来,一般用单引号。
插入数据有2种方式:
方式一:insert into 表名(字段名)values(值);
方式二:insert into 表名 set 列名1=值1,列名2=值2;
语法一支持多行插入,语法二不支持。insert into 表名(字段名)values(值),(值),(值);
方式一支持子查询,方式二只支持单行单列的子查询
#表中插数据
INSERT INTO boys(id,boyName,userCP) VALUES(1,'张飞',100);
INSERT INTO boys VALUES(2,'关羽',130);
INSERT INTO boys(userCP,id,boyName) VALUES(300,12,'刘备');
INSERT INTO boys(id,boyName) VALUES(3,'诸葛亮');
INSERT INTO boys(id,boyName) VALUES(4,'张三'),(5,'李四');
SELECT * FROM boys;

2. 删除数据:
语法:DELETE FROM 表名 [WHERE 条件]
注意:1. 如果不加条件,则删除表中所有记录。
2. 如果要删除所有记录:
1. DELETE FROM 表名; -- 不推荐使用。有多少条记录就会执行多少次删除操作
2. TRUNCATE TABLE 表名; -- 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
#清空数据truncate。直接删除,删的很干净,清空内存空间。一般删除数据还是用delete
#在oracle数据库中,DELETE会保留在回收站一段时间,TRUNCATE直接删除不会保留在回收站中。
truncate 不能做事务回滚,而delete 可以回滚事务。delete 后面可以加where 子句,truncate 不能,因为truncate会直接删除所有数据。
# 1.单表删除
#语法: delete from 表名 [where 子句]
# 范例:删除女生表中id 大于13 的所有的女生
DELETE FROM beauty WHERE id > 13;
# 2.多表删除
/*
 sql92 语法
	delete 表1别名,表2表名  from 表1 别名,表2 别名
	where 连接条件 [and 筛选条件] 
 sql99 语法
	delete 表1别名,表2表名  from 表1 别名 inner | left | right 表2 别名
	on 连接条件 
	[where 子句]
*/
# 92 语法 范例:将张无忌和他的女朋友全部删除
DELETE  a, b FROM boys a,beauty b
WHERE a.`id` = b.`boyfriend_id` 
AND a.`boyName` = '张无忌';
# 99 语法 范例:将张无忌和他的女朋友全部删除
DELETE  a, b FROM boys a INNER JOIN 
beauty b ON a.`id` = b.`boyfriend_id` 
WHERE  a.`boyName` = '黄晓明';

3. 修改数据:
语法:UPDATE 表名 SET 列名1 = 值1, 列名2 = 值2,... [WHERE 条件];
注意:1. 如果不加任何条件,则会将表中所有记录全部修改。
#修改字段信息
UPDATE boys SET boyName =  '张飞',userCP = 137 WHERE boyName = '小黎飞刀';
SELECT * FROM boys;
#2 修改多表记录
/*
 sql 92
  update 表1 别名,表2 别名
  set 列=值 ....
  where 连接条件 
  [and 筛选条件]
 sql 99
   update 表1 别名 inner | left | right join 表2 别名
   on 连接条件
   set 列=值 ....
   [where 筛选条件]
*/
# 范例:将张无忌的颜值该成1000 并且将其女朋友的手机号码改成110
SELECT a.`id`,a.`boyName`,a.`userCP`,b.`name`,b.`phone`
FROM boys a INNER JOIN beauty b 
ON a.`id` = b.`boyfriend_id` WHERE a.`boyName` = '张无忌';
-- sql 99 语法
UPDATE boys a INNER JOIN beauty b 
ON a.`id` = b.`boyfriend_id` 
SET a.`userCP` = 1000,b.`phone`= '110'
WHERE a.`boyName` = '张无忌';
-- sql 92 语法 将张无忌的颜值该成500 并且将其女朋友的手机号码改成120
UPDATE boys a,beauty b 
SET a.`userCP` = 500,b.`phone`= '120'
WHERE a.`id` = b.`boyfriend_id`  AND 
a.`boyName` = '张无忌';

DCL(Data Contron Language):数据控制语句

(DCL用来控制数据库的访问,了解),用于定义用户的访问权限和安全级别,及创建用户。

DCL:管理用户,授权
* DBA:数据库管理员
1. 管理用户
	1. 添加用户:
		* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
	2. 删除用户:
		* 语法:DROP USER '用户名'@'主机名';
	3. 修改用户密码:
			UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';

			UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';

			SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');

			SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');

		* mysql中忘记了root用户的密码?

			1. cmd -- > net stop mysql 停止mysql服务

				* 需要管理员运行该cmd
			
			2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables

			3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功

			4. use mysql;

			5. update user set password = password('你的新密码') where user = 'root';

			6. 关闭两个窗口

			7. 打开任务管理器,手动结束mysqld.exe 的进程

			8. 启动mysql服务

			9. 使用新密码登录。

	4. 查询用户:

		-- 1. 切换到mysql数据库

		USE myql;

		-- 2. 查询user表

		SELECT * FROM USER;

	* 通配符: % 表示可以在任意主机使用用户登录数据库

2. 权限管理:
	1. 查询权限:
		-- 查询权限
			SHOW GRANTS FOR '用户名'@'主机名';
			SHOW GRANTS FOR 'lisi'@'%';
	2. 授予权限:
		-- 授予权限
			grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
		-- 给张三用户授予所有权限,在任意数据库任意表上
			GRANT ALL ON ***.*** TO 'zhangsan'@'localhost';
	3. 撤销权限:
		-- 撤销权限:
			revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
			REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

数据库的备份和还原

1.命令行cmd方式:

备份: mysqldump -u用户名 -p密码 数据库名称 > 保存的路径

还原:

​	1. 登录数据库

​	2. 创建数据库

​	3. 使用数据库

​	4. 执行文件。source 文件路径

2.图形化工具:

你可能感兴趣的:(笔记)