基础知识总结(九)

1创建仓库 添加文件/修改文件
初始化一个Git仓库,使用git init命令。
添加文件到Git仓库,分两步:
  • 第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件;
  • 第二步,使用命令git commit,完成。
2 查看修改
  • 要随时掌握工作区的状态,使用git status命令。
  • 如果git status告诉你有文件被修改过,用git diff<file>可以查看修改内容。
3 版本回退
  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本
4工作区和暂存区

工作区(Working Directory)

工作区就是你在电脑里能看到的目录

版本库(Repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
每次修改,如果不add到暂存区,那就不会加入到commit中。
5 版本回退
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
6 删除文件
命令git rm <--gile>用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

linux
7 lunix的启动过程
Linux系统的启动过程,其过程可以分为5个阶段:
内核的引导。
运行 init。
系统初始化。
建立终端 。
用户登录系统。

内核引导:   当计算机打开电源后,首先是BIOS开机自检,按照BIOS中设置的启动设备(通常是硬盘)来启动。
操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。

init过程:init 进程是系统所有进程的起点,你可以把它比拟成系统所有进程的老祖宗,没有这个进程,系统中任何进程都不会启动。
init 程序首先是需要读取配置文件 /etc/inittab。
许多程序需要开机启动。它们在Windows叫做"服务"(service),在Linux就叫做"守护进程"(daemon)。
init进程的一大任务,就是去运行这些开机启动的程序。
但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。
Linux允许为不同的场合,分配不同的开机启动程序,这就叫做"运行级别"(runlevel)。也就是说,启动时根据"运行级别",确定要运行哪些程序

系统初始化 : 在init的配置文件中有这么一行: si::sysinit:/etc/rc.d/rc.sysinit 它调用执行了/etc/rc.d/rc.sysinit,而rc.sysinit是一个bash shell的脚本,它主要是完成一些系统初始化的工作,rc.sysinit是每一个运行级别都要首先运行的重要脚本。
它主要完成的工作有:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。

建立终端:   rc执行完毕后,返回init。这时基本系统环境已经设置好了,各种守护进程也已经启动了。
init接下来会打开6个终端,以便用户登录系统。在inittab中的以下6行就是定义了6个终端:

用户登录系统:
一般来说,用户的登录方式有三种:(1)命令行登录(2)ssh登录(3)图形界面登录

8 关机相关命令 
sync 将数据由内存同步到硬盘中。
shutdown h 10 This server will shutdown after 10 mins 这个命令告诉大家,计算机将在 10 分钟后关机,并且会显示在登陆用户的当前屏幕中。

Shutdown h now 立马关机

Shutdown h 20 : 25 系统会在今天 20 : 25 关机
Shutdown h + 10 十分钟后关机

Shutdown r now 系统立马重启

Shutdown r + 10 系统十分钟后重启

reboot 就是重启,等同于 shutdown r now

halt 关闭系统,等同于 shutdown h now poweroff
9 linux 目录结构
在 Linux 或 Unix 操作系统中,所有的文件和目录都被组织成以一个根节点开始的倒置的树状结构。
文件系统的最顶层是由根目录开始的,系统使用 / 来表示根目录。在根目录之下的既可以是目录,也可以是文件,而每一个目录中又可以包含子目录文件。如此反复就可以构成一个庞大的文件系统。
在Linux文件系统中有两个特殊的目录,一个用户所在的工作目录,也叫当前目录,可以使用一个点 . 来表示;另一个是当前目录的上一级目录,也叫父目录,可以使用两个点 .. 来表示。
 . :代表当前的目录,也可以使用 ./ 来表示;
 .. :代表上一层目录,也可以 ../ 来代表。
如果一个目录或文件名以一个点 . 开始,表示这个目录或文件是一个隐藏目录或文件(如:.bashrc)。即以默认方式查找时,不显示该目录或文件。

10 linux 文件基本属性
在Linux中我们可以使用ll或者ls –l命令来显示一个文件的属性以及文件所属的用户和组
每个文件的属性由左边第一部分的10个字符来确定(如下图)。
对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。
同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。
文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。
因此,Linux系统按文件所有者、文件所有者同组用户和其他用户来规定了不同的文件访问权限。

11 更改文件属性命令

1、chgrp:更改文件属组

chgrp  [- R ]  属组名 文件名

2、chown:更改文件属主,也可以同时更改文件属组

chown  [– R ]  属主名  文件名
chown  [- R ]  属主名:属组名  文件名

12 处理目录的常见命令

ls: 列出目录
ls  [- aAdfFhilnrRSt ]  目录名称
-a :全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)
-d :仅列出目录本身,而不是列出目录内的文件数据(常用)
-l :长数据串列出,包含文件的属性与权限等等数据;(常用)
cd:切换目录
cd  [相对路径或绝对路径]
pwd:显示目前的目录
mkdir:创建一个新的目录
mkdir [- mp ] 目录名称
-m :配置文件的权限喔!直接配置,不需要看默认权限 (umask) 的脸色~
-p :帮助你直接将所需要的目录(包含上一级目录)递归创建起来
rmdir:删除一个空的目录
rmdir [- p ] 目录名称
-p :连同上一级『空的』目录也一起删除
cp: 复制文件或目录
[ root@www  ~]#  cp  [- adfilprsu ]  来源档( source )  目标档( destination )
[ root@www  ~]#  cp  [ options ]  source1 source2 source3  ....  directory
-a:相当於 -pdr 的意思,至於 pdr 请参考下列说明;(常用)
-d:若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;
-f:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;
-i:若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
-l:进行硬式连结(hard link)的连结档创建,而非复制文件本身;
-p:连同文件的属性一起复制过去,而非使用默认属性(备份常用);
-r:递归持续复制,用於目录的复制行为;(常用)
-s:复制成为符号连结档 (symbolic link),亦即『捷径』文件;
-u:若 destination 比 source 旧才升级 destination !

        rm: 移除文件或目录
       rm  [- fir ]  文件或目录
-f :就是 force 的意思,忽略不存在的文件,不会出现警告信息;
-i :互动模式,在删除前会询问使用者是否动作
-r :递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!

mv :移动文件或目录
[ root@www  ~]#  mv  [- fiu ]  source destination
[ root@www  ~]#  mv  [ options ]  source1 source2 source3  ....  directory

-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
    -u :若目标文件已经存在,且 source 比较新,才会升级 (update)

13 linux 磁盘管理
df:列出文件系统的整体磁盘使用量
du:检查磁盘空间使用量
        fdisk:用于磁盘分区
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看

14  vim
基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode)输入模式(Insert mode)底线命令模式(Last line mode)。 这三种模式的作用分别是:

命令模式:

用户刚刚启动 vi/vim,便进入了命令模式。
此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。
以下是常用的几个命令:
i 切换到输入模式,以输入字符。
x 删除当前光标所在处的字符。
: 切换到底线命令模式,以在最底一行输入命令。
若想要编辑文本:启动Vim,进入了命令模式,按下i,切换到输入模式。
命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。

输入模式

在命令模式下按下i就进入了输入模式。
在输入模式中,可以使用以下按键:
字符按键以及Shift组合,输入字符
ENTER,回车键,换行
BACK SPACE,退格键,删除光标前一个字符
DEL,删除键,删除光标后一个字符
方向键,在文本中移动光标
HOME/END,移动光标到行首/行尾
Page Up/Page Down,上/下翻页
Insert,切换光标为输入/替换模式,光标将变成竖线/下划线
ESC,退出输入模式,切换到命令模式

底线命令模式

在命令模式下按下:(英文冒号)就进入了底线命令模式。
底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。
在底线命令模式中,基本的命令有(已经省略了冒号):
q 退出程序
w 保存文件
按ESC键可随时退出底线命令模式

15 shell
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 个人感觉可以对应成 win 中的 bat,通过代码来实现一些自动定时任务,自动备份或者执行的任务。
1、 chmod +x file   加上执行权限,否则会提示无执行权限。
2、注意执行脚本时候或者全目录,或者   ./file.sh   ,如果不加的话,linux 默认会从PATH 里去找该 file.sh。

16 shell变量
定义变量:
定义变量时,变量名不加美元符号
注意,变量名和等号之间不能有空格
使用变量:
使用一个定义过的变量,只要在变量名前面加美元符号即可
已定义的变量,可以被重新定义

只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

删除变量
使用 unset 命令可以删除变量
变量被删除后不能再次使用。unset 命令不能删除只读变量。
变量类型
运行shell时,会同时存在三种变量:
1) 局部变量   局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量   所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量   shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运

shell字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
        单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号的优点:
双引号里可以有变量
        双引号里可以出现转义字符】
定义数组
在Shell中,用括号来表示数组,数组元素用"空格"符号分割开

读取数组:
读取数组元素值的一般格式是:
$ {数组名[下标]}

获取数组长度 
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length = $ {# array_name [@]} # 或者
length = $ {# array_name [*]} # 取得数组单个元素的长度
lengthn = $ {# array_name [ n ]}

shell注释
以"#"开头的行就是注释,会被解释器忽略。
sh里没有多行注释,只能每一行加一个#号。只能像这样:

16 shell 传参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为: $n n   代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
$#
传递到脚本的参数个数
$*
以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$
脚本运行的当前进程ID号
$!
后台运行的最后一个进程的ID号
$@
与$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$-
显示Shell使用的当前选项,与 set命令 功能相同。
$?
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

17 shell数组
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name =( value1  ...  valuen )

我们也可以使用下标来定义数组:
array_name [ 0 ]= value0
array_name [ 1 ]= value1
array_name [ 2 ]= value2

读取数组
读取数组元素值的一般格式是:
$ { array_name [ index ]}

获取数组中的所有元素
使用@ 或 * 可以获取数组中的所有元素

18 算术运算符
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

+
加法
`expr $a + $b` 结果为 30。
-
减法
`expr $a - $b` 结果为 -10。
*
乘法
`expr $a \* $b` 结果为  200。
/
除法
`expr $b / $a` 结果为 2。
%
取余
`expr $b % $a` 结果为 0。
=
赋值
a=$b 将把变量 b 的值赋给 a。
==
相等。用于比较两个数字,相同则返回 true。
[ $a == $b ] 返回 false。
!=
不相等。用于比较两个数字,不相同则返回 true。
[ $a != $b ] 返回 true。

19  test命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
-eq
等于则为真
-ne
不等于则为真
-gt
大于则为真
-ge
大于等于则为真
-lt
小于则为真
-le
小于等于则为真

20 流程控制
sh的流程控制不可为空
if else 语法格式:
if  condition
then
command1
command2
...
commandN
else
command
fi

for循环
for  var  in  item1 item2  ...  itemN
do
command1
command2
...
commandN
done

while循环 
while  condition
do
command
done

util循环一直到条件为真停止 与while相反
while  condition
do
command
done

case 模式 

case    in 模式 1 )
command1
command2
...
commandN
;; 模式 2
command1
command2
...
commandN
;; esac

21 shell函数
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
22 shell重定向
command > file
将输出重定向到 file。
command < file
将输入重定向到 file。
command >> file
将输出以追加的方式重定向到 file。
n > file
将文件描述符为 n 的文件重定向到 file。
n >> file
将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m
将输出文件 m 和 n 合并。
n <& m
将输入文件 m 和 n 合并。
<< tag
将开始标记 tag 和结束标记 tag 之间的内容作为输入。

23 shell文件包含


elasticsearch
.1 Node 与 Cluster
Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。
单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。
  • Node: 通常一台服务器上部署一台es node,作为集群的一部分,用于数据的存储和提供搜索功能,在一个集群中节点通过node.name区分,默认在node启动时随机生成一个的字符串做为节点名称,可配置
  • Index: 类似于关系型数据库中的database,用于组织一类功能相似的数据,在一个集群中可以定义任意个索引,索引的名称只能由小写字母组成,在数据索引,更新,搜索,删除时作为数据标识的一部分
  • Type: 类似于关系型数据库中的table,在Index中可以定义多个Type,原则上一个Type是由相同属性组成的数据集合
  • Document: 类似于关系型数据库中的record,是数据的最基本存储单元,使用json形式表示,Document在物理上存储在Index下,但是在逻辑上会分配到具体的Type下
  • Shards & Replica:
    一个Index可能存储大量的数据(超过单个节点的硬件限制),不管是数据存储还是数据索引,为解决数据单节点存储并提高并发,es将每一个Index物理分为多个片,从而水平扩展存储容量,提高并发(可以同时对个shard进行索引和搜索)
    为防止某个存储单元出现故障后数据不能索引的情况,es提供将shard进行复制功能,将主shard出现故障后,复制shard替代主shard进行数据索引操作,已此方式实现其高可用性,因为在搜索时可以使用复制shard,从而提高的数据搜索的并发性
    在Index创建时可以进行分片数量和复制数量的设置,默认创建每个Index设置5个shard和1个Replica,表示该Index由5个逻辑存储单元进行存储,每个逻辑存储单元具有一个复制节点进行备灾,注意,shard只能在创建Index时进行设置,shard数量与document分配到哪个shard上存储有关(通常使用hash(document _id) % shard num计算 document存储在哪个shard上)
    在es将主shard和replic分片在不同的Node

Index插入
新建 Index,可以直接向 Elastic 服务器发出 PUT 请求。
新增记录
向指定的 /Index/Type 发送 PUT 请求,就可以在 Index 里面新增一条记录。
查看记录
向/Index/Type/Id发出 GET 请求,就可以查看这条记录。
删除记录
删除记录就是发出 DELETE 请求。
更新记录
更新记录就是使用 PUT 请求,重新发送一次数据。


数据查询
基本匹配查询
基本匹配查询主要有两种形式:(1)使用Search Lite API,并将所有的搜索参数都通过URL传递;
(2)使用Elasticsearch DSL,其可以通过传递一个JSON请求来获取结果。

Multi-field Search
正如我们之前所看到的,想在一个搜索中查询多个 document field (比如使用同一个查询关键字同时在title和summary中查询),你可以使用multi_match查询

Bool Query
  我们可以在查询条件中使用AND/OR/NOT操作符,这就是布尔查询(Bool Query)。布尔查询可以接受一个must参数(等价于AND),一个must_not参数(等价于NOT),以及一个should参数(等价于OR)。

  Fuzzy   Queries (模糊查询)
    模糊查询可以在Match和 Multi-Match查询中使用以便解决拼写的错误,模糊度是基于Levenshteindistance计算与原单词的距离。
以下说明各个字段的含义:
took: 执行查询的时间(单位为毫秒)
timed_out: 执行不能超时
_shards: 提示有多少shard参与查询以及查询成功和失败shard数量
hits: 查询结果
hits.total: 文档总数
_score, max_score: 为文档与查询条件匹配度和最大匹配度

1 took :整个搜索请求花费了多少毫秒
2 hits.total :本次搜索,返回了多少条结果
3 hits.max_score :本次搜索的所有结果中,最大的相关度分数是多少,每一条 document 对于 search 的相关度,越相关, _score 分数越大,排位越靠前
4 hits.hits :默认查询前 10 条数据,完整数据, _score 降序排序
5 shards :表示本次搜索过程中的 shards 信息。 total   表示本次搜索请求一共路由到多少个 shards 中, "successful":   表示这些路由到的shards中有多少个是成功了的 ,"failed": 表示这些路由到的shards中有多少个是失败了的。
shards fail 的条件( primary replica 全部挂掉),不影响其他 shard 。默认情况下来说,一个搜索请求,会路由到一个 index 的所有 primary shard 上去,每个 primary shard 都可能会有一个或多个 replic shard ,所以请求也可以到 primary shard 的其中一个 replica shard 上去。
6 "hits"   一个数据,此次搜索返回的数据,默认返回 10 条,以 _score 降序排序


Elasticsearch查询分两个阶段查询阶段和提取阶段
查询阶段

客户端向集群中的某个节点(假设节点1)发起查询请求,节点1会创建一个from+size大小的队列(from:偏移量,size:要取回的文档个数)。
节点1向集群中所有其他的分片(主或从)发起查询请求,每个分片也会创建一个from+size大小的队列,并将查询结果添加到队列中。
其他分片将查询到的文档ID和排序值发送给节点1,节点1将所有结果进行合并并排序,添加到队列中

提取阶段
节点1根据文档ID发出请求到相关分片,相关分片查询出结果,并将结果返回给节点1
节点1将结果返回给客户端


Spring AOP的实现 
Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是 InvocationHandler 接口和 Proxy 类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为 final ,那么它是无法使用CGLIB做动态代理的。


2 高并发数据库设计要注意的问题
    1、数据行的长度不要超过8020字节,如果超过这个长度的话在物理页中这条数据会占用两行从而造成存储碎片,降低查询效率。
    2、能够用数字类型的字段尽量选择数字类型而不用字符串类型的(电话号码),这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
    3、对于不可变字符类型char和可变字符类型varchar 都是8000字节,char查询快,但是耗存储空间,varchar查询相对慢一些但是节省存储空间。在设计字段的时候可以灵活选择,例如用户名、密码等长度变化不大的字段可以选择CHAR,对于评论等长度变化大的字段可以选择VARCHAR。
    4、字段的长度在最大限度的满足可能的需要的前提下,应该尽可能的设得短一些,这样可以提高查询的效率,而且在建立索引的时候也可以减少资源的消耗。

3 b+树概念及特点
B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+树包含根节点、内部节点和叶子节点。根节点可能是一个叶子节点,也可能是一个包含两个或两个以上孩子节点的节点。
1.有n棵子树的结点中含有n个关键字,每个关键字不保存数据,只用来索引,所有数据都保存在叶子节点。
2.所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.所有的非终端结点可以看成是索引部分,结点中仅含其子树(根结点)中的最大(或最小)关键字。 
通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点

4查询优化
保证在实现功能的基础上,尽量减少对数据库的访问次数;通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;算法的结构尽量简单;在查询时,不要过多地使用通配符如SELECT * FROM T1语句,要用到几列就选择几列。
优化查询最重要的就是,尽量使语句符合查询优化器的规则避免全表扫描而使用索引查询。如:
1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
2. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。
5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。
eg: SELECT * FROM T1 WHERE NAME LIKE ‘%L%’ 
            SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’ 
            SELECT * FROM T1 WHERE NAME LIKE ‘L%’ 
    即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。


5 mysql 索引
聚集索引:表中各行的物理顺序与键值的逻辑(索引)顺序相同,表中只能包含一个聚集索引,主键列默认为聚集索引
MYSQL不支持非主键的聚集索引。
          mysql索引类型 : 1.普通索引  是最基本的索引,它没有任何限制。
 2.唯一索引  与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
3 主键索引    是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引:
.4 组合索引  指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合

6 三次握手连接

第一次

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次

第二次握手服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

ACK:确认标志   
SYN:同步标志

四次挥手
1) TCP客户端发送一个FIN,用来关闭客户到服务器的 数据传送
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端。
(4) 客户端发回ACK 报文 确认,并将确认序号设置为收到序号加1。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。



猜你喜欢

转载自blog.csdn.net/u013854708/article/details/80043333