SQL
对SQL注入的理解
SQL注入的原理是将SQL代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。也就是说,在一些对SERVER端发起的请求参数中植入一些SQL代码,SERVER端在执行SQL操作时,会拼接对应参数,同时也将一些SQL注入攻击的“SQL”拼接起来,导致会执行一些预期之外的操作。
比如我们的登录功能,其登录界面包括用户名和密码输入框以及提交按钮,登录时需要输入用户名和密码,然后提交。此时调用接口/user/login/ 加上参数username、password,首先连接数据库,然后后台对请求参数中携带的用户名、密码进行参数校验,即SQL的查询过程。假设正确的用户名和密码为ls和123456,输入正确的用户名和密码、提交,相当于调用了以下的SQL语句。
SELECT * FROM user WHERE username = 'ls' AND password = '123456'
SQL中会将#及--以后的字符串当做注释处理,如果我们使用 ' or 1=1 # 作为用户名参数,那么服务端构建的SQL语句就如下:
select * from user where username='' or 1=1 #' and password='123456'
而#会忽略后面的语句,而1=1属于常等型条件,因此这个SQL将查询出所有的登录用户。其实上面的SQL注入只是在参数层面做了些手脚,如果是引入了一些功能性的SQL那就更危险了,比如上面的登录功能,如果用户名使用这个 ' or 1=1;delete * from users; #,那么在";"之后相当于是另外一条新的SQL,这个SQL是删除全表,是非常危险的操作,因此SQL注入这种还是需要特别注意的。
MySQL索引
理解:索引(Index)是帮助MySQL高效获取数据的数据结构,包括B+树或者Hash表。
为什么不用二分,二叉树?
因为二分要求检索数据有序,数据库存储的时候不一定满足
二叉树查找只能应用于二叉查找树,当节点自增时二叉树会退化为有序表,查找还是O(n);使用二叉树查询的时候,查询的时间复杂度是O(log n),查询的时间效率已经很快。但是二叉树存在一个问题是,每一个分支上,最多就只有两个分支,当数据量大的时候,就会导致树的高度很高,查询的时候,IO的次数就会增多,查询的效率就会有所下降。使用B树或者B+树,让一个节点,可以有多个分支,可以很好的降低树的高度,减少IO的次数,提升查询的效率。
为什么选择了B+ 树而不是B树?
- B树的特点是每一个节点中都会存储key和数据,而B+树只有叶子节点才会存储数据信息(这里的数据信息 指 索引的数据信息。针对聚簇索引),其他的节点都只会存储key的信息。Mysql在查询的时候,因为其他节点的数据量少,可以一次性的在内存中加载更多的key的数据,以供查询使用。
- B树的叶子节点之间是独立的,B+树的叶子节点之间有指针将叶子节点相连接起来。Mysql是一种关系型数据库,多个数据之间可能是存在一定的关系的,当查询某一个数据的时候,可能会查询和之相关的一些其他的数据,可以很好的支持范围查询。(数据都存在叶子节点且叶子节点之间有指针联系,方便进行范围查询)
- B树的查询效率不稳定,B+树查询的效率稳定。当查询数据的时候,B树在遇到满足条件的额数据之后,就会返回数据信息,不会走到叶子节点。但是B+树在查询的时候,无论如何都会走到叶子节点,才会获取到数据,并返回数据信息。
- 因为B+树的叶子节点不会存放数据信息(这里的数据信息指 完整的数据信息,包括了未添加索引的列的信息。即 索引中的 叶子节点,只会存放 索引列的数据,不包括未被索引的数据。聚簇索引包括所有数据,其他索引只包括 索引列和主键列),所以有更多的空间来存放key的信息,可以让树的高度更低,IO的次数更少,效率更高。
![]()
B+树的非叶子节点不存储data,只存储key;叶子节点不存储指针
优化后的B+树的叶子节点会带一个指向相邻叶子节点的顺序访问指针

索引类型
- 聚簇索引
聚簇索引是在索引树的叶子节点中保存了完整的数据信息,则索引称为聚簇索引。Mysql的 InnoDB引擎为主键创建的主键索引即是聚簇索引,数据文件即是索引文件。
![]()
- 非聚簇索引
非聚簇索引是指索引树的叶子节点中保存的不是完整的数据信息,而是指向数据的一个指针或者是地址信息等(MyIsam的主键索引是指向数据的地址信息,InnoDB 中是主键的Id)。如果需要获取全部的数据信息,需要进行一次回表的操作。



浙公网安备 33010602011771号