目录
一、数据库的概念
什么是数据库?为什么要学数据库?
数据库: 存放数据的仓库
学习数据库的作用:
- 学习SQL注入漏洞(漏洞之王)
- 所有的web系统--> 数据-->存放起来-->数据库里面
前端 ------->后端 ------->数据库
编程相关的所有东西,都是来源于生活
现实生活种的仓库:
京东自建物流, 全国各地有很多很多仓库
京东买东西之后,就近原则在仓库里面直接出货
仓库里面要存放很多的东西, 这些东西必定是需要分类的, 分区域存放
理一个关系:
有一个大的京东仓库---------------------------------------------数据库管理系统( DBMS: database management system)
仓库里面有不同的分区(A区,B区, C区)---------------------------具体的数据库(database)
每个区有很多货架------------------------------------------------------表(table)
每个货架又有很多层----------------------------------------------------行 (row)
每一层里面才是物品----------------------------------------------------列--物品 (column)
我们学习的东西就是DBMS
二、数据库的分类
数据库里面我们大概可以分为两种:
关系型数据库:
表格的形式
- Oracle数据库: 全球排名第一的数据库,性能最牛逼(以前在银行里面用的很多),不开源,收费
- MySQL数据库: 占有率相当高,Oracle青春版, 开源,免费, 性能也行----(DBA)
- MSSQL数据库: 微软数据库, 也很优秀,很多政府项目用, ---》 .NET平台 (编程语言用C#, 操作系统也是微软的, 数据库也是微软),微软-->巨硬, 微软现在云服务做的很好
- PGSQL数据库: 和MySQL感觉是孪生姐妹, MSF 里面
- SQLITE数据库: 嵌入式数据库, 做工具, 做爬虫, 做POC校验, 做EXP验证等等, 需要存放很多===> 文件/SQLITE数据库里面
非关系型数据库:
图片、文件夹、视频、文档
- Redis数据库: 缓存---> 数据库存在内存里面的, 减少数据库IO,增加系统的吞吐量, 后面会和SSRF漏洞进行结合
- memecahce: 缓存
- MongoDB: 真的很牛皮, 大数据库刚刚出来的时候,(一行数据,就可以把一个人的所有数据全部包含)
三、数据库系统
数据库系统是指在计算机系统中引入数据库后的系统。完整的数据库系统结构关系如图所示:
四、安装数据库
数据库安装方式有三种:
- 官网下载安装包,直接安装即可。
- 官网下载免安装包,绿色版,解压打开即可。
- 集成环境(WAMP) Windows Apache MySQL PHP
集成环境有很多种: XAMPP / WAMPSERVER / PHPstudy
PHPStudy =》 切换环境超级方便
安装基本就是傻瓜式安装,安装需要注意的东西:
1. 注意安装的盘符,尽量不要在C盘
2. 安装之前,将自己电脑上的MySQL数据库停止掉且删除服务
win+R
输入:services.msc
需要找到是否有MySQL的服务,有就停掉,且删除服务: sc delete 服务名字(进入cmd命令行删除)
配置数据库的环境变量
win+R--->CMD
这个时候是需要配置数据库的环境变量。
什么是环境变量: 方便操作系统快速的去找到对应软件的可执行文件。
配置的方式:
- 我的电脑-->右键-->属性
- 高级系统设置--->环境变量
- 系统变量-->双击Path
- 进入环境变量编辑页面--->新建-->输入mysql可执行文件路径(D:\phpstudy_pro\Extensions\MySQL5.7.26\bin)
- 后续就是全部确定即可
在任何路径下面输入mysql出现如下界面说明配置成功:
五、MySQL的登录命令
PHPstudy安装的MySQL默认的用户名和密码
用户名: root
密码: root
mysql -uroot -p 回车 =》 输入密码
mysql: mysql命令
-u : user 登录用户
-p : 指定密码
MySQL的默认端口是: 3306
mysql -uroot -h localhost -P 3306 -p
-u : 用户名
-h : 主机地址-->MySQL数据库安装的机器的ip地址(127.0.0.1: 回环ip, localhost: 本地主机)
-P : 端口号 默认是 3306 端口即服务
-p : 密码
六、SQL
SQL是什么?
结构化查询语言
SQL 是所有数据库查询语言的统称
后续操作数据库的主要工作内容: 就是写SQL
数据库就是根据所写的SQL来执行相关的命令(增删改查)
记住: 操作数据库的核心点=》 建库,建表, 数据的增删改查
DDL
- 数据定义语言: Data Define Language这种语言主要用于: 建库,建表,修改表结构, 删除表,删除库
DML
- 数据管理语言: Data Manager Language这种语言主要用于: 数据的增删改
DQL
- 数据查询语言: Data Query Language这种语言主要用于: 数据查询
DCL
- 数据控制语言: Data Control Language这种语言主要用于: 数据库的权限管理
七、创建数据库
# 展示所有的数据库
show databases;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| admin |
| connect |
| db1 |
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| security |
| sys |
| test |
| web2401 |
| zhoujielunyyds |
+--------------------+
12 rows in set (0.01 sec)
# 创建数据库
# 关于数据库名字: 统一小写
create database 数据库的名字;
# 标准的创建数据库的语句
create database if not exists 数据库的名字;
# MySQL数据存放在什么地方的?
# 默认情况是存放在: MySQL安装目录/data目录下面
# 通过观察,MySQL的数据库,在文件系统中就是一个 : 文件夹而已
# 删除数据库
drop database 数据库名字;
# 标准的删除语句
drop database if exists 数据库名字
八、增删改查数据库
增加数据
# 语法
insert into 表名(字段名1, 字段名2, 字段名3....字段名n) values (值1,值2,值3....值n);
# 省略的字段中约束必须是null的,如果是not null 那就不能省略
mysql> insert into user(user_name,user_age) values('jack',18);
Query OK, 1 row affected (0.01 sec)
mysql> insert into user(user_name,user_age) values('rose',17);
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+-----------+----------+-------------+--------------+-----------+
| id | user_name | user_age | user_gender | user_address | user_like |
+----+-----------+----------+-------------+--------------+-----------+
| 1 | jack | 18 | 1 | NULL | NULL |
| 2 | rose | 17 | 1 | NULL | NULL |
+----+-----------+----------+-------------+--------------+-----------+
2 rows in set (0.00 sec)
# 简写 => 全插入
# 必须写所有的字段值
# 自增ID可以写成null => MySQL的特性
insert into 表名 values(所有字段的值依次填写,用逗号隔开);
mysql> insert into user values(null,'lucy',14,2,'Beijing','rap');
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
+----+-----------+----------+-------------+--------------+-----------+
| id | user_name | user_age | user_gender | user_address | user_like |
+----+-----------+----------+-------------+--------------+-----------+
| 1 | jack | 18 | 1 | NULL | NULL |
| 2 | rose | 17 | 1 | NULL | NULL |
| 3 | lucy | 14 | 2 | Beijing | rap |
+----+-----------+----------+-------------+--------------+-----------+
3 rows in set (0.00 sec)
mysql> insert into user values(null,'lucy',14,2,'Beijing');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
# 批量插入
insert into user(user_name, user_age) values('lucy', 20),('tom',19),('David',
22), ('Allen', 23);
删除数据
# 语法
delete from 表名 [where 条件]
mysql> delete from user where id=3;
Query OK, 1 row affected (0.01 sec)
mysql> select * from user;
+----+-----------+----------+-------------+--------------+-----------+
| id | user_name | user_age | user_gender | user_address | user_like |
+----+-----------+----------+-------------+--------------+-----------+
| 1 | jack | 18 | 1 | NULL | NULL |
| 2 | rose | 17 | 1 | NULL | NULL |
+----+-----------+----------+-------------+--------------+-----------+
逻辑删除
数据库里面的删除: delete => 直接将数据删除掉
在目前这种互联网时代 =》 数据是最重要的
很多时候在业务里面,我们是不会去直接将数据删除的, 而是要将数据保留下来,以备后续的数据分析
=》 溯源
这种情况就不能直接删除,而是逻辑删除
我们需要将这条数据加一个状态字段 =》 is_deleted 默认值 0 , 如果删除 将这个字段值设置 1
正常情况查询数据:
select * from student where is_deleted = 0;
所以所谓删除 =》 实际在数据库里面就是update
update student set is_deleted=1 where stu_code=?
修改数据
# 语法
update 表名 set 字段名1=字段值1,字段名2=字段值2....字段名n=字段值n [where 条件]
# 将jack的地址修改被成都
mysql> update user set user_address='成都' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from user;
+----+-----------+----------+-------------+--------------+-----------+
| id | user_name | user_age | user_gender | user_address | user_like |
+----+-----------+----------+-------------+--------------+-----------+
| 1 | jack | 18 | 1 | 成都 | NULL |
| 2 | rose | 17 | 1 | NULL | NULL |
+----+-----------+----------+-------------+--------------+-----------+
查询(重点)
投影查询
# 语法:* 代表所有字段(列)
select * from 表名;
## 按照字段进行查询
select user_name,user_gender from user;
限制查询(重中之重)
- 关键字:limit
- 方法一:限制条数 limit n
#只查2条数据
select * from user limit 2;
- 方法2:分段查询 limit index,length
# index : 下标 从0开始
# length : 长度
# 下标从0开始 ,查询2条
select * from user limit 0,2;
# 定一个基调: 3条一页
# 第一页
select * from user limit 0,3;
# 第二页
select * from user limit 3,3;
# 第三页
select * from user limit 6,3;
# 分页有两个参数
# page 当前的页数
# pageSize 每页的条数
# 第一页: page=1&pageSize=60 ===> limit 0, 60
# 第二页: page=2&pageSize=60 ====> limit 60, 60
# 第三页: page=3&pageSize=60 ====> limit 120, 60
# 总结一下规律
# 页码: page
# 页容量: pageSize
limit (page-1)*pageSize, pageSize;
# 这个规律记下来,后面要用
如果有SQL注入漏洞: 我们的核心是啥?==》 查数据
通过注入漏洞去查询: 数据库,数据库中的表,表里面的字段,数据
条件查询
- 关键字:where
- 单条件:
select * from user where user_name="JACK";
- 多条件:
#多条件 =》在JS中 多条件用的逻辑运算符: && || !
# 在数据库中对应: and or not
select * from user where user_name="ROSE" and user_age >20;
select * from user where user_age > 21 or user_gender="男";
# not 有几个组合
# 以某个字段值是否为空作为条件: is null/ is not null
select * from user where user_address is not null;
select * from user where user_address is null;
# not 还有一种情况 : 判断某个值是否在某个集合中
# in / not in
select * from user where user_age=20 or user_age=22 or user_age=23;
select * from user where user_name in("jack","rose",23);
select * from user where user_age between 20 and 30;
- 比较
# >,>=,<,<= , != , between ...and..
# between ...and.. 等价于 >= and <=
- 将条件,限制,投影 结合起来限制查询一定是放在SQL语句的最后
select user_name,user_age from user where user_age >20 limit 1;
模糊查询
- 关键字:like % _
- 全模糊查询语法:select * from 表名 where 字段名 like "%条件值%";
#查询名字中间有k的同学的所有信息
select * from user where user_name like "%k%";
- 半模糊%放在开头或结尾
- 占位符_表示一个字符
#查询名字由三个字符组成且中间字母是c的学生信息
select * from user where user_name like "_o_";
- 拓展:正则表达式查询,关键字:REGEXP
select * from user where user_name REGEXP 'ja.k';
排序查询
排序在实际的业务相当多
销量排行, 热歌榜, 成绩同级排名,热点话题排名。。。。。。
关键字 : order by
语法: order by 字段名 asc/desc
asc 升序 =》 默认值
desc 降序 =》 用的多
#通过年龄升序
select * from user order by user_age asc;
#通过年龄降序
select * from user order by user_age desc;
#通过年龄降序后,通过id降序
update user set user_age=22 where user_name="lucy";
select * from user order by user_age desc, id desc;
# 一定记住一点:
# 程序是从左到右,从上到下 依次扫描
# 和安全相关的排序:
select * from table order by 数字
数字: 代表的是第几列,就是第几个字段
子查询
# 子查询总的来说可以分成两大类:
# 1. where子查询
# where 字段 in | not in (子查询)
# where 字段= | > | >= | < | <= | !=(子查询)
select cat_id from goods order by shop_price desc limit 1;
select * from category where cat_id=(select cat_id from goods order by
shop_price desc limit 1);
# 2. from子查询
select * from goods order by goods_price desc limit 5;
select * from (select * from goods order by goods_price desc limit 5) as test;
联合查询
# union
# 他的作用:将两个查询的结果集 组合成一个结果集
# 语法: 查询语句 union 查询语句;
select goods_id,goods_name from goods
UNION
SELECT cat_id,cat_name from category;
# 需要注意: union前后的查询的字段数,必须是相等的(和内容无关),才能结合起来。
select goods_id,goods_name from goods
union
SELECT 1,2,3;
# union的结果集的结合的条件
# 条件就是:两次查询的结果的字段数必须一致
select * from t_class
union
select stu_id, stu_name from t_student;
# sql注入的地方
select * from t_class where class_id=-1
union
select 1,2;
九、内置数据库
- MySQL 默认存在 4 个内置数据库
- performance_schema
-
- 主要用于收集数据库服务器性能参数。
- sys
-
- Sys 库所有的数据源来自:performance_schema。
-
- 目标是把 performance_schema 的把复杂度降低,让 DBA 能更好的阅读这个库里的内容。
- mysql
-
- mysql 的核心数据库,类似于 sql server 中的 master 表,主要负责存储数据库的用户、权限设置、关键字等 mysql 自己需要使用的控制和管理信息。
select host,user,authentication_string from user;
- information_schema(重点掌握)
-
- information_schema 提供了访问数据库元数据的方式。
-
- 元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。
-
- 换句换说,information_schema 是一个信息数据库,它保存着关于 MySQL 服务器所维护的所有其他数据库的信息。
-
- information_schema 有三张关键的表:schemata、tables、columns。
-
- schemata
-
-
- 提供了关于数据库中的库的信息。
-
-
-
- 详细表述了某个库的名称,默认编码,排序规则。
-
-
-
- 各字段说明如下:
-
字段 | 含义 |
schema_name | 数据库名称 |
default_character_set_name | 数据库编码 |
default_collation_name | 数据库排序规则 |
select schema_name from information_schema.schemata;
-
- tables
-
-
- 提供了关于数据库中的表的信息(包括视图)。
-
-
-
- 详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。
-
-
-
- 各字段说明如下:
-
字段 | 含义 |
table_catalog | 数据表登记目录 |
table_schema | 数据表所属的数据库名 |
table_name | 表名称 |
........ | ........ |
-- 所有数据库的表名
mysql> select table_name from information_schema.tables;
-- 指定数据库的表名
mysql> select table_name from information_schema.tables where table_schema = 'student';
select column_name from information_schema.columns where table_schema = 'student' and table_name = 'users';
-
- columns
-
-
- 提供了关于表中的列的信息。
-
-
-
- 详细表述了某个列属于哪个表。
-
-
-
- 各字段说明如下:
-
字段 | 含义 |
table_schema | 表所有者(对于schema的名称) |
table_name | 表名 |
column_name | 列名 |
...... | ...... |
十、内置函数
查看数据库版本
select version();
select @@version;
获取数据库路径
#获取数据库数据存放的路径
select @@datadir;
#获取数据库路径
select @@basedir;
获取数据库名
select database();
获取用户名
select user();
获取组合数据
- concat():用于将多个字符串连接成一个字符串,形成单独一列,可能有多行。
- group_concat():返回一个字符串结果,该结果由分组中的值连接组合而成,形成单独一列,只有一行。
mysql> select concat(user_name,'-',user_age) from user;
+--------------------------------+
| concat(user_name,'-',user_age) |
+--------------------------------+
| jack-18 |
| rose-17 |
| lucy-22 |
| tom-19 |
| David-22 |
| Allen-23 |
+--------------------------------+
6 rows in set (0.00 sec)
mysql> select group_concat(user_name,'-',user_age) from user;
+--------------------------------------------------+
| group_concat(user_name,'-',user_age) |
+--------------------------------------------------+
| jack-18,rose-17,lucy-22,tom-19,David-22,Allen-23 |
+--------------------------------------------------+
1 row in set (0.00 sec)
获取字节长度
mysql> select length('123456');
+------------------+
| length('123456') |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec)
#获取字符的长度
mysql> select char_length('国科');
+-----------------------+
| char_length('国科') |
+-----------------------+
| 2 |
+-----------------------+
1 row in set (0.00 sec)
字符截取
- substr():字符截取(重点)
- left():从左开始字符截取
- right():从右开始字符截取
mysql> select substr('yongz',1,1);
+---------------------+
| substr('yongz',1,1) |
+---------------------+
| y |
+---------------------+
1 row in set (0.00 sec)
mysql> select left('yongz',1);
+-----------------+
| left('yongz',1) |
+-----------------+
| y |
+-----------------+
1 row in set (0.00 sec)
mysql> select right('yongz',1);
+------------------+
| right('yongz',1) |
+------------------+
| z |
+------------------+
1 row in set (0.00 sec)
睡眠/延时函数
mysql> select sleep(3);
+----------+
| sleep(3) |
+----------+
| 0 |
+----------+
1 row in set (3.01 sec)
判断
mysql> select if(substr(database(),1,1)='s','是','不是');
+-----------------------------------------------+
| if(substr(database(),1,1)='s','是','不是') |
+-----------------------------------------------+
| 是 |
+-----------------------------------------------+
1 row in set (0.00 sec)