渣渣小本求职复习之路每天一博客系列——数据库基础(MySQL)(4)

      前情回顾:昨天我们回忆了数据库基础中SQL语言的查询、视图以及索引,还顺带走马观花地了解了一下MySQL中存储引擎的概念和简单举例。

      昨天没发博客园首页,结果阅读量惊人地低,只有十几个。不过我并没有太过失望,因为起码我有十几个朋友可能是特地收藏了我的博客地址或在动态中关注到我的更新。想到这里,顿时就治愈了。

—————————————————————————其实也没怎么闲聊就结束了————————————————————————————

      今天的内容主要是关于MySQL,包括索引的设计和使用、SQL注入攻击介绍与防范。

第七章:索引的设计和使用

      在第六章,我们已经简单介绍了索引,在这里,我们将进一步了解MySQL中索引的设计和使用情况。

      第一节:设计索引的原则

      索引的设计并不是毫无规律可循的,有一些原则可以根据具体情况遵循,会有利于提升索引的使用效率,更高效地使用索引。

1.搜索的索引列。不一定是所要选择的列。换句话来说,最适合索引的列是出现在WHERE子句中的列,或连接子句中指定的,而不是出现在SELECT关键字后的选择列表中的列。

2.使用唯一索引。考虑某列值的分布,索引的列的基数越大,索引的效果越好。例如,存放出生日期的列具有不同值,很容易区分各行。而用来记录性别的列,只含有M和F,则对此列进行索引没有多大用处,因为不管搜索哪个值,都会得出大约一半的行。

3.使用短索引。如果对字符串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做。例如,如果有一个CHAR(200)列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。这样,能够节省大量空间,可能使查询更快。更为重要的是,对于较短的键值,所以呢高速缓存中的块能容纳更多的键值,因此,MySQL也可以在内存中容纳更多的值。这样就增加了找到行而不用读取索引中较多块的可能性。

4.利用最左前缀。在创建一个n列的索引时,实际是创建了MySQL可利用的n个索引。多列索引可起几个索引的作用,因为可利用索引中最左边的列集来匹配行。这样的列集称为最左前缀。(这个不是很明白)

5.不要过度索引。过度索引会占用额外的磁盘空间,降低写操作的性能。MySQL在生成一个执行计划时,要考虑各个索引,这也会带来更多的工作。

      第二节:BTREE索引与HASH索引

      索引分为B树索引、哈希索引、全文索引以及集群索引,而不同的存储引擎对它们的支持情况也有所不同。

      常见的几种存储引擎(MyISAM、InnoDB、MEMORY、MERGE和NDB)都支持B树索引,而哈希索引的支持者却只有MEMORY和NDB。MyISAM支持全文索引,InnoDB支持集群索引。

      不同类型的索引有各自的适用范围。下面就简单说说B树索引和HASH索引吧。

      HASH索引有一些重要的特征需要在使用的时候特别注意

1.只用于使用=<=>操作符的等式比较
2.优化器不能使用HASH索引来加速ORDER BY操作
3.MySQL不能确定在两个值之间大约有多少行。如果将一个MyISAM表改为HASH索引的MEMORY表,会影响一些查询的执行效率
4.只能使用整个关键字来索引一行。(这个不是很明白)

      而当对索引字段进行范围查询的时候,只有BTREE索引可以通过索引访问,而HASH索引实际上是全表扫描。

  确保索引能用上,就要注意SQL语句的编写。在创建索引(选择HASH或BTREE)的时候,应该根据需要视情况而定。

第八章:SQL注入攻击与防范

  SQL的安全问题一般都没什么人注意,这可能会给应用系统造成很大的安全隐患,其中最重要的就是SQL注入攻击,这也是在面试中经常会碰见的考察问题。

      第一节:SQL注入攻击的简单介绍

      SQL注入(SQL Injection) 攻击威力不小,攻击者可以利用它读取、修改或者删除数据库内的数据,获取数据库中的用户名和密码等敏感信息,甚至可以获得数据库管理员的权限。下面以一个PHP程序写成的用户登录验证程序举例说明SQL注入

      (1)创建用户表user

1 CREATE TABLE user(
2 userid int(11)  NOT NULL auto_increment,
3 username varchar(20) NOT NULL default ' ',
4 password  varchar(20) NOT NULL default ' ',
5 PRIMARY KEY (userid)
6 )TYPE=MyISAM AUTO_INCREMENT=3;

  (2)给用户表user添加一条用户记录

INSERT INTO 'user' VALUES(1,'angel','mypass');

  (3)验证用户root登录localhost服务器

 1 <?php
 2        $servername="localhost";
 3        $dbusername="root";
 4        $dbpassword="";
 5        $dbname="injection";
 6        mysql_connect($servername,$dbusername,$dbpassword) or die ( "mysql connection failed" );
 7        $sql="SELECT * FROM user WHERE username='$username' AND password='$password'";
 8        $result=mysql_db_query($dbname,$sql);
 9        $userinfo = mysql_fetch_array($result);
10        if (empty($userinfo)
11        {
12        echo "login failed";
13        }else{
14        echo "login success";
15        }
16        echo"<p>SQL Query:$sql<p>";
17        ?>

  (4)然后提交如下URL:

          http://127.0.0.1/injection/user.php?username=angel' or '1=1

             结果发现,这个URL竟然可以成功登录系统!这显然不行吖,无法无天了都!同样也可以利用如下的SQL的注释语句实现SQL诸如,如下面的例子:

1 http://127.0.0.1/injection/user.php?username=angel '#
2 http://127.0.0.1/injection/user.php?username=angel '/*

             因为在SQL语句中,“/*”或者“#”都可以将后面的语句注释掉,结果导致只根据用户名而没有密码的URL都成功进行了登录。利用“or”和注释符不同的地方在于,前者利用的是逻辑运算,而后者则是根据MySQL的特性,这个比逻辑运算简单多了。SQL注入攻击的手段还有很多,大家可以在多了解了解,知己知彼,方能百战百胜。

  第二节:SQL注入攻击常用防范措施

             方法1:PrepareStatement+Bind-variable

             对Java、JSP开发的应用,可以使用这个方法防止注入攻击,另外从PHP5.0开始,也在扩展的MySQLI中支持PrepareStatement。

             方法2:使用应用程序提供的转换函数

             很多API都提供了对特殊字符进行转换的函数,例如MySQL C API:使用mysql_real_escape_string()API调用。

             方法3:自定义函数进行校验

             验证的途径可以分为几种:(1)整理数据使之变得有效(2)拒绝已知的非法输入(3)只接受已知的合法输入。所以,如果想要获得最好的安全状态,目前最好的解决办法就是对用户提交或者可能改变的数据进行简单分类,分别应用正则表达式来对用户提供的输入数据进行严格的检测和验证。

————————————————————————————DAY TEN——————————————————————————————————

      今天的内容偏少了,嚷嚷着几天增量都没什么动静,我自己都不好意思。

1.今天到图书馆,感觉还不错,明天早上尽量早起再来。

2.好久没锻炼身体。上次跑步已经忘记是什么时候,打球也少了许多。怪不得最近小病小痛那么多,准程序员也要注意身体吖。

3.三分之一过去了,还有三分之二。

原文地址:https://www.cnblogs.com/levenyes/p/3392996.html