1.数据库介绍
什么是数据库?
存储数据的介质(存储数据的软件)
数据库软件系统的作用:
- 方便我们操作者去对数据进行快速的保存(存储)、查询、修改、统计分析
- 不同的数据软件对不同的数据以及查询方式等等有不同的优化
2.数据库类型有些什么?
- 关系型数据库:(MySQL、Oracle、SQLSever、MSAccess、pgSQL)
- 基础存储模式就是二维表的存储模式(行(数据):每一行数据就代表一条数据;列(字段):每一列代表一种类型的数据);
- 关系型:表与表之间会产生联系联系(一对多、多对一、多对多、一对一)
- 非关系型数据库:(MongoDB、HBase、FastHDsf)(文档类数据(json)、音视频文件、二进制文件)
- 存储东西是什么:文档类数据(json)、音视频文件、二进制文件
3.MySQL5.7(压缩版)
3.1mysql安装
- 解压压缩包到非C盘目录
- 配置环境变量
- MYSQL_HOME:解压的mysql文件根目录
- path目录下添加根目录下bin文件夹目录地址
- 在根目录下创建一个空的data文件夹
- 把准备好的my.ini拷贝到根目录下,修改my.ini文件
[mysql]
#设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306
#日志
general_log=1
general_log_file=F:\mySQL\mysql-5.7.34-win32\logs\mysql_general_log.log
#设置mysql的安装目录(!!!!!!!!!!!!!!!!!修改!!!!!!!!!!!!!!!!!!!!)
basedir=F:\mySQL\mysql-5.7.34-win32
#设置mysql数据的存放目录(!!!!!!!!!!!!!!!!修改!!!!!!!!!!!!!!!!!!!!!)
datadir=F:\mySQL\mysql-5.7.34-win32\data
#允许最大连接数
max_connections=200
#服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
#创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
secure_file_priv=
sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
使用管理员权限打开命令控制行
初始化mysql数据库,且创建一个无密码的root账号
注意:初始化后观察data文件夹下是否有东西生成,重点注意有没有三个文件夹生成
mysqld --initialize-insecure
- 在windows上安装服务
看提示是否为:Service successful installed
用任务管理器查看-》服务-》有没有mysql名字的服务
mysqld -install
启动服务
MySQL服务正在启动.. MySQL服务已经启动成功。
net start mysql
3.2 mysql的卸载
- 停止服务 net stop mysql
- 删除mysql根目录下的data文件夹中的所有内容
- 使用管理员权限打开命令控制行:SC delete mysql
4. 连接数据库
通过命令行连接数据库的方法:
mysql -h服务器的地址(访问本机不用写) -u用户名 -p密码
通过命令行退出数据库方法:
mysql> exit;
5. 数据库root用户密码的修改
- 使用root账号连接上数据库
- 进入mysql数据仓库: use mysql;
- 修改root的密码
5.1 通过管理员给用户设置密码(必须要用root账号来操作)
set password for '用户名'@'host值' = password('新密码');
如:set password for 'root'@'localhost' = password('root123456');
设置完成之后一定要执行:
flush privileges;
mysql数据仓库中user表的一些字段解释
User: 数据库用户名
host:当前用户允许访问的主机地址(如:localhost代表只能服务所在的本机能够访问,%:所有的计算机都可以使用该账号访问数据库)
authentication_string:密码加密字段,旧版(mysql5以前的版本,密码字段是:password)
5.2 借助SQL的表数据修改语句修改root密码
update 表名 set 字段名=新字段值 where 字段='root';
如:update user set authentication_string=password('cxk666') where user='root';
设置完成之后一定要执行:
flush privileges;
6. 忘记root密码(只能跳过登录密码验证设置新密码无法找回旧密码)
要强制让mysql允许无密码启动
修改my.ini配置文件: 在[mysqld] 下添加
[mysqld]
skip-grant-tables
重启mysql服务
7.SQL语句组成
SQL(Structured Query Language):结构化查询语言
DML**(数据操作语言)** | 用来操作数据库中所包含的数据 | INSERTUPDATEDELETE |
---|---|---|
DDL**(数据定义语言)** | 用于创建和删除数据库对象等操作 | CREATEDROPALTER |
DQL**(数据查询语言)** | 用来对数据库中的数据进行查询 | SELECT |
DCL**(数据控制语言)** | 用来控制数据库组件的存取许可、存取权限等 | GRANT revokeCOMMITROLLBACK |
8.SQL的所有运算符
8.1 算数运算符
运算符 | 说 明 |
---|---|
+ | 加运算,求两个数或表达式相加的和,如****6+8 |
- | 减运算,求两个数或表达式相减的差 |
***** | 乘运算,求两个数或表达式相乘的积 |
/ | 除运算,求两个数或表达式相除的商,如5/3的值为****1 |
% | 取模运算,求两个数或表达式相除的余数,如:5%3的值为****2 |
8.2 赋值运算符
运算符 | 说 明 |
---|---|
= | **把一个数或变量或表达式赋值给另一变量,**如:Name=‘王华’ |
8.3 逻辑运算符
运算符 | 说 明 |
---|---|
AND 与 | 当且仅当两个布尔表达式都为true时,返回TRUE。 |
OR 或 | 当且仅当两个布尔表达式都为false,返回FALSE。 |
NOT 非 | 布尔表达式的值取反 |
8.4 比较运算符
运算符 | 说 明 |
---|---|
= 注意 | **等于,例如:**age=23 |
> | **大于,例如:**price>100 |
< | 小于 |
**<> **注意 | 不等于 |
>= | 大于等于 |
<= | 小于等于 |
**!= **注意(不能使用) | 不等于(非SQL-92****标准 ) |
运算符号优先级(从低到高)
优先级由低到高排列 | 运算符 |
---|---|
1 | =(赋值运算)、:= |
2 | II、OR |
3 | XOR |
4 | &&、AND |
5 | NOT |
6 | BETWEEN、CASE、WHEN、THEN、ELSE |
7 | =(比较运算)、<=>、>=、>、<=、<、<>、!=、 IS、LIKE、REGEXP、IN |
8 | | |
9 | & |
10 | <<、>> |
11 | -(减号)、+ |
12 | *、/、% |
13 | ^ |
14 | -(负号)、〜(位反转) |
15 | ! |
9.MySQL系统默认数据库
information_schema:主要存储系统中的一些数据库对象信息,如用户表信息、字段信息、权限信息、字符集信息和分区信息等;视图、过程、函数
performance_schema:主要存储数据库服务器性能参数
mysql:主要存储系统的用户权限信息
sys:存储的是数据库软件系统参数;字典配置
10. DDL语句
10.1 创建数据库
create database 数据库名;
如:create database cxk; 结束的分号在sql语句结束时一定要编写
create database `mabaoguo`; 斜点标识符号:用于描述一个字段、表、数据库名字的时候使用
10.2 查看已有的数据仓库
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| cxk |
| cxk2 |
| mabaoguo |
| mysql |
| performance_schema |
| sys |
+--------------------+
10.3 切换数据仓库
之后sql语句的数据操作首先要选择一个数据库再进行操作
use 数据库名;
如:use cxk; 切换到cxk数据库了
10.4 删除数据库
drop database 数据库名称;
如:drop database cxk; 把cxk数据库以及该数据库下的所有数据删除了
10.5数据表操作
(1)mysql的字段数据类型
- 整型:常用类型 int
TINYINT | 非常小的数据 | 有符值: -2****7 ~ 27-1 无符号值:0 ~ 28**-1** | 1****字节 |
---|---|---|---|
SMALLINT | 较小的数据 | 有符值: -2****15 ~ 215-1 无符号值: 0 ~ 216-1 | 2****字节 |
MEDIUMINT | 中等大小的数据 | 有符值: -2****23 ~ 223-1 无符号值: 0 ~ 224-1 | 3****字节 |
INT | 标准整数 | 有符值: -2****31 ~ 231-1 无符号值:0 ~ 232**-1** | 4****字节 |
BIGINT | 较大的整数 | 有符值: -2****63 ~263-1无符号值:0 ~264-1 | 8****字节 |
- 浮点型:常用的double ,如果出现浮点类型字段要计算使用decimal类型
FLOAT | 单精度浮点数 | ±1.1754351e -38 | 4****字节 |
---|---|---|---|
DOUBLE | 双精度浮点数 | ±****2.2250738585072014e -308 | 8****字节 |
DECIMAL | 字符串形式的浮点数 | Decimal**(M,D)** | M+2****个字节 |
字符串类型:常用varchar类型
char:固定长度字符类型(不看实际的数据类型,只按照字段定义的长度来开辟空间)
varchar:可变长度字符类型(根据实际存储的数据来开辟空间存储)
CHAR[(M)] | 定长字符串 | M****字节 |
---|---|---|
VARCHAR[(M)] | 可变字符串 | 可变长度 |
TINYTEXT | 微型文本串 | 0~28–1****字节 |
TEXT | 文本串 | 0~216–1****字节 |
- 日期类型:常用类型 datetime
DATE | YYYY-MM-DD**,日期格式** | 1000-01-01~ 9999-12-31 |
---|---|---|
DATETIME | YY-MM-DD hh:mm:ss | 1000-01-01 00**:00:00 ~9999-12-31 23:59:**59 |
TIME | hh:mm:ss | -835:59:59 ~ 838:59:59 |
TIMESTAMP | YYYYMMDDHHMMSS | 1970年某时刻~2038年某时刻,精度为1****秒 |
YEAR | YYYY****格式的年份 | 1901~2155 |
- 布尔类型 : boolean
6.枚举类型 : enum(‘枚举值1’,‘枚举值2’,…)
`Select_priv` enum('N','Y')
(2)数据表的创建
表名、字段名、数据库名的命名方法严格按照java的标识符命名规则使用,按照驼峰规则使用
特殊: 逻辑主键字段命名:实体描述+ID,如:studentID、goodsID
create table `数据表的名称`(
`字段1名称` 数据类型(定义数据大小),
`字段2名称` 数据类型(定义数据大小)int(3)
);
create table `person`(
`userName` varchar(10),
`age` int(3)
);
查看当前数据库中有哪些表:show tables;
树形结构数据表创建案例
create table `t_goods_category`(
`categoryID` VARCHAR(50) PRIMARY KEY COMMENT '商品分类id',
`code` VARCHAR(80) not null UNIQUE KEY COMMENT '分类编号',
`name` VARCHAR(80) not null COMMENT '分类名称',
`parentID` VARCHAR(50) not null COMMENT '父级id,如果是最父级值为-1',
`innerCode` VARCHAR(200) not null COMMENT '树形编码'
);
字段约束
非空约束 | NOT NULL | 字段不允许为空 |
---|---|---|
默认约束 | DEFAULT | 赋予某字段默认值 |
唯一约束 | UNIQUE KEY(UK) | 设置字段的值是唯一的 允许为空,但只能有一个空值 |
主键约束 | PRIMARY KEY(PK) | 设置该字段为表的主键****可唯一标识该表记录 |
外键约束 | FOREIGN KEY(FK) | 用于在两表之间建立关系, 需要指定引用主表的哪一字段 |
自动增长 | AUTO_INCREMENT | 设置该列为自增字段 默认每条自增****1 **通常用于设置主键整形、唯一约束或主键约束 ** |
给字段添加约束
create table `person`(
`personID` VARCHAR(20) PRIMARY KEY,/* 一般使用javaUUID填充 */
`userName` varchar(10) NOT NULL UNIQUE KEY,/* 非空且唯一,约束可以设置多个 */
`age` int(3) DEFAULT 18 COMMENT '年龄',/* 注释,只能添加在约束之后 */
`studentCode` int(5) UNIQUE KEY,
`code` int(5) UNIQUE KEY AUTO_INCREMENT /* 自增列必须有唯一约束或主键约束字段才能设置 */
)COMMENT='人员信息表';
查看表字段设计:desc 表名;
检查性约束(MySQL 没有效果)
check(约束的条件)
在创建表的时候规定好
/* 1. 创建表的时候创建检查性约束 */
create table `user`(
age int(2) not null check(age<10 and age>0)
)
(3)删除表
drop table 表名;
(4)修改表
1. 修改表名
alter table `旧表名` rename `新表名`;
alter table `student` rename `cxk`;
2. 添加字段
alter table `要添加字段的表名` add 字段名 数据类型(定义长度) 约束 注解;
alter table `cxk` add `age` int(3) not null COMMENT '年龄';
3.修改字段
/*1. 修改字段名称*/
/* 只是新字段名变了,其他的如数据类型、定义长度、约束、注解描述都要保持不变 */
alter table `cxk` CHANGE `name` `userName` varchar(2) NOT NULL;
/*2. 修改字段类型*/
alter table `cxk` CHANGE `name` `name` VARCHAR(50) PRIMARY KEY COMMENT '用户名2';
4.删除字段
ALTER TABLE 表名 DROP 字段名;
ALTER TABLE `cxk` DROP `userName`;
5. 在创建表之后添加单个主键约束的方法
/* 1 借助修改字段方法,给字段添加上主键约束 */
# 给cxk表的code字段修改为主键
ALTER TABLE `cxk` CHANGE `code` `code` varchar(255) PRIMARY KEY;
/* 2 修改字段方法-添加主键约束 */
ALTER TABLE `cxk` add PRIMARY KEY(`code`);
/* 3 修改表方法-添加字段约束 */
ALTER TABLE 表名 ADD CONSTRAINT 主键名
PRIMARY KEY 表名(主键字段);
ALTER TABLE `cxk` ADD CONSTRAINT `pk_jinitaimei`
PRIMARY key `cxk`(`code`);
6.删除表的主键约束
删除了表的主键约束之后,原主键字段还会保留一个非空约束(斩草没除根)还需要使用修改字段的方法将非空约束去除
alter table `表名` drop primary key;
(5)添加联合主键的方法
联合主键的作用:复杂表中,使用多个字段作为主键;目的是使用多个字段的唯一性来标识每行数据是独一无二的
1. 在创建表的时候添加联合主键
create table `person`(
`code` int(4),
`name` VARCHAR(10),
PRIMARY KEY(`code`,`name`)
);
2. 创建表之后设置联合主键
/* 1 修改字段方法-添加主键约束 */
ALTER TABLE `cxk` add PRIMARY KEY(`code`,`age`);
/* 2 修改表方法-添加字段约束 */
ALTER TABLE 表名 ADD CONSTRAINT 主键名
PRIMARY KEY 表名(主键字段,主键字段2...);
ALTER TABLE `cxk` ADD CONSTRAINT `pk_jinitaimei`
PRIMARY key `cxk`(`code`,`userName`);
(6)添加外键的方法
什么是外键:两张表之间关联字段数据的约束规则
alter table `从表名` add FOREIGN KEY (`从表中需要关联的字段名称`)
REFERENCES `主表名`(`主表的关联字段名`);
alter table `t_dept` add FOREIGN KEY (`deptManager`)
REFERENCES `t_user`(`userID`);
外键删除更新约束
CASCADE: 从表或主表当删除或更新时,自动删除或更新匹配的数据 (推荐:一般设置在更新操作,不设置删除操作)
SET NULL: 主表 删除或更新时,设置从表关联的数据为null (作用:一旦修改马上解除数据关联) (推荐:更新不设置,删除的时候推荐设置)
RESTRICT: 拒绝所有主表的关联数据删除、更新操作
NO ACTION: 拒绝所有主表的关联数据删除、更新操作
如果要设置更新、删除约束
推荐设置: 更新-》CASCADE 删除-》SET NULL
alter table `t_dept` add FOREIGN KEY (`deptManager`)
REFERENCES `t_user`(`userID`)
on delete set null
on update CASCADE;
设置外键的问题:
- 保证从表和主表的关联字段类型、长度、约束必须完全相同
- 在添加外键时,最好表里不要有数据
- 在添加删除或修改关联约束时,如果从表字段有非空约束,就不能使用SET NULL规则
11.DML语句
11.1 MySQL数据引擎
默认是:InnoDB引擎
MyISAM: 支持全文索引,但是不支持事务、外键、行锁定;使用场景:查询多是使用
InnoDB:支持事务、外键、行锁定;增删改多时使用
设置表的数据引擎
CREATE TABLE `javatest`.`Untitled` (
`userID` int(2) NOT NULL COMMENT '员工编号',
`userName` varchar(255) COMMENT '员工姓名',
PRIMARY KEY (`userID`)
) ENGINE = MyISAM 设置引擎
11.2 数据插入语句-单行插入
插入语句不管是单行还是多行插入:最好指定要插入的字段名,因为表结构可能会发生变化
/* 全表字段插入 值的顺序按照数据表定义字段的顺序写*/
insert into `t_java` VALUES ('01','周杰伦',18,'三年一班');
/* 指定字段插入 值顺序按照指定字段的顺序编写 */
insert into `t_java` (`name`,`code`) VALUES ('周杰伦','01');
11.3 数据插入语句-多行插入
insert into `t_java` VALUES ('01','周杰伦',18,'三年一班'),('02','吴亦凡',18,'朝阳区人民法院');
11.4 数据查询结果存入新表中(配合查询语句使用)
create table `新表名`(
放查询语句
);
如:
create table `newTable`(
select * from `t_java`
);
11.5 更新语句
修改某张表的某几行或一行中的某几个字段为新值
如果更新语句不写条件就代表全表更新(危险操作!)
update `表名` set `字段名`='修改的值',`字段名`='修改的值' where 条件;
/* 更新条件的编写 */
update `t_java` set `name`='阿巴阿巴' where `name`='周杰伦';
# 年龄大于16岁 且 班级是三年一班的同学名字改为卢本伟
update `t_java` set `name`='卢本伟'
where `age`>16
and `className`='三年一班';
# 年龄大于16岁 或者 班级是三年一班的同学名字改为卢本伟
update `t_java` set `name`='卢本伟'
where `age`>16
or `className`='三年一班';
# 年龄不大于16岁的同学名字改为周杰伦
update `t_java` set `name`='周杰伦'
where not `age`> 16;
案例
create table `student`(
`id` VARCHAR(20) PRIMARY KEY,
`name` VARCHAR(10),
`sex` int(1) COMMENT '1:男 2:女 ',
`age` int(3),
`className` VARCHAR(20),
`score` int(3),
`grade` VARCHAR(10) COMMENT '字段值是:A B C D'
);
/*
1.批量插入5个学生的数据
2. 修改语句1:将1班学生成绩大于60分且小于90分的同学grade字段设置为B
3. 修改语句2:将1班和2班中所有性别为男的学生姓名修改为卢本伟
4. 修改语句3: 将1班和2班中成绩小于60分或成绩大于100分的学生grade字段设置为A
*/
INSERT INTO student VALUES ('1001','路飞',1,18,'2班',60,'D'),
('1002','索隆',1,21,'2班',80,'B'),
('1003','娜美',2,19,'1班',100,'A'),
('1004','罗宾',2,37,'1班',100,'A'),
('1005','乔巴',1,9,'1班',95,'A');
#将1班学生成绩大于60分且小于90分的同学grade字段设置为B
update `student` set `grade`='B'
where `className`= '1班'
and `score`>60&&`score`<90;
UPDATE `student` SET `grade` = 'B'
WHERE `className` = '1班'
AND (`score` > 60 AND `score` < 90);
# 将1班和2班中所有性别为男的学生姓名修改为卢本伟
# mysql 逻辑运算符号优先级 not>and>or
update `student` set `name`='卢本伟'
where sex = 1
and (className = '1班'
or className = '2班');
#将 1班 和 2班 中 成绩 小于60分 或 成绩大于100分 的学生grade字段设置为A
# 班级= 1班 or 2班
# and
# 成绩 小于60分 or 成绩大于100分
update `student` set `grade`='A'
where (className='1班'
or className='2班')
and
(`score`<60 or`score` >100)
# 查询年龄小于等于19或大于等于22的学生 且 学生在1班
select * from student
where
(age<=19 or age>=22) and className='1班';
# 因为and运算符的优先级高于or运算符 所以要加小括号
11.6 数据删除语句
/* 条件删除语句 */
/* 如果没有条件就代表删除表中所有数据 */
/* 该删除语句不会重置自增序列 */
DELETE FROM 表名 [WHERE条件];
DELETE FROM student WHERE studentName = ‘王宝宝’;
/* 清空表操作 */
/* 重置自增列、删除所有数据 */
TRUNCATE TABLE 表名;
开发中的逻辑删除
在表中会定义一个字段,描述数据是否被删除:isDelete int(1) default 0 comment ’ 0:未删除 1:已删除 ’
/* 逻辑删除使用更新语句,将数据表中的isDelete字段设置为1即可 */
update student set isDelete = 1 where 条件;
12.DQL语句
SELECT <字段名列表>FROM <表名或视图>
[WHERE <查询条件>]
[[GROUP BY <分组的字段名>]
[HAVING <条件>]
[[ORDER BY <排序的列名> [ASC 或 DESC]]
[LIMIT [位置偏移量,]行数];
12.1 投影字段查询
select `name`,`age` from `student`
12.2 条件查询
select `name`,`age` from `student`
where age>18;
查询条件的使用(条件的写法适用于DML)
(1)使用关系运算符和逻辑运算符查询
/* 使用关系运算符和逻辑运算符查询 */
select `name`,`age` from `student`
where age>18
and age<80;
(2) 模糊查询
/*模糊查询 */
/* 关键字:like */
/*
匹配方法: '李%' 以李开头的文字进行匹配
'%李' 以李结尾的文字进行匹配
'%李%' 包含李的文字进行匹配
*/
select * from `student`
where name like '%李%'
(3) in 、 not in 存在于和不存在于
/* 和、包含 in */
/* 查询学生信息包括18、19、20岁的人 */
select * from `student`
where age in (18,19,20);
/* 除哪些之外 not in */
/* 查询学生信息除了18、19、20岁的人 */
select * from `student`
where age not in (18,19,20);
(4) is null 和 is not null 为空或不为空判断
在插入数据和更新数据时,''代表的是空字符串不是null,只有直接赋值null才是空的意思
如:update
student
setname
=null where id=1;
/* 查询字段为空的条件 */
select * from `student`
where `name` is null; /* 不要使用`name` = null 千万不要使用 */
/* 查询字段不为空的条件 */
select * from `student`
where `name` is not null;
(5)between x and x 在某两个数之间的条件 区间查询条件
BETWEEN 19 and 23 的两个数值都包含
select * from student
where age BETWEEN 19 and 23;
12.3 查询结果排序
select `name`,`age` from `student`
where age>18
order by `要排序的字段` [ASC 升序 或 DESC 降序]
如:
select `score`,`age` from `student`
order by `age` desc,`score` asc ;
12.4 查询投影使用别名
select `score` as `成绩`,`age` as `年龄`
from `student`
order by `age` desc,`score` asc ;
12.5 查询表名取别名
select pp.age,pp.className
from `student` as pp
12.6 投影字段使用常量描述一个伪字段
select `name`,'在校' as `isInSchool` from student;
12.7 查询投影中使用算数运算符
数值类型字段使用
±*/%
select sum(`score`)/4 from student;
13. mysql的函数
13.1 聚合函数
函数名 作用 AVG() 返回某字段的平均值 COUNT() 返回某字段的行数 MAX() 返回某字段的最大值 MIN() 返回某字段的最小值 SUM() 返回某字段的和
/* avg- 计算某个字段的平均值 */
select AVG(`age`) as age_avg from student
where grade = 'A';
/* count- 统计行数聚合函数 */
/* count(*) = count(1) count(主键字段)>count(普通字段) */
select count(*) as studnet_count
from student where age BETWEEN 18 and 20;
/* max-最大值聚合函数 */
# 获取评分为B的学生年龄最大值
select max(`age`) from student
where grade ='B';
/* min-最小值聚合函数 */
# 获取评分为B的学生年龄最小值
select MIN(`age`) from student;
/* sum - 和统计聚合函数 */
select sum(`score`) from student;
13.2 常用函数-字符串函数
函 数 名 | 作 用 | 举 例 |
---|---|---|
CONCAT(str1, str1…strn) | 字符串连接 | **SELECT CONCAT(‘My’,‘S’,'QL’);****返回:**MySQL |
INSERT(str,pos,len,newstr) | 字符串替换 | SELECT INSERT( ‘这是SQL Server数据库’, 3,10,‘MySQL’);返回:这是MySQL****数据库 |
LOWER(str) | 将字符串转为小写 | **SELECT LOWER(‘MySQL’);****返回:**mysql |
UPPER(str) | 将字符串****转为大写 | SELECT UPPER(‘MySQL’); **返回:**MYSQL |
SUBSTRING (str,num,len) | 字符串截取 | SELECT SUBSTRING( **‘JavaMySQLOracle’,5,5);****返回:**MySQL |
/* 字符串拼接-concat(...) */
/* 效果 字段name和常量-- 以及 字段 age 拼接 效果: 张三--18 */
select concat(`name`,'--',`age`) as resName from student;
/* 字符串替换-INSERT(要替换的原字符串常量或字段名,要替换的起始位置,要替换几个字符,替换的新字符串) */
INSERT('这是SQL Server数据库',3,10,'MySQL') 结果: 这是MySQL数据库
select INSERT(`name`,1,1,'高') as newName from student;
/* 截取字符串-SUBSTRING(要截取的字段或常量值,截取的起始位置,截取几个字符); */
SUBSTRING('JavaMySQLOracle',5,5); 结果: MySQL
select SUBSTRING(`name`,1,1) as xing from `student`;
13.3 常用函数-日期函数
函数名 | 作用 | 举例**(结果与当前时间有关)** |
---|---|---|
CURDATE() | 获取当前日期 | **SELECT CURDATE();****返回:**2016-08-08 |
CURTIME() | 获取当前时间 | **SELECT CURTIME();****返回:**19:19:26 |
NOW() | 获取当前日期和时间 | **SELECT NOW();****返回:**2016-08-08 19:19:26 |
WEEK(date) | 返回日期date为一年中的第几周 | **SELECT WEEK(NOW())****;****返回:**26 |
YEAR(date**)** | 返回日期date的年份 | **SELECT YEAR(NOW());****返回:**2016 |
HOUR(time) | 返回时间time的小时值 | **SELECT HOUR(NOW());****返回:**9 |
MINUTE(time) | 返回时间time的分钟值 | **SELECT MINUTE(NOW());****返回:**43 |
DATEDIFF(date1,date2) | 返回日期参数date1和date2之间相隔的天数 | SELECT DATEDIFF(NOW(), **‘2008-8-8’);****返回:**2881 |
ADDDATE(date,n) | 计算日期参数date加上n天后的日期 | **SELECT ADDDATE(NOW(),5);****返回:**2016-09-02 09:37:07 |
/* curdate-获取当前数据库服务所在计算机的本地时间(yyyy-MM-dd) */
select CURDATE() as nowdate,`name` from student;
/*curtime-获取当前数据库服务所在计算机的本地时间(HH:mm:ss) */
select curtime() as nowtime,`name` from student;
/*now-获取当前数据库服务所在计算机的本地时间(yyyy-MM-dd HH:mm:ss) */
select now() as nowtimeAndDate,`name` from student;
/*
WEEK(date) 获取日期是今年的第几周
YEAR(date) 获取年份数值
注意: 传入的数据必须包含年月日数据才行
*/
/*
HOUR(time) 获取小时的描述
MINUTE(time) 获取分钟的表述
注意: 传入的数据必须包含时分秒数据才行
*/
/* DATEDIFF(date1,date2) - 计算两个日期相差的天数*/
select DATEDIFF(now(),'2022-12-08') from student;
/* adddate - 计算目标日期添加天数之后的日期*/
select ADDDATE(now(),3) from student;
13.4 常用函数-数学函数
CEIL(x) | 向上取整 | ** ****SELECT CEIL(2.3)****返回:3 ** |
---|---|---|
FLOOR(x) | 向下取整 | ** ****SELECT FLOOR(2.3)****返回:2 ** |
RAND() | 返回0~1间的随机数 | ** ****SELECT RAND()****返回:0.5525468583708134 ** |
13.5 常用函数-逻辑控制函数
#1.
# if函数
# if(表达式,表达式为true时值,表达式为false时值)
select
if(`sex`=1,'男','女') as sexStr
from student;
/*
2.
case
when boolean结果表达式 then 显示的值
when boolean结果表达式 then 显示的值
when boolean结果表达式 then 显示的值
end
*/
# 将成绩分数转换为ABC,0~60分:C 60~90:B 90~100:A
select
(case
when score BETWEEN 0 and 60 then 'C'
when score BETWEEN 61 and 90 then 'B'
when score BETWEEN 91 and 100 then 'A'
end) as scoreType
from student;
/*
3.
IFNULL(字段名,当字段为空时显示的值)
当字段值不为空则以字段值显示,为空的话显示第二个参数的值
*/
select IFNULL(`grade`,'无评分') from student;
13.6 mysql-分页语句
select * from student
LIMIT 2; # 只显示两行
select * from student
LIMIT 1,2; # [偏移量,显示行数]
/* 页码:x 每页显示的条目数:size */
# limit size * (x - 1),size;
14.子查询
14.1 条件子查询
执行过程: 先执行子查询—》执行父查询
子查询结果集写法要匹配子查询条件
1. 关系运算符:子查询只能有一个字段,一个值 1. in、not in:子查询只能有一个字段,但是可以有一行或多行值 1. between X and X1 : 子查询只能有一个字段,一个值 1. like 模糊匹配:子查询只能有一个字段,一个值,且借助concat函数完成拼接如:'%张%' concat('%',子查询,'%')
/* 子查询投影字段只能有一个,且数据类型要匹配 */
# 查询年龄比张三大的学生
SELECT
*
FROM
`stu_info`
WHERE
`age` > ( SELECT `age` FROM `stu_info` WHERE `name` = '张三' );
/* 模糊匹配子查询 - 子查询条件 like 借助 concat函数进行拼接 */
select * from `stu_info`
where `name` like CONCAT((select substring(`name`,1,1) from `stu_info`
where name = '张三'),'%')
条件子查询: ALL
和子查询返回的所有值进行比较,条件满足所有数据则返回数据;
例如:sal>ALL(1,2,3)等价于sal>1 and sal>2 and sal>3,即大于所有
可以使用的查询条件 : > < >= <= <>
# 查询学生成绩比60,80,90分**都大**的同学的成绩
select * from `stu_score`
where `score` > ALL(
select `score` from `stu_score`
where `score` = 60
or `score` = 80
or `score` = 90
);
等同于
select `score` from `stu_score`
where `score` > 60
and `score` > 80
and `score` > 90
条件子查询:ANY
和子查询的任意一个值进行比较,满足其中一个值就返回数据
例如:sal>ANY(1,2,3)等价于sal>1 or sal>2 or sal>3,即大于任意一个就可以。
select * from `stu_score`
where `score`> ANY(
select `score` from `stu_score`
where `score` = 60
or `score` = 80
or `score` = 90
)
等同于
select `score` from `stu_score`
where `score` > 60
or `score` > 80
or `score` > 90
exists 是否存在
判断子查询是否有结果集,如果子查询有结果集则父查询正常执行;如果没有结果集父查询结果为空
select * from `stu_info`
where EXISTS (select * from `stu_info` where `name`='张三');
复制表子查询
/* 拷贝表结构 创建 新表 */
/*只会拷贝表结构没有数据*/
create table `newStu` like `stu_info`;
/* 拷贝表结构和数据 */
# 通过查询创建新表
create table `newStu` as
(select `name` from `stu_info` where `name`='张三');
特殊:跨数据库复制表、创建表
create table `mysql_user` like `mysql`.`user`;
create table `mysql_user` as
(select * from `mysql`.`user`)
create table `mysql`.`cxk`(
code int(2)
);
14.2 投影子查询
select
`name`,
(select `score` from `stu_score` where `name`='张三' and `lessonName` = '语文') as score
from `stu_info`;
14.3 关联表子查询
/* select * from 来源可以是普通表、视图、子查询 */
select * from (select `id`,`name` from `stu_info`) as stu
left join (select `id`,`score` from `stu_score`) as sc
on sc.id = stu.id;
select * from (select `id`,`name` from `stu_info`) as stu;
15. 分组查询
- 分组查询只会配合聚合函数使用
- 如果要投影普通字段(没有使用聚合函数的),只能使用分组字段进行投影
# 计算 每个科目 的 平均分
select
avg(`score`),lessonName
from `stu_score`
GROUP BY `lessonName`;
多字段分组
根据业务逻辑中分组的顺序编写group by后面的字段顺序
# 统计每个科目,各个评分等级的人数有多少
# 先按科目分组,然后再把每个科目的评分进行分组
select count(*),lessonName,grade from `stu_score`
GROUP BY `lessonName`,`grade`
分组的结果集排序
/* 可以直接使用聚合函数的别名使用在排序字段中 */
select count(*) as `cc`,lessonName,grade from `stu_score`
GROUP BY `lessonName`,`grade`
order by cc desc
分组的结果分页
分页结果是根据分组的结果集来分页,并不是分组之前的sql结果结果分页
select count(*) as `cc`,lessonName,grade from `stu_score`
GROUP BY `lessonName`,`grade`
order by cc desc
limit 5;
分组结果筛选语句
having <条件语句>
# 统计每个科目,各个评分等级的人数有多少,然后查询出人数大于等于3的数据
select count(*) as `cc`,lessonName,grade from `stu_score`
GROUP BY `lessonName`,`grade`
HAVING cc >= 3
16. 去重语句
distinct : 将字段对应的行数据去重
select DISTINCT `grade`,`lessonName` from `stu_score`
17. 关联查询语句
inner join:内连接 基于 笛卡尔积连接进行筛选
left join:左连接
right join:右连接
select 投影 from 表1
连接方法 join 表2
on 连接的条件
where 对表连接的结果集进行筛选
group by 对表连接的结果集或条件筛选之后的结果集进行分组
order by 对以上结果集进行排序
limit 对以上结果集进行分页
17.1 内连接
内连接查询只有满足条件的数据才会出现
select * from `stu_info`
inner join `stu_score`
on `stu_info`.id = `stu_score`.id
where stu_score.score>90
17.2 左连接
- 左表(主表)-数据是会全部出现
- 连接过程中匹配的数据正常拼接,左表出现和右表无匹配数据就用null 填充
SELECT S.studentName,R.subjectNo,R.studentResult
FROM student AS S # 主表(左表)- 一定会全部出现
LEFT JOIN result AS R # 从表(右表)
ON S.studentNo = R.studentNo;
17.3 右连接
- 右表(主表)-数据是会全部出现
- 连接过程中匹配的数据正常拼接,右表出现和左表无匹配数据就用null 填充
select * from `stu_info` # 从表(左表)
right join `stu_score` # 主表(右表)- 一定会全部出现
on `stu_info`.id = `stu_score`.id
18. 联合查询
union \ union all
union : 会去重(根据行数据去重)
union all: 不会去重
SELECT column1, column2 ...
FROM table1, table2
[WHERE condition1]
UNION / UNION ALL
SELECT column1, column2 ...
FROM table1, table2
[WHERE condition2]
select `name` from `stu_info` where `name`='张三'
union all
select `name` from `stu_info` where `name`='张三'
19. 事务
事务必须具备以下四个属性,简称ACID 属性原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability)
1.原子性(Atomicity)
事务是一个完整的操作,事务的各步操作是不可分的(原子的),要么都执行,要么都不执行
2.一致性(Consistency)
当事务完成时,数据必须处于一致状态
3.隔离性(Isolation)
并发事务之间彼此隔离、独立,它不应以任何方式依赖于或影响其他事务
4.持久性(Durability)
事务完成后,它对数据库的修改被永久保持
BEGIN; # 开启事务
UPDATE `bank` SET `currentMoney`=`currentMoney`-500
WHERE `customerName`='张三';
UPDATE `bank` SET `currentMoney`=`currentMoney`+500
WHERE `customerName`='李四';
COMMIT; # 事务提交,事务中所做的操作都会持久化到硬盘
# 二选一
ROLLBACK; # 回滚事务,将刚刚所有的操作回滚,恢复到事务之前的状态
19.1 自动事务提交
默认情况下,每条单独的SQL语句视为一个事务
关闭默认提交状态后,可手动开启、关闭事务
SET autocommit = 0|1;
值为0:关闭自动提交
值为1:开启自动提交
查看事务的自动提交状态
show variables like 'autocommit'
20. 视图
视图是一张虚拟表
表示一张表的部分数据或多张表的综合数据其结构和数据是建立在对表的查询基础上
视图中不存放数据
数据存放在视图所引用的原始表中
视图的作用:
筛选表中的行防止未经许可的用户访问敏感数据降低数据库的复杂程度将多个物理数据库抽象为一个逻辑数据库
视图查询的数据是实时的,并不是把创建视图中使用的sql查询的结果集保存到临时表,是实时查询
特殊:
1. 视图与视图、视图与表之间是可以关联查询的,就把视图当做一张普通表即可 1. 视图中可以使用多个表一个视图可以嵌套另一个视图 1. 对视图数据进行添加、更新和删除操作直接影响所引用表中的数据 1. 当视图数据来自多个表时,不允许添加和删除数据
/* 创建视图 */
CREATE VIEW view_name
AS
<SELECT 语句>;
/*删除视图*/
DROP VIEW [IF EXISTS] view_name;
/*查看视图*/
SELECT 字段1, 字段2, …… FROM view_name;
# 查询每个学生的成绩(原始sql)
select
`stu_info`.name as `stuName`,
`stu_info`.id,
`stu_score`.score
from `stu_info`
left join `stu_score`
on `stu_info`.id = `stu_score`.id;
# 创建视图
create view `view_stu_info_score` as
select
`stu_info`.name as `stuName`,
`stu_info`.id,
`stu_score`.score
from `stu_info`
left join `stu_score`
on `stu_info`.id = `stu_score`.id;
# 调用视图
select `stuName` from `view_stu_info_score`;
21.索引
索引是一种有效组合数据的方式,为快速查找到指定记录
作用:
1.大大提高数据库的检索速度
2.改善数据库性能
MySQL索引按存储类型分类:
1.B-树索引:InnoDB、MyISAM均支持
2.哈希索引
什么字段需要创建索引? (主键、外键是会自动创建索引的)
- 经常使用在投影中的字段
- 经常作为主要条件的字段
/* 创建索引 */
/* 同一张表中索引名称不能重复,但是多张表之间索引名称可以重复 */
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名称
ON 要创建索引的表 (字段1,字段2...);
create index `stuInfoIndex_name_age`
on `stu_info`(`name`,`age`);
/*删除索引*/
DROP INDEX 索引名称 ON 索引所在的表名;
21.1 什么时候索引失效?
最左匹配原则:不满足最左匹配原则会让索引失效
在条件语句中,有索引的字段条件优先编写,没有索引的靠后
count、函数、类型转换 都会让索引失效
is null 可以使用索引优化,但是not null 就不行会让索引失效(所有的not操作都会让索引失效)
或连接左右两边有一个出现非索引列都会让索引失效, 如 : where a>0 ro b<10; b没有设置索引,a设置了索引,会让a索引失效
模糊匹配的字段索引失效
22. 数据库备份指令
备份是一个dos指令,不是sql语句!!!!在cmd中运行
mysqldump
[options] 备份选项参数
–u username 连接的数据库用户名
–h host 连接的数据库主机名
–ppassword 连接数据库用户密码
数据库名称 [表名1[,表名2……]] > 创建保存到本机的sql文件路径
mysqldump -uroot -p javatest > F:\mySQL\mysql-5.7.34-win32\beifen1.sql
选项参数:
-add-drop-table | 在每个CREATE TABLE语句前添加DROP TABLE语句,默认是打开的,可以用**-skip-add-drop-table****来取消** |
---|---|
–add-locks | 该选项会在****INSERT 语句中捆绑一个****LOCK TABLE 和****UNLOCK TABLE 语句****好处:防止记录被再次导入时,其他用户对表进行的操作 |
-t或-no-create-info | 只导出数据,而不添加CREATE TABLE语句 |
-c或–complete-insert | 在每个INSERT语句的列上加上列名,在数据导入另一个数据库时有用 |
-d或–no-data | 不写表的任何行信息,只转储表的结构 |
23.恢复
/* 方法一:使用mysql指令完成 dos界面完成 */
mysql –u root –p schoolDB < d:\backup\myschool_20160808.sql
/*方法二: 登录mysql,然后选择数据库后使用 dos界面完成*/
USE myschoolDB2; #选择数据库
source d:\backup\myschool_20160808.sql; #恢复数据库
24. 数据库设计(仅供参考)
24.1 设计流程
- 获取需求
- 定义出实体(Entity):考虑第二范式的设计规则
- 描述实体的属性(Attitutte): 考虑第一范式的设计规则
- 描述实体与实体之间的关系(Relationship):考虑第三范式的设计规则
- 1-1:一对一关系
- 1-N:一对多关系,关联描述字段保存在“多”的一方
- N-1:多对一关系,关联描述字段保存在“多”的一方
- N-N:多对多,创建一个中间表间接实现多对多关系,如: 订单和商品表之间的关系要使用一个订单商品信息记录表来间接描述描述多对多关系
24.2 E-R图 实体关系映射图
矩形:实体名称
椭圆:实体的属性
菱形:实体之间的关系(动词)
24.3 使用PowerDesginer设计数据库
概要设计阶段:E_R图----》 概念设计模型
详细设计阶段:概念设计模型进一步细化-----》逻辑设计模型
逻辑设计模型:描述实体名、字段名、字段类型(大致去描述类型)、长度、备注、是否有主键或外键;根据实体间的对应关系生成关联字段或关联表
- 编码阶段:逻辑设计模型----》物理设计模型
物理设计模型:需要指定一个数据库类型(Mysql、oracle)根据逻辑设计模型的数据库表设计,直接生成sql代码
在powerDesginer中设计模型的过程:
逻辑模型(logical Design model)—》物理模型(Physical Design Model)----》导出sql就完成设计
24.4 数据库设计三大范式(表设计和关联设计)
24.4.1 第一范式(1 st NF)
第一范式的目标:是确保每列的原子性
如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)
24.4.2 第二范式(2 st NF)
第二范式要求:每个表只描述一件事情
建立在正确的业务分析,将实体划分后都是满足第二范式的
24.4.3 第三范式(3 st NF)
第三范式的目的:冗余小、表关联正确无误的数据
要满足第二范式的设计需求,其次关联字段使用主键关联
25. 数据库用户管理(DCL语句)
一般使用root账号来完成,DCL操作是在mysql数据库下完成
- 用户创建
- 用户删除
- 修改密码
- 用户的权限管理(授权、收回权限)
use mysql;
/*1. 创建用户语句*/
/*
允许访问控制:
1. 固定ip:如172.168.22.51,描述的是只有ip为172.168.22.51地址的计算能使用当前账号访问mysql服务
2. localhost:当前账号只允许在服务器计算机本地访问mysql服务
3. %: 当前账号允许所有ip地址的计算使用当前账号访问mysql服务
*/
create user '用户名'@'允许访问控制' IDENTIFIED by '明文密码';
如:
create user 'cxk'@'172.168.22.51' IDENTIFIED by 'ctrl';
/*2. 删除用户*/
drop user '用户名'@'当前用户的访问权限控制';
drop user 'cxk'@'172.168.22.51';
/*3. 修改密码*/
set password for '用户名'@'host值' = password('新密码');
如:set password for 'root'@'localhost' = password('root123456');
设置完成之后一定要执行:
flush privileges;
/*1. 数据库用户权限-授权*/
grant 权限列表 on 数据库对象.* to 用户名@'host值' IDENTIFIED by '密码';
设置完成之后一定要执行:
flush privileges;
/*
grant ALL on *.* : 所有数据库所有的权限
*/
grant ALL on javatest.* to 'cxk'@'172.168.22.51' IDENTIFIED by 'ctrl';
/*2. 回收权限*/
revoke 权限列表 on 数据库对象.* from 用户名@'host值';
设置完成之后一定要执行:
flush privileges;
revoke ALL on javatest.* from 'cxk'@'172.168.22.51';
/* 查询用户的详细权限 */
select * from db where User = 'cxk';
/* 如果权限回收出现问题,就把账号删掉从新授权 */