认识关系型数据库与非关系型数据库:
首先谈一谈自己认识的这两种数据库:
关系型数据库常见的就是:mysql
非关系型数据库常见的是:nosql (全称:not only sql)
为什么要有关系与非关系的区别呢?主要在于查询或者是常见的时候,采用的方式不同,所以最好是根据不同的场景,采取最适合的数据库。
网上大部分文章的理解:
在此之前,我们先来看一看网上大部分的回答:
关系型数据库是依据关系模型来创建的数据库
关系模型就是 一对一,多对多,等关系模型
常见的关系型数据库有:Mysql,Oracle,SQLserver
关系型数据库的特点:
安全,因为存储在磁盘上,不会断电消失。
容易理解(建立在模型上)
但是不节省空间
非关系型数据库
主要是基于‘非关系模型’的数据库
非关系模型比如有:
列模型:存储的数据是一列一列的,
关系型数据库是以一行作为一个记录
列模型数据库是以一列为一个记录(数据即为索引,IO很快,主要是一些分布式数据库)
键值对模型:存储的数据是一个个的“键值对”:比如:name:liming那么name这个键里的值就是liming。
文档类模型:以一个个文档来存储数据,有点类似“键值对”
常见的非关系型数据库有:
列模型:Hbase
键值对模型:redis,memchacheDB
文档类模型:mongoDB
非关系型数据库的特点:
效率高(因为存储在内存中)
但是不安全(断电丢失,但是redis可以同步到数据磁盘中)
现在很多非关系型数据库都开始支持存到磁盘中
这种回答普遍存在,自己学习的时候很难理解,并且对于学习安全的人员来说,这样的回答作用不大
谈一谈自己大量阅读后所认识到的:
最重要的一点就是:这两者的区别主要是查询方式和构造数据库方式差异太大!!!!
关系型数据库,最典型的就是MYSQL:
MYSQL进行一次查询的步骤有:database–>table_name–>column–>value
MYSQL创建数据库也非常标准,正式由于太过标准,导致有时候很麻烦:
举几个例子:
场景1:
如果我们要存储一个公司人员的姓名,联系方式、是否爱吃巧克力三个内容
那么我们就会创建三个列,分别是姓名、联系方式、是否爱吃巧克力,那么问题来了,假如A联系方式不止一个,有2-3个怎么办?工作的时候联系工作机,空闲的时候联系本机这样的现象,那么就要再联系方式多创建几列:联系方式1,联系方式2,但是并不是所有人都有多个联系方式,此时就会出现联系方式为空的情况,但是由于MYSQL的标准创建存储,是不允许出现这种情况的,所以我们不得不再单独的多创建一个telephone表来存储这些信息
场景2:
我们需要统计员工的信息:姓名、联系方式、家庭地址、邮箱、爱好、生活习惯、旅游等等繁琐的信息,如果这个时候我们依然是使用MYSQL去存储的话,那么就太麻烦了,我们不得不思考一下,为什么不能按照每个人来存储呢?通过查询某个人的某些特定信息,就可以知道他的所有信息,这样该多好
于是就引入了非关系型数据库:
非关系型数据库为了更好的理解,我将采用代码对比的形式来讲解:
假如书店要对书籍做一个数据库整理,整理内容包括:书名、发行日期、发行商、价格、作者几个内容
那么我们再MYSQ里面需要做如下处理:
而我们再NOsql里面则只需要这样做:
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
format: "ebook",
price: 29.00,
publisher_id: "SP001"
}
{
ISBN: 9780992461225,
title: "JavaScript: Novice to Ninja",
author: "Darren Jones",
format: "ebook",
price: 29.00,
publisher: {
name: "SitePoint",
country: "Australia",
email: "feedback@sitepoint.com"
}
}
我们只需要把这些信息集合的放在一个BOOK文档里面即可,存储更方便,查询的时候也更快
再来看一个:
记录员工的各种数据,NOSQL:
{
name: [
"Billy", "Bob", "Jones"
],
company: "Fake Goods Corp",
jobtitle: "Vice President of Data Management",
telephone: {
home: "0123456789",
mobile: "9876543210",
work: "2244668800"
},
email: {
personal: "bob@myhomeemail.net",
work: "bob@myworkemail.com"
},
address: {
home: {
line1: "10 Non-Existent Street",
city: "Nowhere",
country: "Australia"
}
},
birthdate: ISODate("1980-01-01T00:00:00.000Z"),
twitter: '@bobsfakeaccount',
note: "Don't trust this guy",
weight: "200lb",
photo: "52e86ad749e0b817d25c8892.jpg"
}
而如果采用MYSQL的话,我们就需要额外建立很多其他表才行,这就是这两种的差别
这里再说一下:关于这两种数据类型的特点我们要知道:MYSQL这样的关系型数据库,内容是存储在电脑上的,数据是建立再模型上的,更容易理解,NOSQL这样的非关系型数据库,内容是存储在内存上的,所以 ,断电就消失,但是目前也正在像磁盘存贮转移了.
mysql的学习:
因为MYSQL在SQL注入中漏洞利用较多,且自己也没有掌握好这部分的知识,所以选择学习一下mysql数据库:
创建一个数据库:
CREAT DATABASE TEST_ONE:
显示已有的所有数据库名称:
SHOW DATABASES;
删除数据库:
DROP DATABASE test_one;
使用PHP脚本删除数据库:用到的的函数:mysqli_query
首先说一下这个函数的用法:
mysql_query() 函数执行一条 MySQL 查询。 参数:mysqli_query(connection,query,resultmode); connection:必须,连接的主机,query:必须:要查的字符串,resultmode:可选。一个常量。可以是下列值中的任意一个:
MYSQLI_USE_RESULT(如果需要检索大量数据,请使用这个)或MYSQLI_STORE_RESULT(默认)
注意:!!mysqli_query是进行一个mysql查询,可以理解为是进行一个SQL执行语句,那么这里如果不严格把控,就会出现严重的漏洞:比如删库,下面看几个例子让我们更好的理解一下这个函数:
$sql = 'DROP DATABASE RUNOOB';
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('删除数据库失败: ' . mysqli_error($conn));
}
echo "数据库 RUNOOB 删除成功\n";
mysqli_close($conn);
?>
上述代码就是执行一个SQL语句,删除数据库RUNOOB
而我们常见的数据库查询是怎么样的呢?:
<?php
$con = mysql_connect("localhost","mysql_user","mysql_pwd");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
$sql = "SELECT * FROM Person";
mysql_query($sql,$con);
// 一些代码
mysql_close($con);
?>
以上就是执行一个数据库信息查找的例子
选择一个数据库连接:
用到的函数:mysqli_select_db(connection,dbname);
作用:选择一个数据库进行连接
connection 必需。规定要使用的 MySQL 连接。
dbname 必需,规定要使用的默认数据库。
这里可能还不是很懂
看看代码就懂了:
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '123456'; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo '连接成功';
mysqli_select_db($conn, 'RUNOOB' );
mysqli_close($conn);
?>
$conn就是我们连接的SQL,‘RUNNOB’就是我们要查询的数据库
创建一个数据表:
使用到的SQL语句:CREATE TABLE table_name (column_name column_type);
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '123456'; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
echo '连接成功<br />';
$sql = "CREATE TABLE runoob_tbl( ".
"runoob_id INT NOT NULL AUTO_INCREMENT, ".
"runoob_title VARCHAR(100) NOT NULL, ".
"runoob_author VARCHAR(40) NOT NULL, ".
"submission_date DATE, ".
"PRIMARY KEY ( runoob_id ))ENGINE=InnoDB DEFAULT CHARSET=utf8; ";
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('数据表创建失败: ' . mysqli_error($conn));
}
echo "数据表创建成功\n";
mysqli_close($conn);
?>
我们在PHPADMIN里面运行看一看:
以上就是建立表的方式‘
删除数据表:
在PHPADMIN里面的命令:
DROP TABLE table_name:
我们直接在PHPADMIN里面操作一下:
可以看到test_one 下的表的确呗删除了
增删查改:
都可以通过一行代码实现:
增:顾名思义,也就是增加数据。在通用的SQL语句中,其简单结构通常可概述为: INSERT table_name(columns_name) VALUES(new_values) 。
删:删除数据。简单结构为: DELETE table_name WHERE condition。
查:查询语句可以说是绝大部分应用程序最常用到的SQL语句,他的作用就是查找数据。其简单结构为:SELECT columns_name FROM table_name WHERE condition。
改:有修改/更新数据。简单结构为:UPDATE table_name SET column_name=new_value WHERE condition。
而这里面这么多数据,我们最需要了解的则是查:
mysql查询语句形式主要如下:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
给出几条很常用的查询语句:
select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+
# 查数据库
select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+"
#查表名
select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='ctfshow_user')--+
#查询列名的:
select id,username,password from ctfshow_user --+"
查处列名下的值
以上就是数据库里面经常遇到的一些操作
information_schema:
下面熟悉数据库默认的系统库和表:
mysql 系统数据库
数据字典表
权限信息表
对象信息表
查询日志表
服务器端帮助信息表
时区信息表
复制信息表
优化器系统表
其他系统表
information_schema 信息数据库
再安全学习中,我们首先最需要了解的东西就是information_schema信息数据库:
再MYSQL版本>5.0的时候
INFORMATION_SCHEMA 数据库提供了访问数据库元数据的各种视图,包括数据库、表、字段类型以及访问权限等。这些信息有时候也被称为数据字典(data dictionary )或者系统目录(system catalog),主要来源就是 mysql 系统数据库中的数据字典表。
INFORMATION_SCHEMA 中的表实际上都是只读的视图,只能执行查询操作,不能执行 DML 语句。通常使用SHOW语句查看的信息都存在对应的数据字典表。
简单来说,这个表下面有整个数据库的库名,表名,列名:
我们以PHPADMIN为例看一看:
再来看看列名字:
information_schema再SQL注入漏洞中和CTF比赛中经常出现,我们经常做的是用来查去库,再通过联合查询查到表–>列–>值
而当MYSQL版本<5.0的时候:
mysql的低版本缺乏系统库information_schema,故通常情况下,我们无法直接查询表名,字段(列)名等信息,这时候只能靠猜来解决。
PHP连接查询数据库必用的函数:
mysql_connect:
在我们访问并处理数据库中的数据之前,必须创建到达数据库的连接。
在 PHP 中,这个任务通过 mysql_connect() 函数完成。
参数说明:mysqli_connect(host,username,password,dbname,port,socket);
host 可选。规定主机名或 IP 地址。
username 可选。规定 MySQL 用户名。
password 可选。规定 MySQL 密码。
dbname 可选。规定默认使用的数据库。
port 可选。规定尝试连接到 MySQL 服务器的端口号。
socket 可选。规定 socket 或要使用的已命名 pipe。
用法:
<?php
$con = mysql_connect("localhost","peter","abc123",‘my_dob’);
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
// some code
?>
mysql_close()
说明:关闭与数据库的连接
mysql_close()
<?php
$con = mysql_connect("localhost","peter","abc123");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
// some code
mysql_close($con);
?>
mysql_query() :
执行sql代码的一种函数:
mysql_query(query,connection)
query 必需。规定要发送的 SQL 查询。注释:查询字符串不应以分号结束。
connection 可选。规定 SQL 连接标识符。如果未规定,则使用上一个打开的连接。
用法:
<?php
$con = mysql_connect("localhost","mysql_user","mysql_pwd");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
$sql = "SELECT * FROM Person";
mysql_query($sql,$con);
// 一些代码
mysql_close($con);
?>
进行连接并且执行SQL查询(因为这个函数可以进行SQL执行,所以功能不仅仅是可以拿来查询,也可以拿来删库,建库等等)
mysqli_select_db():
mysqli_select_db() 函数用于更改连接的默认数据库。
connection 必需。规定要使用的 MySQL 连接。
dbname 必需,规定要使用的默认数据库。
示例:
<?php
// 假定数据库用户名:root,密码:123456,数据库:RUNOOB
$con=mysqli_connect("localhost","root","123456","RUNOOB");
if (mysqli_connect_errno($con))
{
echo "连接 MySQL 失败: " . mysqli_connect_error();
}
// ...查询 "RUNOOB" 数据库的一些 PHP 代码...
// 修改数据库为 "test"
mysqli_select_db($con,"test");
// ...查询 "test" 数据库的一些 PHP 代码...
mysqli_close($con);
?>