码迷,mamicode.com
首页 > 数据库 > 详细

MySQL

时间:2017-06-23 23:47:12      阅读:338      评论:0      收藏:0      [点我收藏+]

标签:通过   对比   any   sql   linux   str   column   2.7   ogg   

 

第1章 数据库

2.3 数据库安装

MySQL家谱:

1、正宗后代

3.26 MySQL-5.0.xx到MySQL-5.1.xx的产品线 5.2 yum自带

正式中很少用了。

yum info mysql

yum grouplist

 

2*****、MySQL-5.4.xx-到MySQL-5.7.xx产品线 主流。

主流5.5 5.6 5.7

讲此产品线,5.6.34

 

3、MySQL-Cluster-6.0.xx-到MySQL-Cluster-7.5.xx产品线

类似 ORACLE RAC

2.4 数据库常见安装方法:

mysql安装方法:

1、yum/rpm 安装  适合并发不大,企业内部的一些应用场景 不能定制

 

2、二进制安装比较简单方便 适合5.0-5.1和5.5-5.6系列,

解压即可

 

3、编译安装 5.5-5.6系列采用cmake编译方式*******常用

./cmake ,make, makeinstall

 

4、5.0产品线 configure ,make make install

 

5、利用源码编译安装,做成rpm包,然后在yum仓库 yum安装

 

建议:MySQL5.5及以上版本,安装方式机器数量少的话,推荐cmake编译安装 数量多就用二进制免安装,如果数量特别大,可以选择定制rpm包的安装方式

 

讲5.6.34,cmake安装。

 

第3章 单实例安装:

3.1 安装过程

1、  安装MySQL所需要的依赖包和编译软件(cmake

[root@db02 ~]# yum install -y ncurses-devel libaio-devel

[root@db02 ~]# yum install -y cmake

[root@db02 ~]# rpm -qa ncurses-devel libaio-devel cmake

ncurses-devel-5.7-4.20090207.el6.x86_64

cmake-2.8.12.2-4.el6.x86_64

libaio-devel-0.3.107-10.el6.x86_64

2、  创建用户

[root@db02 ~]# useradd mysql -s /sbin/nologin -M

[root@db02 ~]# id mysql

uid=501(mysql) gid=501(mysql) groups=501(mysql)

3、上传源码安装包并解压

[root@db02 ~]# cd /home/oldboy/tools/

rz传入

[root@db02 tools]# tar xf mysql-5.6.34.tar.gz

4、编译、

[root@db02 tools]# cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.34 \

-DMYSQL_DATADIR=/application/mysql-5.6.34/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.6.34/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_EXTRA_CHARSETS=all \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITH_ZLIB=bundled \

-DWITH_SSL=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DENABLE_DOWNLOADS=1 \

-DWITH_DEBUG=0

3.2 cmake编译参数

 

 

5、编译安装

make &&make install

提示:

#错误情况:磁盘满了,内存扩大会提高速度

#1)请提前加大VM虚拟机硬件的内存,这样编译时候会更快,最好设置2GB以上的内存。

#3)重视每个操作过程的输出,有错误要解决掉再继续,不能忽略掉操作中的错误(error)。

6、做软链接

ln -s /application/mysql-5.6.34/ /application/mysql

7、配置MySQL配置文件

cp support-files/my*.cnf /etc/my.cnf

8、初始化

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql

9、授权mysql用户

chown -R mysql.mysql /application/mysql/

10、复制mysql启动文件

cp support-files/mysql.server /etc/init.d/mysqld

11、授权mysql启动文件

chmod 700 /etc/init.d/mysqld

12、加入开机自启动

chkconfig mysqld on

chkconfig --list mysqld

13、启动mysql

/etc/init.d/mysqld start

netstat -lntup|grep 330

14、设置mysql全局环境变量

echo ‘PATH=/application/mysql/bin/:$PATH‘ >>/etc/profile

tail -1 /etc/profile

source /etc/profile

echo $PATH

mysql

重新初始化

##############################################################

#重新初始化

#rm -fr /application/mysql/data/*

#授权mysql用户

chmod 700 /etc/init.d/mysqld

chown -R mysql.mysql /application/mysql/

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql

[root@db02 mysql-5.6.34]# pwd

/home/oldboy/tools/mysql-5.6.34

cp support-files/my-default.cnf /etc/my.cnf

/etc/init.d/mysqld start

##############################################################

 

15、设置密码:

mysqladmin -u root password ‘oldboy123‘

 

 

 

3.2.1 清理用户及无用数据库(基本优化)

select user,host from mysql.user;

drop user ‘‘@‘db02‘;

drop user ‘‘@‘localhost‘;

drop user ‘root‘@‘db02‘;

drop user ‘root‘@‘::1‘;

select user,host from mysql.user;

drop database test;

show databases;

##################

3.3 排错

tail -100 /application/mysql/data/db02.err

常见错误

3.3.1 启动问题四:

常见问题1

[root@mysql02 ~]# /etc/init.d/mysqld start

Starting MySQL.Logging to ‘/application/mysql-5.6.36/data/mysql02.err‘.

170618 18:59:33 mysqld_safe Directory ‘/application/mysql-5.6.36/tmp‘ for UNIX socket file don‘t exists.

 ERROR! The server quit without updating PID file (/application/mysql-5.6.36/data/mysql02.pid).

解决方法:

[root@mysql02 ~]# mkdir /application/mysql/tmp

[root@mysql02 ~]# chown -R mysql.mysql /application/mysql/

[root@mysql02 ~]# /etc/init.d/mysqld start

Starting MySQL.Logging to ‘/application/mysql-5.6.36/data/mysql02.err‘.

. SUCCESS!

常见问题2

故障:ERROR! The server quit without updating PID file

1.权限.chown -R mysql.mysql

2.killall mysqld

3.重新初始化.

4.运行1年了,出问题(非法关机或者关数据库).

 

第4章 多实例介绍

4.1 什么是MySQL多实例?

在一台服务器上安装一套MySQL程序,起多个不同的端口,通过不同的端口提供服务 ,多实例配置用多个配置文件配置  server_id的区别 端口的区别 数据文件路径的区别

 

 

 

4.2 MySQL多实例的作用,

·有效利用服务器资源

当单个服务器资源有剩余时,可以充分利用剩余的资源提供更多的服务,且可以实现资源的逻辑隔离。

节约服务器资源

当公司资金紧张,但是数据库又需要各自尽量独立地提供服务,而且,需要主从复制等技术时,多实例就再好不过了。

MySQL多实例有它的好处,但也有其弊端,比如,会存在资源互相抢占的问题

当某个数据库实例并发很高或有SQL慢查询时,整个实例会消耗大量的系统CPU、磁盘I/O等资源,导致服务器上的其他数据库实例提供服务的质量一起下降。这就相当于大家住在一个房子的不同卧室一样,早晨起来上班,都要刷牙、洗脸等,这样卫生间就会长期占用,其他人要等待一样。不同实例获取的资源是相对独立的,无法像虚拟化一样完全隔离。

4.3 MySQL多实例的生产应用场景

4.3.1 资金紧张型公司的选择

若公司资金紧张,公司业务访问量不太大,但又希望不同业务的数据库服务各自尽量独立地提供服务而互相不受影响,同时,还需要主从复制等技术提供备份或读写分离服务,那么,多实例就再好不过了。例如:可以通过3台服务器部署9~15个实例,交叉做主从复制、数据备份及读写分离,这样就可达到9~15台服务器每个只装一个数据库才有的效果。这里要强调的是,所谓的尽量独立是相对的。

4.3.2 并发访问不是特别大的业务

当公司业务访问量不太大的时候,服务器的资源基本上都浪费了,这时就很适合多实例的应用,如果对SQL语句的优化做得比较好,MySQL多实例会是一个很值得使用的技术,即使并发很大,合理分配好系统资源,搭配好服务,也不会有太大问题。

4.3.3 门户网站应用MySQL多实例场景

门户网站通常都会使用多实例,因为配置硬件好的服务器,可节省IDC机柜空间,同时,跑多实例也会减少硬件资源跑不满的浪费。比如,百度公司的很多数据库都是多实例,不过,一般是从库多实例,例如某部门中使用的IBM服务器为48核CPU,内存96GB,一台服务器跑3~4个实例;此外,新浪网使用的也是多实例,内存48GB左右。

 

 

 

 

4.4 多实例安装:

#####################################

多实例安装 多实例与单实例只能用一个

 

1、安装MySQL所需要的依赖包和编译软件(cmake

[root@db02 ~]# yum install -y ncurses-devel libaio-devel

[root@db02 ~]# yum install -y cmake

[root@db02 ~]# rpm -qa ncurses-devel libaio-devel cmake

ncurses-devel-5.7-4.20090207.el6.x86_64

cmake-2.8.12.2-4.el6.x86_64

libaio-devel-0.3.107-10.el6.x86_64

2、创建用户

[root@db02 ~]# useradd mysql -s /sbin/nologin -M

[root@db02 ~]# id mysql

uid=501(mysql) gid=501(mysql) groups=501(mysql)

3、上传源码安装包并解压

[root@db02 ~]# cd /home/oldboy/tools/

rz传入

wget -q http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.34.tar.gz

[root@db02 tools]# tar xf mysql-5.6.34.tar.gz

4、编译、

[root@db02 tools]# cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.34 \

-DMYSQL_DATADIR=/application/mysql-5.6.34/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.6.34/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_EXTRA_CHARSETS=all \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITH_ZLIB=bundled \

-DWITH_SSL=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DENABLE_DOWNLOADS=1 \

-DWITH_DEBUG=0

5、编译安装

make &&make install

提示:

#错误情况:磁盘满了,内存扩大会提高速度

#1)请提前加大VM虚拟机硬件的内存,这样编译时候会更快,最好设置2GB以上的内存。

#3)重视每个操作过程的输出,有错误要解决掉再继续,不能忽略掉操作中的错误(error)。

6、做软链接

ln -s /application/mysql-5.6.34/ /application/mysql

 

 

若安装了mysql单实例关闭单实例

[root@db02 mysql-5.6.34]# /etc/init.d/mysqld stop  关闭单实例

Shutting down MySQL.. SUCCESS!

[root@db02 mysql-5.6.34]# chkconfig mysqld off   关闭单实例

 

7、把data.zip放入/

unzip data.zip 解压配置文件包

[root@db02 /]# tree /data/

/data/

├── 3306

│?? ├── my.cnf

│?? └── mysql

└── 3307

    ├── my.cnf

└── mysql

8、创建多实例目录

mkdir /data//{3306,,3307}/data -p

9、授权多实例目录

chown -R mysql.mysql /data/

10、授权启动文件执行权限

find /data/ -name mysql|xargs chmod 700

find /data/ -name mysql|xargs ls -l

11、初始化

cd /application/mysql/scripts

./mysql_install_db  --defaults-file=/data/3306/my.cnf --basedir=/application/mysql/ --datadir=/data/3306/data --user=mysql

./mysql_install_db  --defaults-file=/data/3307/my.cnf --basedir=/application/mysql/ --datadir=/data/3307/data --user=mysql

12、设置全局环境变量

echo ‘PATH=/application/mysql/bin/:$PATH‘ >>/etc/profile

tail -1 /etc/profile

source /etc/profile

13、启动多实例MySQL

[root@db02 tools]# /data/3306/mysql start

Starting MySQL...

[root@db02 tools]# /data/3307/mysql start

Starting MySQL...

14、登录多实例数据库

[root@db02 tools]# mysql -S /data/3306/mysql.sock

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.6.34 Source distribution

 

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

 

mysql>

15、给mysql设置密码

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3306/mysql.sock

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3307/mysql.sock

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3308/mysql.sock

16、登录有密码的实例

[root@db02 scripts]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock

17、#有密码改密码

[root@db02 scripts]# mysqladmin -poldboy456 password oldboy123 -S /data/3307/mysql.sock

 

4.5 现场作业:请你增加一个3308实例。

mkdir -p /data/3308/data

\cp /data/3306/my.cnf  /data/3308/

\cp /data/3306/mysql  /data/3308/

sed -i ‘s/3306/3308/g‘ /data/3308/my.cnf

sed -i ‘s/server-id = 6/server-id = 8/g‘ /data/3308/my.cnf

sed -i ‘s/3306/3308/g‘ /data/3308/mysql

chown -R mysql:mysql /data/3308

chmod 700 /data/3308/mysql

cd /application/mysql/scripts

./mysql_install_db --defaults-file=/data/3308/my.cnf --datadir=/data/3308/data --basedir=/application/mysql --user=mysql

chown -R mysql:mysql /data/3308

egrep "server-id|log-bin" /data/3308/my.cnf

/data/3308/mysql start

sleep 5

netstat -lnt|grep 3308

 

 

 

 

 

 

 

 

第5章 MySQL安全优化

 

 

不要给数据库外网IP

 

第6章 mysql启动基本原理

6.1 MySQL单实例启动基本原理说明

/etc/init.d/mysqld是一个shell启动脚本,启动后最终会调用mysqld_safe脚本,最后调用mysqld主程序启动mysql,如下,/etc/init.d/mysqld脚本中调用mysqld_safe的程序。

/etc/init.d/mysqld启动:

$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

/etc/init.d/mysqld 停止:

if (kill -0 $mysqld_pid 2>/dev/null)

      then

        echo $echo_n "Shutting down MySQL"

        kill $mysqld_pid

6.2 MySQL单实例服务启动小结

1)使用/etc/init.d/mysqld start 命令启动数据库的本质就相当于执行mysqld_safe --user=mysql &命令

2)后文老男孩自己开发shell脚本启动多实例数据库时就是调用的mysqld_safe程序。

3)在找回MySQL root密码时,也会使用musqld_safe程序并带忽略授权表的参数启动来找回root密码

请描述MySQL启动与关闭的原理?
mysql 使用start启动,调用mysqld_safe指向配置文件来管理mysqld的进程。
mysql 使用stop关闭原理,是利用KIll的方式杀掉mysqld_pid进程号。

6.3 关闭MySQL数据库的方法选择顺序如下:

第一种、最先使用MySQL自带的管理脚本,实例如下:

/etc/init.d/mysqld stop

第二种:为mysqladmin管理方法:

mysqladmin -uroot -poldboy123 shutdown #===这个命令最大的障碍就是必须事先知道密码。

第三种:为利用系统进程管理命令关闭MySQL

kill pid ##==这里的pid为数据库服务对应的进程号、

killall mysqld ##==这里的mysqld是数据库服务对应的进程名字。

pkill mysqld    ##==这里的mysqld是数据库服务对应的进程名字

可通过如下地址查看生产高并发环境野蛮粗鲁杀死数据库导致故障企业案例:

http://oldboy.blog.51cto.com/2561410/1431161

http://oldboy.blog.51cto.com/2561410/1431172

 

6.4 作业:自己写一个单实例mysql启动脚本,并且能够加入chkconfig管理.

 

 

6.5 多实例MySQL 启动与关闭方法示例

下面来看一下多实例MySQL启动与关闭方法的原理

启动3306实例命令服务的命令为/data/3306/mysql start 实际上就是mysql_safe加上不同的实例配置文件参数启动实例如下:

mysqld_safe --defaults-file=/data/3306/my.cnf >/dev/null 2>&1 &

停止3306实例命令为/data/3306/mysql stop 实际上就是使用的mysqladmin命令的方法

mysqladmin -u root -podlboy123 -S /data/3306/mysql.sock shutdown

也可以用kill的方式

 

第7章 MySQL登录、密码设置、查询帮助

7.1 MySQL登录优化

登录安全优化:/etc/my.cnf

[client]

user=root

password=oldboy123

设置:600

chmod 600 /etc/my.cnf

 

登录

[root@db02 ~]# mysql    单实例

[root@db02 ~]# mysql  -S /data/3306/mysql.sock  多实例

 

 

 

[root@db02 ~]# HISTCONTROL=ignorespace  忽略开头空格的记录 可以加入环境变量

[root@db02 ~]#  mysql -uroot -poldboy -S /data/3306/mysql.sock 安全登录加空格开头

7.2 查看MYSQL命令帮助

man linux命令及配置文件\函数等.

help linux内置命令

 

mysql帮助:

help或?

到底.

#设置MySQL的提示符

mysql> prompt \u@oldboy \r:\m:\s-->

PROMPT set to ‘\u@oldboy \r:\m:\s-->‘

root@oldboy 11:41:12-->

 

 

7.3 设置及修改MySQL root用户密码

方法1:

单实例修改:mysqladmin -uroot -poldboy123 password oldboy

多实例修改:mysqladmin -uroot -poldboy -S /data/3306/mysql.sock password oldboy123

方法二:

mysql登录后修改

mysql> update mysql.user set password=password(‘1234‘) where user=‘root‘ and host=‘localhost‘;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

7.4 单实例找回MySQL root用户密码(面试题)

单实例:

忽略授权表启动:

单实例:mysqld_safe --skip-grant-table --user=mysql &

多实例:mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-table &

直接mysql 命令登录

修改密码:update mysql.user set password=PASSWORD("oldboy1234") where user=‘root‘ and host=‘localhost‘;

#刷新flush privileges;

#成功登录mysql -uroot -poldboy1234

#重启MySQL

pkill mysql    杀掉MySQL

/etc/init.d/mysqld start    正常启动

mysql -uroot -poldboy1234   登录成功

###############################################

7.5 多实例找回MySQL-root密码丢失############

###############################################

#跳过授权表不验证启动

[root@db02 ~]# mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-table &

[root@db02 ~]# mysql -uroot -S /data/3306/mysql.sock  登录

 

#修改密码

mysql> update mysql.user set password=PASSWORD("oldboy1234") where user=‘root‘ and host=‘localhost‘;

Query OK, 1 row affected (0.12 sec)

Rows matched: 1  Changed: 1  Warnings: 0

#刷新

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

#成功登录

[root@db02 ~]# mysql -uroot -poldboy1234 -S /data/3306/mysql.sock

 

#重启MySQL

[root@db02 ~]# mysqladmin -uroot -poldboy123 -S /data/3306/mysql.sock shutdown

[root@db02 ~]# mysqld_safe --defaults-file=/data/3306/my.cnf &

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock 登录

7.6 小结

 

第8章 SQL语句DDL DCL DML

DDL(Data Definition Language)——数据定义语言(create,alter,drop),管理基础数据,例如:库,表   #←运维要熟练、开发也要熟练

DCL(Data Control Language)——数据控制语言(grant,revoke,commit,rollback),用户授权,权限回收,数据提交回滚等 #←运维要熟练

DML(Data Manipulation Language)——数据操作语言(select,insert,delete,update),针对数据库里的表的数据进行操作,记录  #←开发要熟练,运维要了解

 

SQL分类:

DDL 数据定义语言  管理库和表     create,drop,alter等.            *****熟练

DCL 数据控制语言  用户管理授权   grant,revoke,commit;rollback.   *****熟练

DMC 数据操作语言  针对表里的数据 insert,delete,update,select     *****熟悉\开发熟练.

 

8.1 SQL语句基本操作

8.1.1 查看数据库:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| oldboy             |

| performance_schema |

+--------------------+

4 rows in set (0.00 sec)

8.1.2 创建数据库

mysql> create database linjie;

Query OK, 1 row affected (0.01 sec)

8.1.3 指定字符集建库

CREATE DATABASE db_name CHARACTER SET  charset_name COLLATE collation_name

CREATE DATABASE oldgirl CHARACTER SET gbk COLLATE gbk_chinese_ci;

show character set;找字符集.

mysql> create database linjie character set gbk COLLATE gbk_chinese_ci;

Query OK, 1 row affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

8.1.4 改库的字符集

mysql> alter database linjie character set utf8 collate utf8_general_ci;

Query OK, 1 row affected (0.00 sec)

mysql> show create database linjie\G

*************************** 1. row ***************************

       Database: linjie

Create Database: CREATE DATABASE `linjie` /*!40100 DEFAULT CHARACTER SET utf8 */

1 row in set (0.00 sec)

8.1.5 查看建库语句

mysql> show create database mysql\G

*************************** 1. row ***************************

       Database: mysql

Create Database: CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */

1 row in set (0.00 sec)

8.1.6 删库

mysql> drop database linjie;

Query OK, 0 rows affected (0.00 sec)

8.1.7 切库

mysql> use oldboy;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

8.1.8 查看当前所在库

mysql> select database();

+------------+

| database() |

+------------+

| oldboy     |

+------------+

1 row in set (0.00 sec)

8.1.9 查看库里的表

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

| test             |

+------------------+

2 rows in set (0.00 sec)

8.2 DDL&&DCL语句之管理用户

8.2.1 查看当前数据库的用户列表

mysql> select user,host from mysql.user;

+--------+--------------------------+

| user   | host                     |

+--------+--------------------------+

| oldboy | %                        |

| root   | 127.0.0.1                |###数据核心保留管理员用户

| oldboy | 172.16.1.%               |

| oldboy | 172.16.1.0/255.255.255.0 |

| oldboy | localhost                |

| root   | localhost                | ###数据库核心保留管理员用户

+--------+--------------------------+

6 rows in set (0.00 sec)

 

8.2.2 创建用户

CREATE

USER

‘用户‘@‘主机‘

IDENTIFIED BY ‘密码‘

动作(创建)

对象(用户)

用户和从哪个主机登录

设定密码

现在创建一个oldboy用户,只允许本地主机登录,密码是oldboy123.

CREATE USER ‘用户‘@‘主机‘ IDENTIFIED BY ‘密码‘;

create user ‘oldboy‘@‘locahost‘ identified by ‘oldboy123‘;  #只能连接

 

mysql> create user linjie@‘localhost‘ identified by ‘123456‘;

Query OK, 0 rows affected (0.00 sec)

企业里创建用户一般是授权一个内网网段登录,最常见的网段写法有两种。

方法1:172.16.1.%(%为通配符,匹配所有内容)。

方法2:172.16.1.0/255.255.255.0,但是不能使用172.16.1.0/24,是个小遗憾。

8.2.3 查看用户对应的权限

mysql> show grants for linjie@‘localhost‘;

+---------------------------------------------------------------------------------------------------------------+

| Grants for linjie@localhost                                                                                   |

+---------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO ‘linjie‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘ |

+---------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

mysql> show grants for linjie@‘localhost‘\G

*************************** 1. row ***************************

Grants for linjie@localhost: GRANT USAGE ON *.* TO ‘linjie‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘

1 row in set (0.00 sec)

8.2.4 删除用户

drop user ‘user‘@‘主机域‘

注意引号,可以是单或双引号,规范是最好加单引号。

drop

user

‘user‘@‘主机域‘

动作(删除)

对象(用户)

具体用户

删除上述中的oldboy用户:

mysql> select user,host from mysql.user where user=oldboy‘; ###删除前检查

+------+-----------+

| user | host      |

+------+-----------+

| oldboy | localhost |

+------+-----------+

1 row in set (0.01 sec)

mysql> drop user oldboy@localhost;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select user,host from mysql.user where user=‘oldboy‘;

Empty set (0.00 sec)

8.2.5 特殊的删除方法:

mysql> delete from mysql.user where user=‘bbs‘ and host=‘172.16.1.%‘;

Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

8.2.6 给用户授权

8.2.6.1  grant命令语法

1、通过在mysql中输入“help grant”得到如下帮助信息。

 

……

CREATE USER ‘jeffrey‘@‘localhost‘ IDENTIFIED BY ‘mypass‘;

GRANT ALL ON db1.* TO ‘jeffrey‘@‘localhost‘;

GRANT SELECT ON db2.invoice TO ‘jeffrey‘@‘localhost‘;

GRANT USAGE ON *.* TO ‘jeffrey‘@‘localhost‘ WITH MAX_QUERIES_PER_HOUR 90;

……

通过查看grant的命令帮助,可以很容易的找到创建用户并授权的例子。

 

2、运维人员比较常用的创建用户的方法是,使用grant命令在创建用户的同时进行权限授权。具体授权例子为:

grant all privileges on dbname.* to username@localhost identified by ‘密码‘;

##前面的引号可以没有,但是密码一定要引起来

grant

all

on dbname.*

to username@localhost

identified by ‘passwd‘

授权命令

对应权限

目标:库和表

用户名和客户端主机

用户密码

 

mysql> grant all on kkk.* to www@localhost identified by ‘123456‘;

Query OK, 0 rows affected (0.00 sec)

mysql> select user,host from mysql.user where user=‘www‘;

+------+-----------+

| user | host      |

+------+-----------+

| www  | localhost |

+------+-----------+

1 row in set (0.01 sec)

3、操作案例1:创建test用户,对oldboy库具备所有权限,允许从localhost主机登录管理数据库,密码为123456.

实现上述操作的具体命令为:

grant all privileges on oldboy.* to ‘test‘@‘localhost‘ identified by ‘123456‘;

操作过程如下:

查看当前数据库用户情况,然后执行对应命令授权如下:

mysql> grant all privileges on oldboy.* to ‘test‘@‘localhost‘ identified by ‘123456‘;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select user,host from mysql.user where user=‘test‘;

+------+-----------+

| user | host      |

+------+-----------+

| test | localhost |

+------+-----------+

1 row in set (0.00 sec)

操作案例2:创建一个权限和root一样大的system用户(with grant option是下面命令的重点)。

mysql> show grants for root@localhost;   ###先查看root用户的权限

+----------------------------------------------------------------------------------------------------------------------------------------+

| Grants for root@localhost                                                                                                              |

+----------------------------------------------------------------------------------------------------------------------------------------+

| GRANT ALL PRIVILEGES ON *.* TO ‘root‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515‘ WITH GRANT OPTION |

| GRANT PROXY ON ‘‘@‘‘ TO ‘root‘@‘localhost‘ WITH GRANT OPTION                                                                           |

+----------------------------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

mysql> grant all on *.* to ‘system‘@‘localhost‘ identified by ‘123456‘ with grant option;  ##创建

Query OK, 0 rows affected (0.00 sec)

 

mysql> show grants for system@localhost;

+------------------------------------------------------------------------------------------------------------------------------------------+

| Grants for system@localhost                                                                                                              |

+------------------------------------------------------------------------------------------------------------------------------------------+

| GRANT ALL PRIVILEGES ON *.* TO ‘system‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘ WITH GRANT OPTION |

+------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

8.2.7 创建用户同时授权

grant all on *.* to oldgirl@‘172.16.1.%‘ identified by ‘oldgirl123‘;

grant all on *.* to oldgirl@‘172.16.1.0/255.255.255.0‘ identified by ‘oldgirl123‘;

flush privileges;

mysql> show grants for oldgirl@‘172.16.1.0/255.255.255.0‘\G

*************************** 1. row ***************************

Grants for oldgirl@172.16.1.0/255.255.255.0: GRANT ALL PRIVILEGES ON *.* TO ‘oldgirl‘@‘172.16.1.0/255.255.255.0‘ IDENTIFIED BY PASSWORD ‘*2CADADD54086D5EB4C9F10E0430084D7F179885C‘

1 row in set (0.00 sec)

8.2.8 回收权限

mysql> revoke insert on *.* from oldboy@‘localhost‘;

Query OK, 0 rows affected (0.00 sec)

mysql> show grants for oldboy@‘localhost‘\G

*************************** 1. row ***************************

Grants for oldboy@localhost: GRANT SELECT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO ‘oldboy‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘

*************************** 2. row ***************************

Grants for oldboy@localhost: GRANT ALL PRIVILEGES ON `oldboy`.* TO ‘oldboy‘@‘localhost‘

2 rows in set (0.00 sec)

 

8.2.9 博客、CMS、bbs等产品的数据库授权:

对于Web连接数据库的用户授权尽量采用最小化原则,但是很多开源软件都是Web界面安装,因此,在安装期间除了select,insert,update,delete4个权限外,有可能还需要create,drop等比较危险的权限,因此需要建库、建表,因此授权例子如下。

mysql> grant select,insert,update,delete,create,drop on blog.* to blog@‘172.16.1.%‘ identified by ‘123456‘;

Query OK, 0 rows affected (0.00 sec)

生成数据库、表后,可以使用revoke命令收回create、drop授权:

mysql> revoke create,drop on blog.* from blog@‘172.16.1.%‘;

Query OK, 0 rows affected (0.00 sec)

 

mysql> show grants for blog@‘172.16.1.%‘;

+--------------------------------------------------------------------------------------------------------------+

| Grants for blog@172.16.1.%                                                                                   |

+--------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO ‘blog‘@‘172.16.1.%‘ IDENTIFIED BY PASSWORD ‘*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9‘ |

| GRANT SELECT, INSERT, UPDATE, DELETE ON `blog`.* TO ‘blog‘@‘172.16.1.%‘                                      |

+--------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

8.2.10 生产场景具体授权命令为:

a.主库授权的命令:

grant select,insert,update,delete on blog.* to ‘blog‘@‘172.16.1.%‘ identified by ‘123456‘;

b.从库授权用户的命令:

grant select on blog.* to ‘blog‘@‘172.16.1.%‘ identified by ‘123456‘;

当然从库除了做select的授权外,还可以加read-only等只读参数,严格控制web用户写从库。

 

8.2.11 授权不规范导致的生产血案

运维人员授权用户all权限了,导致开发通过该用户自行改了表结构(字段),最后造成服务处问题,最后黑锅甩在了运维人员身上。

运维人员排查了半天没结果,最后对比表结构(把生产数据和备份的数据比对),发现了问题,最后告诉开发,把字段改回去,服务就好了。

启发:生产场景尽量不要给开发select以为的权限,用于网站的连接账号不要授权select,insert,delete,update以外的权限,对别人的“仁慈”,就是对自己的岗位和公司最大的背叛。

8.3 DML语句之管理表中的数据

8.3.1 往表中插入数据语法

drop table test;

CREATE TABLE test (

   id int(4) NOT NULL AUTO_INCREMENT,

  name char(20) NOT NULL,

  PRIMARY KEY (id)

) ;

(1)命令语法:

insert into <表名> [(字段名1[,..<字段名n>])] values(值1)[,(值n)]

(2)新建一个简单的测试表test,语句如下:

mysql> use oldboy

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> CREATE TABLE test (

    ->    id int(4) NOT NULL AUTO_INCREMENT,

    ->   name char(20) NOT NULL,

    ->   PRIMARY KEY (id)

    -> ) ;

Query OK, 0 rows affected (0.32 sec)

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

 

8.3.2 往表中插入数据的不同的语法例子:

8.3.2.1  按规矩指定所有列名,并且每列都插入值

mysql> insert into test(id,name) values(1,‘oldboy‘);

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | oldboy |

+----+--------+

1 row in set (0.00 sec)

8.3.2.2  由于id列为自增的,所以,可以只在name列插入值

mysql> insert into test(name) values(‘oldgirl‘);

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

+----+---------+

2 rows in set (0.00 sec)

 

在建表的时候就确认了

#查看表结构

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

8.3.2.3  如果不指定列,就要按规矩为每列都插入恰当的值。

mysql> insert into test values(3,‘oldboy‘);

Query OK, 1 row affected (0.05 sec)

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | linjie |

|  2 | oldboy |

|  3 | oldboy |

+----+--------+

3 rows in set (0.00 sec)

8.3.2.4  批量插入数据的方法:

mysql> insert into test values(4,‘linjie‘),(5,‘lanyezi‘);

Query OK, 2 rows affected (0.00 sec)

Records: 2  Duplicates: 0  Warnings: 0

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | linjie  |

|  2 | oldboy  |

|  3 | oldboy  |

|  4 | linjie  |

|  5 | lanyezi |

+----+---------+

5 rows in set (0.00 sec)

8.3.2.5  插入全部数据

mysql> delete from test;

Query OK, 5 rows affected (0.07 sec)

 

mysql> select * from test;

Empty set (0.00 sec)

 

mysql> insert into test values(1,‘oldboy‘),(2,‘oldgirl‘),(3,‘inca‘),(4,‘zuma‘),(5,‘kaka‘);

Query OK, 5 rows affected (0.01 sec)

Records: 5  Duplicates: 0  Warnings: 0

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

5 rows in set (0.00 sec)

8.3.2.6  测试完毕,退出数据库,然后备份上述数据,留着备用。

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B oldboy >/opt/oldboy.sql

Warning: Using a password on the command line interface can be insecure.

[root@db02 ~]# ll /opt/oldboy.sql

-rw-r--r--. 1 root root 2051 2017-06-21 14:58 /opt/oldboy.sql

[root@db02 ~]# egrep -v ‘#|\/|^$|--‘ /opt/oldboy.sql

USE `oldboy`;

DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

LOCK TABLES `test` WRITE;

INSERT INTO `test` VALUES (1,‘oldboy‘),(2,‘oldgirl‘),(3,‘inca‘),(4,‘zuma‘),(5,‘kaka‘);

UNLOCK TABLES;

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> alter table student change id id int primary key auto_increment;  添加主键

 

 

 

 

 

 

 

 

 

 

 

unique 唯一的 独一无二的。

8.3.3 修改表中的数据

8.3.3.1  修改表中的数据

update test set id=6 where name=‘kaka‘;

mysql> update test set name=‘bingbing‘ where id=3;

Query OK, 1 row affected (0.12 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

mysql> select * from test;

+----+----------+

| id | name     |

+----+----------+

|  1 | linjie   |

|  2 | oldboy   |

|  3 | bingbing |

|  4 | linjie   |

|  5 | lanyezi  |

+----+----------+

5 rows in set (0.00 sec)

8.3.3.2  不指定条件误操作

mysql> update test set name=‘linjie‘;

Query OK, 5 rows affected (0.15 sec)

Rows matched: 5  Changed: 5  Warnings: 0

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | linjie |

|  2 | linjie |

|  3 | linjie |

|  4 | linjie |

|  6 | linjie |

+----+--------+

5 rows in set (0.01 sec)

-U禁止update操作

防止不加条件误删

[root@db02 ~]# mysql -U

mysql> update test set name=‘xiaoting‘;

ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

mysql>

至于防止误操作导致上述数据库故障案例的方法之一,请读者到老男孩的博客http://oldboy.blog.51cto.com/2561410/1321061索引列的创建及生效条件

8.3.4 查询表中的数据

8.3.4.1  命令语法:

select<字段1,字段2,...> from <表名> where <表达式>

其中,select、from、where是不能随便改的,是关键字,支持大小写。

 

mysql> select user,host from mysql.user;

+------+-----------+

| user | host      |

+------+-----------+

| root | 127.0.0.1 |

| root | ::1       |

|      | db02      |

| root | db02      |

|      | localhost |

| root | localhost |

+------+-----------+

6 rows in set (0.00 sec)

8.3.4.2  查看表test中所有数据

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

5 rows in set (0.00 sec)

8.3.4.3  倒叙查询

mysql> select * from test where id>1 order by id desc;

+----+---------+

| id | name    |

+----+---------+

|  5 | kaka    |

|  4 | zuma    |

|  3 | inca    |

|  2 | oldgirl |

+----+---------+

4 rows in set (0.12 sec)

8.3.4.4  升序查询

mysql> select * from test where id>1 order by id asc;

+----+---------+

| id | name    |

+----+---------+

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

4 rows in set (0.00 sec)

8.3.5 删除表中的数据

8.3.5.1  命令语法:

delete from 表名 where 表达式

8.3.5.2  删除表test中编号为1 的记录。

mysql> delete from test where id=1;

Query OK, 1 row affected (0.00 sec)

 

mysql> delete from test where name=‘oldboy‘;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

4 rows in set (0.00 sec)

8.3.5.3  通过update伪删除数据(企业案例)

mysql> alter table test add state tinyint(2) not null default 1;

Query OK, 0 rows affected (0.46 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+------------+------+-----+---------+----------------+

| Field | Type       | Null | Key | Default | Extra          |

+-------+------------+------+-----+---------+----------------+

| id    | int(4)     | NO   | PRI | NULL    | auto_increment |

| name  | char(20)   | NO   |     | NULL    |                |

| state | tinyint(2) | NO   |     | 1       |                |

+-------+------------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

程序显示内容时,使用下面的语句。

mysql> select * from test where state=1;

+----+---------+-------+

| id | name    | state |

+----+---------+-------+

|  2 | oldgirl |     1 |

|  3 | inca    |     1 |

|  4 | zuma    |     1 |

|  5 | kaka    |     1 |

|  6 | linjie  |     1 |

+----+---------+-------+

5 rows in set (0.29 sec)

此时,如果要删除数据,就可以用update替代delete实现逻辑删除,现在阐述oldgirl所在的行。

mysql> update test set state=0 where name=‘oldgirl‘;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

mysql> select * from test where state=1;

+----+------+-------+

| id | name | state |

+----+------+-------+

|  3 | inca |     1 |

|  4 | zuma |     1 |

|  5 | kaka |     1 |

+----+------+-------+

3 rows in set (0.00 sec)

提示:

网页正常显示的数据SQL语句为:select * from test where state=1;

删除上述oldgirl的记录的语句为:update test set state=0 where name=‘oldgirl‘;

因此实际上数据并未真的删除,而是显示状态变为0了。

8.3.6 清空表中的数据

1、  命令语法:truncate table 表名;

2、  删除实践、

mysql> select * from test where state=1;

+----+--------+-------+

| id | name   | state |

+----+--------+-------+

|  3 | inca   |     1 |

|  4 | zuma   |     1 |

|  5 | kaka   |     1 |

|  6 | linjie |     1 |

+----+--------+-------+

4 rows in set (0.00 sec)

 

mysql> truncate table test;

Query OK, 0 rows affected (0.33 sec)

 

mysql> select * from test where state=1;

Empty set (0.00 sec)

3、truncate和delete区别

truncate table test;速度更快。直接清空对应数据的物理文件。

delete from test;速度慢,逻辑清除,按行删。

8.3.7 相关名词注释

权限

说明

SELECT

查询(数据)

INSERT

插入(数据)

UPDATE

修改(数据)

DELETE

删除(数据)

CREATE

创建(数据库、表等对象)

DROP

删除(数据库、表等对象)

RELOAD

重载

SHUTDOWN

关闭

PROCESS

进程

FILE

文件

REFERENCES

参考资料

INDEX

索引

ALTER

修改(数据库、表等对象)

SHOW DATABASES

查看数据库

SUPER

超级权限

CREATE TEMPORARY TABLES

创建临时表

LOCK TABLES

锁表

EXECUTE

执行

REPLICATION SLAVE

从复制权限

REPLICATION CLIENT

从客户端复制

CREATE VIEW

创建视图

SHOW VIEW

查看视图

CREATE ROUTINE

创建存储过程

ALTER ROUTINE

修改存储过程

CREATE USER

创建用户

EVENT

事件

TRIGGER

触发器

CREATE TABLESPACE

创建表空间

 

 

 

 

 

 

 

 

第9章 表操作

    MySQL数据库中的表和Word,Excel里的表格是一模一样的。

 

 

9.1 建表的基本语法

(1)语法

create table <表名>(

<字段名1><类型1>,

...

create table<表名>(

<字段名n><类型n>;

提示:其中create table是关键字,不能更改,但是大小写可以变化。

(2)建表语句:

create table student(

id int(4) not null,

name char(20) not null,

age tinyint(2)  NOT NULL default ‘0‘,

dept varchar(16)  default NULL

);

上述语句表示创建一个student表,有4个字段:

create table student(                 #CREATE TABLE是创建表的固定关键字,student为表名

id int(4) not null,                   #学号列,数字类型,长度为4,不为空值

name char(20) not null,               #名字列,定长字符类型,长度20,不为空值

age tinyint(2)  NOT NULL default ‘0‘, #年龄列,很小的数字类型,长度为2,不为空,默认为0值

dept varchar(16)  default NULL        #系别列,变长字符类型,长度16,默认为空

) ENGINE=InnoDB DEFAULT CHARSET=UTF8; #引擎和字符集,引擎默认为innodb,字符集,继承库的utf8

(3)student表的直观显示,可以用下表表示:字段下面的5行为表的5条记录。

 

9.1.1 字段类型表的对应列的内容的类型

列类型

说明

TINYINT

微小整数类型,可存储的容量为1字节

INT

整数类型,可以存储容量为4字节(4294967296)

CHAR(M)

定长字符串类型,当存储时,总是用空格填满右边到指定的长度。最大可存储1<=M字节<=255

VARCHAR(M)

变长字符串类型,最大可存储1<=M字节<=255

DATE

日期类型,支持的范围是1000-01-01到9999-12-31,MySQL以YYYY-MM-DD格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列。

DOUBLE[(M,D)] [ZEROFILL]

正常大小(双精密)浮点数字类型

BLOB TEXT

最大长度为65535(2^16-1)个字符。

 

9.1.2 CHAR和VARCHAR之间的差别:

CHAR(4)

存储需求

VARCHAR(4)

存储需求

‘‘

‘       ‘

4个字节

‘‘

1个字节

‘ab‘

‘ab    ‘

4个字节

‘ab‘

3个字节

‘abcd‘

‘abcd‘

4个字节

‘abcd‘

5个字节

‘avcdefgh‘

‘abcd‘

4个字节

‘abcd‘

5个字节

例如,VARCHAR(10)列可以容纳最大长度为10的字符串。实际存储需求是字符串(L)的长度,加上一个记录字符串长度的字节。对应字符串‘abcd‘,L是4,存储需要5个字节。

 

CHAR和VARCHAR差别小结:

1、char类型是定长,不够的在右边用空格补全,浪费存储空间,以此列为查询条件时,速度更快,多数系统表的字段都是定长。

2、varchar类型是变长,省存储空间,以此列为查询条件时速度会慢。

 

9.2 创建一个表

use oldboy

create table student(               

id int(4) not null,                 

name char(20) not null,             

age tinyint(2)  NOT NULL default ‘0‘,

dept varchar(16)  default NULL      

) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

mysql> desc student;

+-------+-------------+------+-----+---------+-------+

| Field | Type        | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+-------+

| id    | int(4)      | NO   |     | NULL    |       |

| name  | char(20)    | NO   |     | NULL    |       |

| age   | tinyint(2)  | NO   |     | 0       |       |

| dept  | varchar(16) | YES  |     | NULL    |       |

+-------+-------------+------+-----+---------+-------+

4 rows in set (0.00 sec)

 

9.3 更改表名

9.3.1 采用rename命令更改表名

命令语法:rename table 原表名 to 新表名;

把student表名改为test

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

+------------------+

1 row in set (0.00 sec)

 

mysql> rename table student to test;

Query OK, 0 rows affected (0.32 sec)

 

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| test             |

+------------------+

1 row in set (0.00 sec)

9.3.2 通过alter命令改表名

把test表名改回student

mysql> alter table test rename to student;

Query OK, 0 rows affected (0.02 sec)

 

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

+------------------+

1 row in set (0.00 sec)

9.4 增删改表的字段

9.4.1 添加字段

命令语法:alter table 表名 add 字段 类型 其他;

a.测试表数据

#测试环境

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

 

mysql> use kkk

mysql> CREATE TABLE `test` (

    ->   `id` int(4) NOT NULL AUTO_INCREMENT,

    ->   `name` char(20) NOT NULL,

    ->   PRIMARY KEY (`id`)

    -> ) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

Query OK, 0 rows affected (0.30 sec)

 

mysql> show tables;

+---------------+

| Tables_in_kkk |

+---------------+

| test          |

+---------------+

1 row in set (0.00 sec)

###查看表结构

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

 

b.实践案例

在表test中添加字段sex,age,qq类型分别为char(4),int(4),varchar(15)。

 

mysql> alter table test add sex char(4);

Query OK, 0 rows affected (0.35 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

 

mysql> alter table test add age int(4) after name;

Query OK, 0 rows affected (0.03 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| age   | int(4)   | YES  |     | NULL    |                |

 

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> alter table test add qq varchar(15) first;

Query OK, 0 rows affected (0.03 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| qq    | varchar(15) | YES  |     | NULL    |                |

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | int(4)      | YES  |     | NULL    |                |

| sex   | char(4)     | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

5 rows in set (0.00 sec)

 

9.4.2 删除字段

mysql> alter table test drop qq;

Query OK, 0 rows affected (0.72 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| age   | int(4)   | YES  |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> alter table test drop age;

Query OK, 0 rows affected (0.07 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

9.4.3 修改字段名称

mysql> alter table test add age int(4) after name;

Query OK, 0 rows affected (0.10 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> alter table test change age oldboyage char(4) after name;

Query OK, 0 rows affected (0.10 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-----------+----------+------+-----+---------+----------------+

| Field     | Type     | Null | Key | Default | Extra          |

+-----------+----------+------+-----+---------+----------------+

| id        | int(4)   | NO   | PRI | NULL    | auto_increment |

| name      | char(20) | NO   |     | NULL    |                |

| oldboyage | char(4)  | YES  |     | NULL    |                |

| sex       | char(4)  | YES  |     | NULL    |                |

+-----------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

9.4.4 企业里更改表的流程:开发人员写出SQL语句,发给运维或DBA检验并执行!

提示:工作中添加字段需求来自开发,运维或DBA拿着开发给的语句执行。

对数据库表的修改,尽量在代码上线的时候或者业务的低谷,不要再流量高峰期处理大表的更改。

     下班的时候尽量不要单人独自生产线上改东西。

9.5 面试题授权:##MySQL数据库授权oldboy用户管理bbs库的所有表,172.16.1.0整个网段访问,密码是123456,请给出详细#命令(不低于2种方法:)

mysql> create database bbs;

Query OK, 1 row affected (0.00 sec)

 

mysql> grant all on bbs.* to oldboy@‘172.16.1.0/255.255.255.0‘ identified by ‘123456‘;

Query OK, 0 rows affected (0.00 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

9.6 mysql表的字段类型

 

以索引列为查询条件时可以加快查询数据的速度

9.7 为表的字段创建索引

数据库的索引就像书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询数据的速度,这是MySQL优化的重要内容之一。

9.7.1 创建主键索引

查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有很多个普通索引列。主键列要求列的所有内容必须唯一,而普通索引列不要求内容必须唯一。

主键就类似我们在学校学习时的学号一样,班级内是唯一的,整个表的每一条记录的主键值在表内都是唯一的,用来唯一标识一条记录。那么,我们该如何建立主键索引和普通索引呢?

首先,无论建立主键索引还是普通索引,都要在表的对应列上创建,可以对单列创建索引,也可以对多列创建索引!

建立主键索引的方法:

1、在建表时,可以增加建立主键索引的语句如下

drop table student;

create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

age tinyint(2)  NOT NULL default ‘0‘,

dept varchar(16)  default NULL,

primary key(id),

KEY index_name(name)

);

提示:

1、primary key(id)   ←主键

2、KEY index_name(name) ←name字段普通索引

优化:在唯一值多的列上建索引查询效率高。

mysql> show create table student\G   #查看建表语句

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT ‘0‘,

  `dept` varchar(16) DEFAULT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

 

2、建表后通过alter命令增加主键索引(不要这样干)

mysql> alter table student drop primary key;

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

##如果建表时没有增加AUTO_INCREMENT,就可以删掉(id自增的不能删除)。

 

去掉AUTO_INCREMENT,再创建一张表

mysql> drop table student;

Query OK, 0 rows affected (0.01 sec)

 

mysql> create table student(

    -> id int(4) not null,

    -> name char(20) not null,

    -> age tinyint(2)  NOT NULL default ‘0‘,

    -> dept varchar(16)  default NULL,

    -> primary key(id),

    -> KEY index_name(name)

    -> );

Query OK, 0 rows affected (0.09 sec)

 

mysql> alter table student drop primary key;

Query OK, 0 rows affected (0.07 sec)

Records: 0  Duplicates: 0  Warnings: 0

#利用alter命令修改id列主键自增

mysql> alter table student change id id int primary key auto_increment;

Query OK, 0 rows affected (0.09 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(11)     | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

提示:只有int类型且为primary key 才可以使用auto_increment。

 

9.7.2 创建普通索引

1、在建表时,可以增加建立普通索引的语句如下

drop table student;

create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

age tinyint(2)  NOT NULL default ‘0‘,

dept varchar(16)  default NULL,

primary key(id),

KEY index_name(name)

);

###查看有没有索引

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

####查看索引

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

2 rows in set (0.00 sec)

 

2、建表后利用alter增加普通索引

删除建表时创建的index_name索引

mysql> alter table student drop index index_name;

Query OK, 0 rows affected (0.30 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

1 row in set (0.00 sec)

 

在name列上添加索引,索引名为index_name,

mysql> alter table student add index index_name(name);

Query OK, 0 rows affected (0.06 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

2 rows in set (0.00 sec)

提示:PRI为主键的标识,MUL为普通索引的标识。

 

生产场景:数据量很大的时候,不适合建立索引,会影响用户访问。曾经400-500万条记录的表,建立索引,花了90-180秒。

尽量选择在业务低谷时建立索引。

 

9.7.3 对字段的前n个字符创建普通索引

当遇到表中比较大的列时,列内容的前n个字符在所有内容中已经接近唯一时,这时可以对列的前n个字符建立索引,而无需对整个列建立索引,这样可以节省创建索引占用的系统空间,以及降低读取和更新维护索引消耗的系统资源。

对字段的前n个字符创建普通索引的语法:

create index index_name on test(name(8));←条件列前n个字符创建索引

操作实际:

在dept系别列上,前8个字符创建索引

mysql> create index index_dept on student(dept(8));

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_dept

 Seq_in_index: 1

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: 8

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

###alter table student add index index_dept((dept(8)));与上面语句等价

 

9.7.4 为表的多个字段创建联合索引

如果查询数据的条件是多列时,我们可以为多个查询的列创建联合索引,什么,可以为多列的前n个字符列创建联合索引,实践演示如下:

##删除之前创建的索引

mysql> alter table student drop index index_name;

Query OK, 0 rows affected (0.06 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> alter table student drop index index_dept;

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

mysql> create index index_name_dept on student(name,dept);

Query OK, 0 rows affected (0.37 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 2

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

 

###对多列前n个字符创建联合索引

mysql> alter table student drop index index_name_dept;

Query OK, 0 rows affected (0.08 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> create index index_name_dept on student(name(8),dept(10));

Query OK, 0 rows affected (0.32 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: 8

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 2

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: 10

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

生产案例:

建表语句加入联合索引:某sns产品生产正式建表语句

use sns;

set names gbk;

CREATE TABLE `subject_comment_manager` (

  `subject_comment_manager_id` bigint(12) NOT NULL auto_increment COMMENT ‘主键‘,

  `subject_type` tinyint(2) NOT NULL COMMENT ‘素材类型‘,

  `subject_primary_key` varchar(255) NOT NULL COMMENT ‘素材的主键‘,

  `subject_title` varchar(255) NOT NULL COMMENT ‘素材的名称‘,

  `edit_user_nick` varchar(64) default NULL COMMENT ‘修改人‘,

  `edit_user_time` timestamp NULL default NULL COMMENT ‘修改时间‘,

  `edit_comment` varchar(255) default NULL COMMENT ‘修改的理由‘,

  `state` tinyint(1) NOT NULL default ‘1‘ COMMENT ‘0代表关闭,1代表正常‘,

  PRIMARY KEY  (`subject_comment_manager_id`),

  KEY `IDX_PRIMARYKEY` (`subject_primary_key`(32)),

  KEY `IDX_SUBJECT_TITLE` (`subject_title`(32))

  KEY `index_nick_type` (`edit_user_nick`(32),`subject_type`)#<==联合索引,此行为新加的,用于给大家讲解的。实际表语句内没有此行。

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

提示:尽量在唯一值多的大表建立索引。

按条件查询数据时,联合索引是有前缀生效特性的。

index(a,b,c)仅a,ab,abc三个查询条件可以走索引。b,ba,ac,c等无法使用索引了,尽量把最常用作为查询条件的列,放在第一的位置。

也可以创建多列联合主键

PRIMARY KEY (`Host`,`User`)

 

9.7.5 创建唯一索引(非主键)

mysql> create unique index uni_ind_name on student(name);

Query OK, 0 rows affected (0.34 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | UNI | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

9.7.6 索引列的创建及生效条件

问题1:既然索引可以加快查询速度,那么就给所有的列建索引吧?

解答:因为索引不但占用系统空间,而且更新数据时还需要维护索引数据的,因此,索引是一把双刃剑,并不是越多越好,例如:数十到几百行的小表上无需建立索引,插入更新频繁,读取比较少的表要少建立索引。

问题2、要在哪些列上创建索引才能加快查询速度呢?

解答:select user,host from mysql.user where password=...,索引一定要创建在where 后的条件列上,而不是select后的选择数据的列上。另外,我们要尽量选择在唯一值的大表上的列建立索引,例如,男女性别列唯一值少,不适合建立索引。

查看表的唯一值数量:

select count(distinct user) from mysql.user;

select count(distinct user,host) from mysql.user;

 

9.7.7 创建索引命令集合小结

1、创建索引相关命令集合

创建主键索引

mysql> alter table student change id id int primary key auto_increment;

删除主键索引(主键列不能自增,否则删不掉):

mysql> alter table student drop primary key;

创建普通索引

mysql> alter table student add index index_dept(dept);

根据列的前n个字符创建索引

mysql> create index index_dept on student(dept(8));

根据多个列创建联合索引

mysql> create index index_name_dept on student(name,dept);

根据多个列的前n个字符创建联合索引

mysql> create index index_name_dept on student(name(8),dept(10));

创建唯一索引

mysql> create unique index uni_ind_name on student(name);

删除普通索引与唯一索引

mysql> alter table student drop index index_dept;

mysql> drop index index_dept on student;

查看唯一值的数量

mysql> select count(distinct user) from mysql.user;

9.7.8 创建索引的基本知识小结:

1、索引类似书籍的目录,会加快查询数据的速度。

2、要在表的列(字段)上创建索引。

3、索引会加快查询速度,但是也会会影响更新的速度,因为更新要维护索引数据。

4、索引列并不是越多越好,要在频繁查询的表语句where后的条件列上创建索引。

5、小表或重复值很多的列上可以不建索引,要在大表以及重复值少的条件列上创建索引。

6、多个列联合索引有前缀生效特性。

7、当字段内容前N个字符己经接近唯一时,可以对字段的前N个字符创建索引。

8、索引从工作方式区分,有主键,唯一,普通索引。

9、索引类型会有BTREE (默认)和hash适合做缓存(内存数据库)等。

http://blog.csdn.net/dyllove98/article/details/9631303

10、索引一般创建用于where关键字后面的列上,group by,order by,join in.

select user,host from mysql.user where id=110;

 

9.8 SQL语句优化

 

 

 

CPU,I/O是不是高,高的话基本就是SQL语句的问题

 

 

 

 

等号容易走索引。

范围查询不爱走索引。

 

MySQL

标签:通过   对比   any   sql   linux   str   column   2.7   ogg   

原文地址:http://www.cnblogs.com/dollinger/p/7071897.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!