[SQL injection] – SQL注入 – Day01 – SQL基础 – 保姆级0基础

[SQL injection] – SQL注入 – Day01 – SQL基础 – 保姆级0基础

阅读对象

本系列文章将从0-1的帮助你开始SQL注入的学习

如果你存在

  1. 看其他师傅写的SQL注入相关文章一头雾水
  2. 不知道从哪开始
  3. 自学困难
  4. 难以手工进行SQL注入

等现象,那么本系列文章正是为你准备

前言

如果完全没有SQL基础就开始学习SQL注入是完全无法想象的,如果你从未学习过SQL 那么完全无法理解SQL注入属于正常现象,并不是太难你学不会 而是你没有开始前的基础。

这就和完全没接触过二次函数就去学习圆锥曲线一样

本文将介绍SQL注入学习前必要的知识,为了确保学习效果,基础学习部分文章都会在讲解完每个知识点之后附上练习 [动手试一试] 部分以及在底部会有本章作业,我们没有义务督促你完成 一切取决于你自己 练习/作业部分可以发到评论区打卡。

SQL介绍

SQL全程结构化查询语言,是一种标准化数据库查询语言

SQL并不是一个完全统一的查询语言,为了方便读者理解,这里先介绍一下数据库

数据库分类

数据库一般分为:

  • 关系型数据库
  • 非关系型数据库

常见的关系型数据库包含:MySQL/PostgreSQL/SQL Server/Oracle/SQLite……

非关系型数据库包含:Redis/MongoDB/Neo4j……

注:这里不需要记忆,仅作介绍

还有一些已经不常用了或者这里没有提到的数据库可以自行搜索了解

关于两者的区别 作为初学者可以简单理解为

关系型数据库组成,表格结构,有更标准的存储结构

非关系型数据库可以由JSON/键值对/图结构组成,类似文件夹和文件的存储结构,有更灵活的存储结构

仅作了解即可,本文不会对非关系型数据库做过多讨论

回到SQL

上文提到SQL并不是完全统一的查询语言

实际上SQL拥有很多不同的标准/规范 如SQL-92/SQL-99/SQL-2011等

主流的关系型数据库都支持标准SQL的基本部分

比如: SELECT * FROM users WHERE id = 1;这条查询语句对任何主流数据库都适用

SQL方言

各个数据库厂商一般会在标准SQL的基础上增加自己的扩展,一般体现在函数/数据类型上

我们称这些额外拓展的部分为SQL方言

在不同的数据库环境下,SQL注入利用也会体现出一定差异

后面在涉及到SQL注入利用的时候我们将会详细介绍到这些方言在SQL注入中的运用

数据库结构

注:本系列文章均以关系型数据库为背景讲解 固这里提到的”数据库”均为关系型数据库。

数据库是按照 数据库 → 表 → 行 → 列 的层次结构存储的

关系顺序是从大到小排列,数据库中存储着表,表中结构包含行和列。

数据库(Database)

是数据存储的最大容器,类似一个文件夹,可以包含多个表则类似文件夹中的文件

每个应用程序通常对应一个数据库,比如:

  • 学生管理系统 → school_db

  • 电商网站 → ecommerce_db

表(Table)

是数据库中的核心组成部分数据都存储在表中

行(Row)列(Column)组成

  • 列(Column):定义数据的类型(如 id/name/age)。
  • 行(Row):每一行代表一条记录(如一个学生的信息)。

我们常见到一些师傅写的文章中提到字段这个词

字段其实就是表的列,上面提到的id/name/age都是字段

数据类型

每一个字段(列)都对应一种数据类型,常见的包括

  • INT (整数) → 存储年龄/ID等
  • VARCHAR (字符串) → 存储姓名/地址等
  • DATE (日期) → 存储生日/日期等
  • DECIMAL (精确小数) → 存储价格/工资等

主键

防止一部分读者没有基础,让我们先了解一下是什么

像超市的暂存柜一样,每个柜子对应一个号码,里面存储着物品

键就是这个号码,物品则是数据

要找到数据,首先要找到对应的号码(键)

键值对的概念就是 键 → 值

  • 主键是唯一标识每一行数据的字段。
  • 主键必须唯一不能为NULL,比如id字段。

标准SQL基础增删改查操作

这里以主流关系型数据库MySQL为例

如果没有本地环境可以选择在线SQL运行平台

默认界面

默认界面

点击前往练习

查询所有库

当我们输入

SHOW databases;

4a47a0db6e20250206124149

我们会得到如下结果

Database
information_schema
mysql
performance_schema
sys

其中

information_schema
mysql
performance_schema
sys

属于系统库

information_schema

它是MySQL中我们需要重点关注的库,后续的SQL注入学习中我们会经常用到它

  • information_schema是MySQL中的元数据数据库,存储了关于MySQL服务器本身的信息,如 数据库/表/列/权限等
  • 它是只读的,不能进行插入/更新/删除等操作

mysql

  • mysql 数据库存储MySQL服务器的核心系统信息,例如用户/权限/时区/插件等。
  • 它是MySQL的控制数据库,包含 MySQL 服务器的管理数据。

performance_schema

  • performance_schema是 MySQL用于性能监控的数据库。
  • 主要存储 MySQL服务器内部的运行状态信息,如 SQL语句执行情况/锁/等待事件等。
  • 默认是关闭的,需要手动启用performance_schema选项。

sys

  • sys是一个方便 DBA 监控和优化MySQL的数据库。
  • 它是performance_schemainformation_schema封装,提供更友好的视图。
  • MySQL 5.7 及以上版本才有。

创建数据库

现在我们开始进行创建数据库的操作

注:一个开发的好习惯是所有SQL语句用大写编写 实际上SQL无论大小写都是可以正常执行的

CREATE DATABASE 语句用于创建一个新的数据库

CREATE DATABASE my_db;

这会创建一个名为my_db的数据库,;作为结束符,代表一句SQL语句到此结束了。

执行结果:

fb5c81ed3a20250206144005

10fb15c77220250206144005

我们发现新的数据库已经被添加好了

选择数据库

创建数据库后,我们需要选择要操作的数据库

USE my_db;

这条命令告诉 MySQL 我们要在my_db这个数据库里执行操作

动手试一试

创建一个new_db数据库,并且选择它

创建表

现在我们在my_db这个数据库中创建一个students

CREATETABLE语句用于表示创建一个我们选择的数据库

指定创建的表名称为students括号中写入需要创建的字段/类型/宽度

PRIMARY KEY表示id字段为主键 不能为空 并且每个值必须唯一

完整语句:

CREATE TABLE students (id INT PRIMARY KEY, name VARCHAR(50), age INT);

该表包含三个字段(列)

  • id(整数型,主键)
  • name(字符串类型,每个值最大 50 个字符)
  • age(整数型,存储年龄)

执行结果

DESC students;语句用于查询我们刚刚创建好的表的结构

CREATE DATABASE my_db;
USE my_db
CREATE TABLE students (id INT PRIMARY KEY, name VARCHAR(50), age INT);
DESC students;

09dd8c266220250206150012

字段解释

  • Field:列名(id/name/age)。
  • Type:数据类型(idINTnameVARCHAR(50))。
  • Null:是否允许NULL(id不能为 NULLnameage可以)。
  • Key:是否是主键(PRI 表示 idPRIMARY KEY)。
  • Default:默认值(默认NULL)。
  • Extra:额外信息(如果idAUTO_INCREMENT,这里会显示auto_increment)。

动手试一试

创建一个My_table表,包含三个字段,分别为主键uid字段,整数类型,uname字段,字符串类型,pin字段,整数类型

表中插入数据

INSERT INTO语句用于给指定表插入数据

这里指定students表,插入id/name/age字段,值分别为1/张三/18

INSERT INTO students (id, name, age) VALUES (1, '张三', 18);

除了id主键无法为空其他字段均可为NULL(空)

预期查询返回结果

  • id = 1
  • name = '张三'
  • age = 18

如下示范仅指定idname字段插入数据 此时age为空

INSERT INTO students (id, name) VALUES (2, '李四');

预期查询返回结果

  • id = 2
  • name = '李四'
  • age = NULL

8266e4bfed20250206153907

f19c90851220250206153907

动手试一试

为刚刚创建的My_table表插入数据,值任意

插入两次,第一次全部字段均包含值,第二次必须有一个字段为空

表中插入多条数据

SQL语句不需要完全写在同一行只要没有输入;结束符就不会中断完整的一句SQL,相反,如果你的SQL语句报错,检查是否添加;结束符。

想必读者经过上文的实践,已经能够独立看懂如下的语句了,这里不做解释。

INSERT INTO students (id, name, age) 
VALUES 
    (3, '王五', 20),
    (4, '赵六', 22),
    (5, '孙七', 19);

9eb9cd58b920250206154023

删除数据库

注:谨慎删除,删除库操作将会删除库内全部数据

DROP DATABASE my_db;

删除表

选中数据库后执行删除表操作

DROP TABLE students;

删除字段(列)

删除表中的某一列,但保留表其他列的数据

操作格式

ALTER TABLE 表名 DROP COLUMN 列名;

实例

ALTER TABLE students DROP COLUMN age;

删除表中行数据(值)

删除表中的行数据,但表结构仍然保留。
DELETE FROM 表名 WHERE 条件;

实例

DELETE FROM students WHERE id = 1;
  • 结果:删除students表中id = 1的那一行数据
  • 如果省略 WHERE,会删除所有数据

SQL查询语句

重点部分!需完全理解掌握

SELECT最常用的SQL语句,用于从数据库的表中查询数据(值)

语法

SELECT 列名1, 列名2, ... FROM 表名 WHERE 条件 ORDER BY 排序方式 LIMIT 结果数量;
  • SELECT:指定要查询的列(字段) 规定返回的列。
  • FROM:指定查询的表。
  • WHERE(可选):添加筛选条件,仅返回符合条件的记录。
  • ORDER BY(可选):指定结果的排序方式。
  • LIMIT(可选):限制返回的记录数。

实际上SQL服务于数据科学和统计,常见的还有一些统计函数,这些会放到后面的文章讲解。

查询所有列(*)

非常常见的用法

SELECT * FROM students;

如上语句将查询students表的所有列和所有行

预计返回表中全部数据

9eb9cd58b920250206154023

查询指定列(字段)

SELECT name, age FROM students;

只查询nameage列,减少不必要的返回内容

602e8f042f20250206160326

图中得知,id字段的值均没有被返回

使用WHERE过滤

查询年龄age大于18的学生

SELECT * FROM students WHERE age > 18;

7afbb1602620250206161209

SQL支持逻辑运算符,可以自行尝试

查询特定名字的学生

SELECT * FROM students WHERE name = '张三';

586e508f1620250206161404

使用AND和OR组合条件

为了防止基础较差的读者阅读困难 这里讲解一下AND和OR

逻辑运算符AND指:条件左右两项均为真则为真

逻辑运算符OR指:条件左右一项为真则为真

如果还是无法理解请自行搜索学习

常用!

查询年龄大于18姓名为”李四”的学生

SELECT * FROM students WHERE age > 18 AND name = '李四';

59b2900aa020250206161601

此处插入两项包含李四的学生数据,只有一项同时满足age > 18name = '李四'的条件,所以仅返回一条

如果将其改成OR两条都返回并且返回全部满足age > 18的学生数据,因为只要满足age > 18或者name = '李四'任意一个条件即可

9eb60bc8bf20250206162447

ORDER BY排序

按年龄升序排序

SELECT * FROM students ORDER BY age ASC;

ASC(默认):从小到大排序。

按年龄降序排序

SELECT * FROM students ORDER BY age DESC;

DESC:从大到小排序。

限制结果查询LIMIT

填入单个操作数则为限制返回多少个结果,如下语句返回学生表中前三条数据

SELECT * FROM students LIMIT 3;

填入两个操作数则为从xxx开始xxx数据

注: 第一位操作数从0开始计算

SELECT * FROM students LIMIT 2, 2;

如上语句表示从第三条数据开始 往后取两条数据

查询年龄最大的两位学生

SELECT * FROM students ORDER BY age DESC LIMIT 2;

根据上文的实践,读者可以自行理解含义

组合查询/联合查询

重点部分

假设我现在同时创建了一个teachers和一个students表在同一个数据库中

我需要同时查询studentsteachers表中的所有姓名

我可以使用UNION关键字合并两条查询语句去重返回结果

SELECT name FROM students
UNION
SELECT name FROM teachers;

本系列后面的文章中将会详细讲解UNION关键字在SQL注入中的使用

今日练习

动手试一试

  1. 创建一个名为 school_db 的数据库,并切换到该数据库。
  2. school_db 数据库中,创建 students 表,包含 id(主键)、name(姓名)、age(年龄)、grade(年级)、score(成绩)。
  3. students 表插入 5 条数据,确保 grade 包含 “高一”、”高二”、”高三”。
  4. 查询 students 表中的所有数据,包括所有列。
  5. 查询 students 表中 score 大于 80 的所有学生。
  6. 查询 grade 为 “高三” 的学生,并按 score 降序排序。
  7. 查询 students 表中成绩最高的学生信息。
  8. 查询 students 表,每页显示 2 条数据,获取第 2 页数据。
  9. 创建 courses 表,包含 course_id(主键)、course_name(课程名称)。
  10. courses 表插入至少 3 门课程(如 数学、英语、物理)。
  11. 联合查询两张表的全部数据。

备注提交方式评论区直接写出你的SQL语句或者使用在线工具截图提交每次的运行结果

尽可能写的时候不要查答案,如果是AI完成的不用提交了我们没义务督促你,一切取决于你自己

© 版权声明
THE END
喜欢就支持一下吧
评论 抢沙发

请登录后发表评论

    暂无评论内容