目录
一、理解数据库
二、安装MySQL数据库
三、SQL语句分类
四、DDL
1、数据库
2、数据类型(列类型)
3、表
四、DML
1、插入数据
2、修改数据
3、删除数据
五、DCL
1、创建用户
2、给用户授权
3、撤销授权
4、查看用户权限
5、删除用户
6、修改用户密码
六、DQL
1、基础查询(列控制)
2、条件控制
3、排序
4、聚合函数
5、分组查询
6、LIMIT
七、备份与恢复
八、约束
1、主键约束(非空、唯一、被引用(学习外键时))
2、主键自增长
3、非空约束
4、唯一约束
5、概念模型
6、外键约束
7、数据库一对一关系
8、数据库多对多关系
九、多表查询
1.合并结果集
2、连接查询
1、内连接
2、外连接
3、子查询
1.RDBMS = 管理员 + 仓库
2.database 多个表
3.table: 表结构(列名称和列类型)
表记录(一行一行的记录)
sudo apt install mysql-server-5.7 //安装MySQL
sudo mysql_secure_installation //修改一些MySQL不安全的默认值
然后进入修改界面,它将询问
配置MySQL系统中使用的密码 输入密码
配置VALIDATE PASSWORD PLUGIN 不配置
删除一些匿名用户和测试数据库 按下Y并ENTER键
禁用远程root登录 按下Y并ENTER键
加载这些新规则 按下Y并ENTER键
注意:
VALIDATE PASSWORD PLUGIN
是一种判断调用。如果启用,MySQL将拒绝与指定条件不符的密码并显示错误。如果你将弱密码与自动配置MySQL用户凭据的软件结合使用,例如phpMyAdmin的Ubuntu软件包,则会导致问题。保持禁用验证是安全的,但是你应该始终为数据库凭据使用强大的唯一密码。
注意:在运行MySQL 5.7(及更高版本)的Ubuntu系统中,MySQL的root用户设置为
auth_socket,
默认使用插件进行身份验证,而不是使用密码。这在许多情况提供了更高的安全性和可用性,但是当我们想要使用外部程序(如phpMyAdmin的部署 可以参考博文)访问用户时,就有麻烦了。
将身份验证方法从auth_socket切换为
mysql_native_password:
1.从终端打开Mysql提示符:
mysql -u root -p
2.查看所有MYSQL用户使用的身份验证方法:
SELECT user,authentication_string,plugin,host FROM mysql.user;
3.修改root用户使用密码进行身份验证:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
4.重新加载授权表并使新更改生效:
FLUSH PRIVILEGES;
5.再次检查,确保root用户不再使用auth-socket插件进行身份验证:
SELECT user,authentication_string,plugin,host FROM mysql.user;
6.退出Mysql提示符:exit
windows下安装mysql
DDL(Data Definition Language):数据定义语言,对数据库、表结构的操作!!
DML(Data Manipulation Language):数据操作语言,对表记录进行更新(增删改)!!
DQL(Data Query Language):数据查询语言,对表记录进行查询!!!
DCL(Data Control Language):数据控制语言,对用户的创建及授权
1 查看所有数据库名称:SHOW DATABASES;
2 切换数据库:USE mydb1,切换到mydb1数据库;
3 创建数据库:CREATE DATABASE [IF NOT EXISTS] mydb1 [CHARSET=utf8];
4 删除数据库:DROP DATABASE [IF EXISTS] mydb1;
5 修改数据库编码:ALTER DATABASE mydb1 CHARACTER SET utf8
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99;
decimal:浮点型,在表单钱方面使用该类型,因为不会出现精度缺失问题;
char:固定长度字符串类型,最大255,数据长度不足指定长度,会补足到指定长度。
varchar:可变长度字符串类型,最大65535.
text(clob):[mysql]字符串类型;
类型 |
M |
UNSIGNED |
ZEROFILL |
范围 |
说明 |
tinytext |
yes |
no |
no |
可变长度字符串。 |
|
text |
no |
no |
no |
同上。 |
|
mediumtext |
no |
no |
no |
同上。 |
|
longtext |
no |
no |
no |
同上。 |
blob:二进制字节类型;
类型 |
M |
UNSIGNED |
ZEROFILL |
范围 |
说明 |
tinyblob |
no |
no |
no |
(256B) |
可变长度二进制类型。 |
blob |
no |
no |
no |
(64K) |
同上 |
mediumblob |
no |
no |
no |
(16M) |
同上 |
longblob |
no |
no |
no |
(4G) |
同上 |
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型;既有时分秒又有年月日
1 创建表:
CREATE TABLE 表名(
列名 列类型,
列名 列类型,
......
);
2 查看当前数据库中所有表名称:SHOW TABLES;
3 查看指定表的创建语句:SHOW CREATE TABLE emp,查看emp表的创建语句;
4 查看表结构:DESC emp,查看emp表结构;
5 删除表:DROP TABLE emp,删除emp表;
6 修改表
前缀:ALTER TABLE 表名:
修改之添加列:
ADD (
列名 列类型,
列名 列类型,
列名 列类型
);
给stu表添加classname列:ALTER TABLE stu ADD (classname varchar(100));
修改之删除列:
DROP 列名;
删除stu表的classname列:ALTER TABLE stu DROP classname;
修改之修改列类型:
MODIFY 列名 列新的类型
修改stu表的gender列类型为CHAR(2):ALTER TABLE stu MODIFY gender CHAR(2);
修改之修改列名:
change 列名 新列名 列类型;
修改stu表的gender列名为sex:ALTER TABLE stu change gender sex CHAR(2);
修改之修改表名称:
RENAME TO 新列名;
修改stu表名称为student:ALTER TABLE stu RENAME TO student;
INSERT INTO 表名(列名1,列名2, …) VALUES(值1, 值2,.....)
在数据库中所有的字符串类型,必须使用单引,不能使用双引!日期类型也要使用单引!
// 插入所有列
INSERT INTO stu(
number, name, age, gender
)
VALUES(
'ITCAST_0001', 'zhangSan', 28, 'male'
);
// 插入部分列,没有指定的列默认为NULL值
INSERT INTO stu(
number, name
) VAKLUES(
'ITCAST_0002', 'liSi'
)
// 不给出插入列,那么默认为插入所有列!值的顺序要与创建表时列的顺序相同
INSERT INTO stu VALUES(
'ITCAST_0003', 'wangWu', 82, 'female'
);
UPDATE 表名 SET 列名1=值1, … 列名n=值n [WHERE 条件]
条件(条件可选的):
> 条件必须是一个boolean类型的值或表达式:UPDATE t_person SET gender='男', age=age+1 WHERE sid='1';
> 运算符:=、!=、<>、>、<、>=、<=、BETWEEN...AND、IN(...)、IS NULL、NOT、OR、AND
WHERE age >= 18 AND age <= 80
WHERE age BETWEEN 18 AND 80
WHERE name='zhangSan' OR name='liSi'
WHERE name IN ('zhangSan', 'liSi')
WHERE age IS NULL, 不能使用等号
WHERE age IS NOT NULL
DELETE FROM 表名 [WHERE 条件]; 不加where删除整个表
CREATE USER 用户名@IP地址 IDENTIFIED BY '密码';
用户只能在指定的IP地址上登录
CREATE USER 用户名@'%' IDENTIFIED BY '密码';
用户可以在任意IP地址上登录
GRANT 权限1, … , 权限n ON 数据库.* TO 用户名@IP地址
给用户分派在指定的数据库上的指定的权限
例如;GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON mydb1.* TO user1@localhost;
给user1用户分派在mydb1数据库上的create、alter、drop、insert、update、delete、select权限
GRANT ALL ON 数据库.* TO 用户名@IP地址;
给用户分派指定数据库上的所有权限
REVOKE 权限1, … , 权限n ON 数据库.* FROM 用户名@IP地址;
撤消指定用户在指定数据库上的指定权限
例如;REVOKE CREATE,ALTER,DROP ON mydb1.* FROM user1@localhost;
撤消user1用户在mydb1数据库上的create、alter、drop权限
SHOW GRANTS FOR 用户名@IP地址
查看指定用户的权限
DROP USER 用户名@IP地址
USE mysql;
UPDATE USER SET PASSWORD=PASSWORD(‘密码’) WHERE User=’用户名’ and Host=’IP’;
FLUSH PRIVILEGES;
1)查询所有列
SELECT * FROM 表名;
SELECT * FROM emp;
2) 查询指定列
SELECT 列1 [, 列2, ... 列N] FROM 表名;
SELECT empno, ename, sal, comm FROM 表名;
3) 完全重复的记录只一次
SELECT DISTINCT * | 列1 [, 列2, ... 列N] FROM 表名;
SELECT DISTINCT sal FROM emp;
4) 列运算
a.数量类型的列可以做加、减、乘、除运算
SELECT sal*1.5 FROM emp;
SELECT sal+comm FROM emp;
b.字符串类型可以做连接运算
SELECT CONCAT('$', sal) FROM emp;
c.转换NULL值
有时需要把NULL转换成其它值,
SELECT IFNULL(comm, 0)+1000 FROM emp;
=>IFNULL(comm, 0):如果comm中存在NULL值,那么当成0来运算。
d.给列起别名
当使用列运算后,查询出的结果起个别名
SELECT IFNULL(comm, 0)+1000 AS 奖金 FROM emp;
=>其中AS可以省略
1) 条件查询
在WHERE子句中可以使用如下运算符及关键字:
- =、!=、<>、<、<=、>、>=;
- BETWEEN…AND;
- IN(set);
- IS NULL;
- AND;
- OR;
- NOT;
与前面的UPDATE和DELETE语句一样,SELECT语句也可以使用WHERE子句来控制记录。
SELECT empno,ename,sal,comm FROM emp WHERE sal > 10000 AND comm IS NOT NULL;
SELECT empno,ename,sal FROM emp WHERE sal BETWEEN 20000 AND 30000;
SELECT empno,ename,job FROM emp WHERE job IN ('经理', '董事长');
2) 模糊查询
模糊查询需要使用运算符:LIKE,其中_匹配一个任意字符,%匹配0~N个任意字符
SELECT * FROM emp WHERE ename LIKE '张_';/*名字由两个字组成的员工*/
SELECT * FROM emp WHERE ename LIKE '___'; /*姓名由3个字组成的员工*/
SELECT * FROM emp WHERE ename LIKE '张%';/*姓张的所有员工*/
SELECT * FROM emp WHERE ename LIKE '%阿%';
--> 查询姓名中间带有阿字的员工,因为%匹配0~N个字符,所以姓名以阿开头和结尾的员工也都会查询到。
SELECT * FROM emp WHERE ename LIKE '%';
--> 这个条件等同与不存在,但如果姓名为NULL的查询不出来!
1) 升序
SELECT * FROM emp ORDER BY sal ASC;
=> 按sal排序,升序,ASC是可以省略的
2) 降序
SELECT * FROM emp ORDER BY comm DESC;
=> 按comm排序,降序,其中DESC不能省略
3) 使用多列作为排序条件
SELECT * FROM emp ORDER BY sal ASC, comm DESC;
=> 使用sal升序排,如果sal相同时,使用comm的降序排序
聚合函数用来做某列的纵向运算。
1) COUNT
SELECT COUNT(*) FROM emp;
--> 计算emp表中所有列都不为NULL的记录的行数
SELECT COUNT(comm) FROM emp;
--> 计算emp表中comm列不为NULL的记录的行数
2) MAX
SELECT MAX(sal) FROM emp;
--> 查询最高工资
3) MIN
SELECT MIN(sal) FROM emp;
--> 查询最低工资
4) SUM
SELECT SUM(sal) FROM emp;
--> 查询工资合
5) AVG
SELECT AVG(sal) FROM emp;
--> 查询平均工资
分组查询是把记录使用某一列进行分组,然后查询组信息。组信息包括分组列和聚合函数。
例如:查看所有部门的记录数。
SELECT deptno, COUNT(*) FROM emp GROUP BY deptno;
SELECT job, MAX(SAL) FROM emp GROUP BY job; => 使用job分组,查询每种工作的最高工资
以部门分组,查询每组记录数。条件为记录数大于3
SELECT deptno, COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 3;
注意,WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。
执行顺序
select
from
where
group by
having
order by
LIMIT用来限定查询结果的起始行,总行数。
SELECT * FROM emp LIMIT 4, 3; /*查询起始行为第5行,一共查询3行记录*/
一页的记录数:10行,查询第3页: select * from emp limit 20, 10; /* (当前页-1) * 每页记录数*/
1. 备份数据库导出SQL脚本(备份数据库内容,并不是备份数据库!)
mysqldump –u用户名 –p密码 数据库名>生成的脚本文件路径
例如:mysqldump -uroot -p123 mydb1>C:\mydb1.sql (与mysql.exe和mysqld.exe一样, 都在bin目录下)
注意,生成的脚本文件中不包含create database语句
2. 恢复执行SQL脚本
第一种方式不登录mysql
mysql -u用户名 -p密码 数据库<脚本文件路径
例如:先删除mydb1库,再重新创建mydb1库
mysql -uroot -p123 mydb1
第二种方式登录mysql
source SQL脚本路径
例如:先删除mydb1库,再重新创建mydb1库:切换到mydb1库,source c:\mydb1.sql
创建表时指定主键的两种方式:指定sid列为主键列,即为sid列添加主键约束
CREATE TABLE stu(
sid CHAR(6) PRIMARY KEY,
sname VARCHAR(20),
age INT,
gender VARCHAR(10)
);
CREATE TABLE stu(
sid CHAR(6),
sname VARCHAR(20),
age INT,
gender VARCHAR(10),
PRIMARY KEY(sid)
);
修改表时指定主键:ALTER TABLE stu ADD PRIMARY KEY(sid);
删除主键:ALTER TABLE stu DROP PRIMARY KEY;
创建表时指定主键自增长
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20),
age INT,
gender VARCHAR(10)
);
因为某些列不能设置为NULL值,所以可以对列添加非空约束。
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL,
age INT,
gender VARCHAR(10)
);
车库某些列不能设置重复的值,所以可以对列添加唯一约束。
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL UNIQUE,
age INT,
gender VARCHAR(10)
);
对象模型:可以双向关联,而且引用的是对象,而不是一个主键!
关系模型:只能多方引用一方,而且引用的只是主键,而不是一整行记录。
当我们要完成一个软件系统时,需要把系统中的实体抽取出来,形成概念模型。
例如部门、员工都是系统中的实体。概念模型中的实体最终会成为Java中的类、数据库中表。
外键必须是另一表的主键的值(外键要引用主键!)
外键可以重复
外键可以为空
一张表中可以有多个外键!
语法:CONSTRAINT 约束名称 FOREIGN KEY(外键列名) REFERENCES 关联表(关联表的主键)
⚪创建表时指定外键约束
create talbe emp (
empno int primary key,
deptno int,
CONSTRAINT fk_emp FOREIGN KEY(mgr) REFERENCES emp(empno)
);
⚪修改表时添加外键约束
ALERT TABLE emp
ADD CONSTRAINT fk_emp_deptno FOREIGN KEY(deptno) REFERENCES dept(deptno);
⚪修改表时删除外键约束
ALTER TABLE emp
DROP FOREIGN KEY fk_emp_deptno;
在表中建立一对一关系比较特殊,需要让其中一张表的主键,即是主键又是外键。
create table husband(
hid int PRIMARY KEY,
...
);
create table wife(
wid int PRIMARY KEY,
...
ADD CONSTRAINT fk_wife_wid FOREIGN KEY(wid) REFERENCES husband(hid)
);
其中wife表的wid即是主键,又是相对husband表的外键!
husband.hid是主键,不能重复!
wife.wid是主键,不能重复,又是外键,必须来自husband.hid。
在表中建立多对多关系需要使用中间表,即需要三张表,在中间表中使用两个外键,分别引用其他两个表的主键。
create table student(
sid int PRIMARY KEY,
...
);
create table teacher(
tid int PRIMARY KEY,
...
);
create table stu_tea(
sid int,
tid int,
ADD CONSTRAINT fk_stu_tea_sid FOREIGN KEY(sid) REFERENCES student(sid),
ADD CONSTRAINT fk_stu_tea_tid FOREIGN KEY(tid) REFERENCES teacher(tid)
);
这时在stu_tea这个中间表中的每条记录都是来说明student和teacher表的关系
例如在stu_tea表中的记录:sid为1001,tid为2001,这说明编号为1001的学生有一个编号为2001的老师
sid tid
101 201 /*编号为101的学生有一个编号为201的老师*/
101 202 /*编号为101的学生有一个编号为202的老师*/
101 203 /*编号为101的学生有一个编号为203的老师*/
102 201 /*编号为102的学生有一个编号为201的老师*/
102 204 /*编号为102的学生有一个编号为204的老师*/
要求被合并的表中,列的类型和列数相同
UNION,去除重复行
UNION ALL,不去除重复行
SELECT * FROM cd
UNION ALL
SELECT * FROM ab;
笛卡尔积
{a,b,c} {1,2}
{a1,a2,b1,b2,c1,c2}
可以使用条件where来去除无用的笛卡尔积
SELECT emp.ename,emp.comm,dept.dname
FROM emp,dept
WHERE emp.deptno=dept.deptno;SELECT e.ename,e.comm,d.dname
FROM emp e,dept d
WHERE e.deptno=d.deptno;
SELECT e.ename,comm,d.dname
FROM emp e INNER JOIN dept d
ON e.deptno=d.deptno
SELECT e.ename,comm,d.dname
FROM emp e NATURAL JOIN dept d实现:找两个表中列名完全相同的列进行自动匹配
外连接有一主一次,左外即左表为主,右外即右表为主。
主表中的所有的记录无论满不满足条件,都打印出来;
当不满足条件时,从表使用NULL来补位。
SELECT e.ename,e.comm,IFNULL(d.dname,'无部门') AS dname
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno=d.deptno
UNION
SELECT e.ename,e.comm,IFNULL(d.dname,'无部门') AS dname
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno=d.deptno
查询中有查询(查看select关键字的个数!)
SELECT * FROM emp WHERE sal=(SELECT MAX(sal) FROM emp);/*单行单列*/
SELECT e.empno,e.ename
FROM (SELECT * FROM emp WHERE deptno=30) e/*多行多列*/
2. 条件