查看自己push了多少行代码:
1 | git log --author='wzr1005' --pretty=tformat: --numstat | awk ' {add += $1; subs += $2; loc += $1 - $2 } END { printf "添加了%s,删除了%s,合计%s\n", add, subs, loc }' |
为了优化SQL语句的排序性能,最好的情况是避免排序,合理利用索引是一个不错的方法。
因为索引本身也是有序的,如果在需要排序的字段上面建立了合适的索引,那么就可以跳过排序的过程,提高SQL的查询速度。
数据库有哪些索引?
一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree)。索引是在表的列上创建。所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中。
请记住记住这一点:索引是一种数据结构 。
比如一列name,存在b-tree里面。
B-Tree 是最常用的用于索引的数据结构。因为它们是时间复杂度低, 查找、删除、插入操作都可以可以在对数时间内完成。另外一个重要原因存储在B-Tree中的数据是有序的。数据库管理系统(RDBMS)通常决定索引应该用哪些数据结构。但是,在某些情况下,你在创建索引时可以指定索引要使用的数据结构。
还有什么其他类型的索引?
使用R-Tree作为数据结构的索引通常用来为空间问题提供帮助。例如,一个查询要求“查询出所有距离我两公里之内的星巴克”,如果数据库表使用R- Tree索引,这类查询的效率将会提高。
另一种索引是位图索引(bitmap index), 这类索引适合放在包含布尔值(true 和 false)的列上,但是这些值(表示true或false的值)的许多实例-基本上都是选择性(selectivity)低的列。
数据库索引里究竟存的是什么?
你现在已经知道数据库索引是创建在表的某列上的,并且存储了这一列的所有值。
但是,需要理解的重点是数据库索引并不存储这个表中其他列(字段)的值。
举例来说,如果我们在Employee_Name列创建索引,那么列Employee_Age和Employee_Address上的值并不会存储在这个索引当中。
如果我们确实把其他所有字段也存储在个这个索引中,那就成了拷贝一整张表做为索引-这样会占用太大的空间而且会十分低效。
索引存储了指向表中某一行的指针
如果我们在索引里找到某一条记录作为索引的列的值,如何才能找到这一条记录的其它值呢?这是很简单 - 数据库索引同时存储了指向表中的相应行的指针。
指针是指一块内存区域, 该内存区域记录的是对硬盘上记录的相应行的数据的引用。因此,索引中除了存储列的值,还存储着一个指向在行数据的索引。
Employee_Name这列的某个值(或者节点)可以描述为 (“Jesus”, 0x82829),
数据库怎么知道什么时候使用索引?
当这个SQL (SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’
)运行时,数据库会检查在查询的列上是否有索引
假设Employee_Name列上确实创建了索引,数据库会接着检查使用这个索引做查询是否合理 - 因为有些场景下,使用索引比起全表扫描会更加低效。
通常来说, 你不会告诉数据库什么时候使用索引 - 数据库自己决定。
什么时候最好不要使用数据库索引?
那么,究竟什么时候不使用数据库索引更好呢?好吧,选择性值低时!为什么低选择性意味着使用索引不是一个好主意?好吧,想想看——假设我们想要运行一个查询来查找表中所有女性的名字——我们当然假设除了“性别”列之外还有另一列“姓名”。如果我们在一个包含 10,000 行的表中搜索所有女性行,那么很有可能 50% 的行是女性,因为实际上只有两个可能的值——男性和女性。假设 50% 的行确实是女性,那么这意味着我们必须访问索引 5,000 次才能找到所有女性行。访问索引需要时间,并消耗资源。 如果我们访问索引 5,000 次,那么直接访问表并进行全表扫描实际上更快。因此,您可以看到查询优化器使用选择性值来确定使用索引或直接读取表是否更有效。
如何在使用SQL创建索引:
之前的例子中,在Employee_Name列上创建索引的SQL如下:
1 | CREATE INDEX name_index |
1
2
1
2
如何创建联合索引
我们可以在雇员表上创建两个列的联合索引,SQL如下:
1 | CREATE INDEX name_index |
使用数据库索引会有什么代价?
那么,使用数据库索引有什么缺点呢?其一,索引会占用空间 - 你的表越大,索引占用的空间越大。
其二,性能损失(主要值更新操作),当你在表中添加、删除或者更新行数据的时候, 在索引中也会有相同的操作。
记住:建立在某列(或多列)索引需要保存该列最新的数据。
基本原则是只如果表中某列在查询过程中使用的非常频繁,那就在该列上创建索引。
联合索引
多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!
最左前缀原则:
顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上,注:如果第一个字段是范围查询需要单独建一个索引,
注:在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好,比如 userid 经常需要作为查询条件,而 mobile 不常常用,则需要把 userid 放在联合索引的第一位置,即最左边
同时存在联合索引和单列索引(字段有重复的),这个时候查询mysql会怎么用索引呢?
这个涉及到mysql本身的查询优化器策略了,当一个表有多条索引可走时, Mysql 根据查询语句的成本来选择走哪条索引;
有人说where查询是按照从左到右的顺序,所以筛选力度大的条件尽量放前面。网上百度过,很多都是这种说法,但是据我研究,mysql执行优化器会对其进行优化,
当不考虑索引时,where条件顺序对效率没有影响,真正有影响的是是否用到了索引!
用了索引就是严格按照顺序来的?
联合索引本质: 就是先查姓、再查名字、、、、、
当创建**(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及(a,b,c)联合索引**
想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!
联合索引规则:
命名规则: 表名_字段名
数据量少的字段不需要加索引
如果where条件中是OR关系,加索引不起作用
符合最左原则
联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找.因为只知道名,不知道姓没用
当最左侧字段是常量引用时,索引就十分有效。
两个或更多个列上的索引被称作复合索引。
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。
复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。
token是服务端生成给客户端的,
基于token的身份验证
使用基于token的身份验证方法,在服务端不需要存储用户的登录记录.
流程是这样的:
->客户端使用用户名跟密码去请求登录
->服务度段收到请求,去验证用户名和密码,验证成功后,服务端会签发一个token,再把这个token发送给客户端
->客户顿收到token以后可以把它存储起来,比如放在cookie里面或者local storage里面,客户端每次向服务端请求资源的时候需要带上服务端签发的token
->,服务端收到请求,然后去验证客户端请求里面带着的token
服务器上的token设置一个有效期,每次APP请求时都要验证token和有效期.
token的优势:
无状态,可扩展
在客户端存储的token是无状态的,并且能被扩展的.基于这种无状态和不存储session信息,负载均衡器能够将用户的信息从一个服务器传到另一个服务器上.如果将已经验证的信息保存在session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为session亲和性).用户量大时,可会造成一些拥堵.但是不要着急,使用token之后问题就会解决,因为token自己hold住了用户的验证信息.
安全性
请求过程中发送token而不再发送cookie能够防止csrf(跨站请求伪造).
如果黑客在其他页面设置了一个链接,这个链接指向一个网站的转账系统。并且当前用户是这个网站的会员,并且处于登陆的状态(也就是客户端浏览器存在存储合法的session_id的cookie),那么当用户点击了这个链接以后,那么客户端浏览器就会将用户的这些信息进行传递到服务端,但是这个链接具体做了什么,用户根本不知道,这也就做到了伪造了用户的身份,做了用户都不知道的事情。。。
csrf中伪造的请求可以在不得到cookie的情况下在请求头中带上cookie,为什么token不能在未知的情况下在伪造请求中发送,发送请求时不是都是浏览器提供吗?
那么应该怎么进行预防这种攻击那?目前主流的框架为了预防这种攻击,都是采用TOKEN机制。也就是说当用户与服务端进行交互的时候,传递一个加密字符串到服务端,服务端来检测这个字符串是否是合法的,如果不合法就有可能是黑客伪造用户信息进行请求的。
那么这个加密字符串是怎么生成的那?加密字符串是由后端程序生成,然后赋值到页面之上。一般是由当前控制器,方法,密钥,时间组合在一起加密而成。传递到服务端以后,服务端重新生成一遍,如果一致就是合法的,否则就是不合法的。
可扩展性
token能够将创建与其他程序共享权限的程序.例如,能将一个随便的社交账号和自己的大号联系起来.当通过服务登录(我们将这个过程Buffer)时,我们可以将这些buffer附到登录的数据流上.使用token时, 可以提供可选的权限给第三方应用程序,当用户想让另一个应用程序访问他们的数据,我们可以通过建立api,得出特殊权限的tokens
多平台跨域
提前先谈论下CORS(跨域资源共享), 对应用程序和服务进行扩展的时候,需要介入各种的设备和应用程序,让我们的api只提供数据服务,我们还可以做出设计选择来提供cdn中的资产.这消除了在为应用程序设置快速标头配置后CORS出现的问题,只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到.