SQL注入,外键使用,E-R模型及表间关系,三范式

SQL注入

学习目标

  • 能够说出如何避免 SQL 注入问题

1. 什么是SQL注入

  • SQL注入:

简单说sql注入是一种可以使得数据库中的数据泄露的方式. 如果有一些人有恶意的目的, 可以利用sql注入完成盗取数据.

  • 产生原因:

后台将用户提交的带有恶意的数据和SQL进行字符串方式的拼接,从而影响了SQL语句的语义,最终产生数据泄露的现象.

简单的说, 就是利用各种方式提交数据给程序并让这些数据和SQL语句产生结合, 进而让新产生的SQL语句和之前的原始的SQL语句变成不同的意思, 至此就可以利用新产生的SQL语句获取想要的数据了.

  • 防止SQL注入

SQL语句的参数化可以防止SQL注入的产生. 将SQL语句的所有数据参数存在一个列表中传递给execute函数的第二个参数进行执行, 就是SQL语句参数化.

python   # 把sql语句需要的参数放到一个列表中   my_list = [xxx,xxx,xxx]   # 把列表作为execute方法的第二个参数传递   cursor.execute(sql,my_list)

2. 非安全方式的SQL语句

 
 
 
 

from pymysql import connect

# 创建Connection连接
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')

# 获得Cursor对象
cur = conn.cursor()

# 获取用户想要查询的物品名称
find_name = input("请输入物品名称:")

# 非安全方式的sql语句
sql = 'select * from goods where name="%s"' % find_name

# 执行sql语句
count = cur.execute(sql)

# 获取查询的结果
result = cur.fetchall()

# 打印查询的结果
print(result)

# 关闭Cursor对象
cur.close()

# 关闭Connection对象
conn.close()

注意:

在输入商品名称的时候输入

 
 
 
 

# 双引号也要输入
" or 1=1 or "

这样就完成了一个简单的SQL注入

 
 
 
 

# 原始的sql语句
sql = 'select * from goods where name="%s"' % find_name
# 输入 " or 1=1 or " 后的sql语句
sql = 'select * from goods where name="" or 1=1 or ""'

这里 name= "" or 1=1 or "" 这个条件是一定成立的,因为or是或的意思多个条件只要有一个条件成立整体就成立,而1=1是一定成立的. 这就造成这个sql语句的意思发生里改变.

3. 安全方式的SQL语句

 
 
 
 

from pymysql import connect

# 创建Connection连接
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')

# 获得Cursor对象
cur = conn.cursor()

# 获取用户想要查询的物品名称
find_name = input("请输入物品名称:")

# sql语句
# 注意:
# 此处不同于python的字符串格式化,必须全部使用%s占位
# 所有参数所需占位符外不需要加引号
sql = 'select * from goods where name=%s'

# 安全的方式
# 构造参数列表
params = [find_name]
# 执行select语句
# 注意:
# 如果要是有多个参数,需要进行参数化
# 那么params = [数值1, 数值2....],此时sql语句中有多个%s即可
count = cur.execute(sql, params)

# 获取查询的结果
result = cur.fetchall()

# 打印查询的结果
print(result)

# 关闭Cursor对象
cur.close()

# 关闭Connection对象
conn.close()

利用参数化列表就可以完成防止SQL注入.

总结

SQL注入问题

  • 将SQL语句的所有数据参数存在一个列表中传递给execute函数的第二个参数

外键使用

学习目标:

  • 知道数据库表外键约束的作用

  • 能够为已经出存在的表添加外键约束

  • 能够创建表时增加外键约束

1. 外键

图片

下面咱们开始来验证外键的作用

  • 分别在 goods_cates 和 goods_brands表中插入记录

 
 
 
 

insert into goods_cates(name) values ('路由器'),('交换机'),('网卡');
insert into goods_brands(name) values ('海尔'),('清华同方'),('神舟');

  • 在 goods 数据表中写入任意记录

图片

 
 
 
 

insert into goods (name,cate_id,brand_id,price)
values('LaserJet Pro P1606dn 黑白激光打印机', 12, 4,'1849');

问题: SQL语句中的12代表什么意义 ? 没错 是cate_id 请问: goods_cates表中有id=12的记录吗 显然没有

图片

  • 查询所有商品的详细信息 (通过左连接 将左表未显示数据添加到最终结果)

 
 
 
 

select * from goods left join goods_cates on goods.cate_id = goods_cates.id;

发现问题: cate_id = 12的SQL语句名称插入的数据是有问题的。

图片

如何防止无效信息的插入,就是可以在插入前判断类型或者品牌名称是否存在呢? 可以使用之前讲过的外键来解决

  • 外键约束:对外键字段的值 在更新和插入时进行和引用的表中字段数据进行对比

  • 关键字: foreign key,只有 innodb数据库引擎 支持外键约束

2. 对于已经存在的字段添加外键约束

 
 
 
 

-- 给brand_id 添加外键约束和goods_brands的id建立外键关联
alter table goods add foreign key (brand_id) references goods_brands(id);
-- 给cate_id 添加外键约束和goods_cates的id建立外键关联
alter table goods add foreign key (cate_id) references goods_cates(id);

-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`jing_dong`.`#sql-403_5`, CONSTRAINT `#sql-403_5_ibfk_2` FOREIGN KEY (`cate_id`) REFERENCES `goods_cates` (`id`))

-- 给cate_id 添加外键失败
-- 会出现1452错误
-- 错误原因:已经添加了一个不存在的cate_id值12,因此需要先删除

delete from goods where cate_id = 12;
alter table goods add foreign key (cate_id) references goods_cates(id);

图片

  • 此时如果再次插入一个不存在的品牌(cate_id=12)的产品,会报错的

 
 
 
 

insert into goods (name,cate_id,brand_id,price) values('LaserJet Pro P1606dn 黑白激光打印机', 12, 4,'1849');

插入失败,报错如下:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`jing_dong`.`goods`, CONSTRAINT `goods_ibfk_2` FOREIGN KEY (`cate_id`) REFERENCES `goods_cates` (`id`))

图片

3. 在创建数据表的时候设置外键约束

  • 注意: goods 中的 cate_id 的类型一定要和 goods_cates 表中的 id 类型一致

 
 
 
 

create table goods(
id int primary key auto_increment not null,
name varchar(40) default '',
price decimal(5,2),
cate_id int unsigned,
brand_id int unsigned,
is_show bit default 1,
is_saleoff bit default 0,
foreign key(cate_id) references goods_cates(id),
foreign key(brand_id) references goods_brands(id)
);

4.  删除外键约束

 
 
 
 

-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table goods;

-- 获取名称之后就可以根据名称来删除外键约束
alter table goods drop foreign key 外键名称;

  • 使用到外键约束会极大的降低表更新的效率, 所以在追求读写效率优先的场景下一般很少使用外键。

总结

  • 将查询的数据直接插入表中  

 
 
 
 

insert into xxx (字段名) select 语句
将select语句的结果集插入到一个表中

  • 连表更新

 
 
 
 

update 表1 join 表2 on 连接条件
set 某表.字段=值

  • 外键约束作用    

子表中的外键字段在插入和更新 新值的时候 新值必须 在主表中相应字段出现过。

E-R模型及表间关系

学习目标

  • 了解E-R模型的组成部分

  • 能够举例说出生活中 1对1 1对多 多对多关系的例子

1. E-R模型

  • E-R模型简介

E-R模型即E-R图。

E-R图即实体-联系图(Entity Relationship Diagram),是指提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。由美籍华裔计算机科学家陈品山(Peter Chen)发明。

  • E-R模型的使用场景

  • 关系型数据库 关系模型的基础上,我们需要根据产品经理的设计策划,抽取出来模型与关系,制定出表结构,这是项目开始的第一步

  • 在设计阶段一般使用E-R模型进行建模。有很多设计数据库的软件,常用的如power designer,db desinger等,这些软件可以直观的看到实体及实体间的关系

  • 设计数据库,可能是由专门的数据库设计人员完成,也可能是由开发组成员完成,一般是项目经理带领组员来完成

  • 待设计完成E-R模型会将其转化为关系模型

图片

  • E-R模型组成元素

图片

E-R图用 实体、联系和属性这3个概念来描述现实问题, 有以下三种元素:

  • 实体型(Entity):具有相同属性的实体具有相同的特征和性质,用实体名及其属性名集合来抽象和刻画同类实体;在E-R图中用矩形表示,矩形框内写明实体名;比如 电商购物系统中用户、购物车、订单等都是实体。

  • 属性(Attribute):实体所具有的某一特性,一个实体可由若干个属性来刻画。在E-R图中用椭圆形表示,并用无向边将其与相应的实体连接起来;比如用户的ID、用户名、密码、昵称、身份证号码 都是属性。

  • 联系(Relationship): 实体彼此之间相互连接的方式称为联系,也称为关系。

 
 
 
 

实体: 用矩形表示,并标注实体名称

属性: 用椭圆表示,并标注属性名称

关系: 用菱形表示,并标注关系名称

联系可分为以下 3 种类型:一对一、一对多、多对多:

  • 关系也是一种数据,需要通过一个字段存储在表中

  • 实体A对实体B为1对1,则在表A或表B中创建一个字段,存储另一个表的主键值

图片

  • 实体A对实体B为1对多:在表B中创建一个字段,存储表A的主键值

图片

  • 实体A对实体B为多对多:新建一张表C,这个表只有两个字段,一个用于存储A的主键值,一个用于存储B的主键值

图片

总结

  • 范式就是设计数据库的通用规范。

  • E-R图由 实体、属性、实体之间的联系构成,主要用来描述 数据库中表结构。

猜你喜欢

转载自blog.csdn.net/Blue92120/article/details/131822129