MySQL之三---MySQL数据库的二进制安装、源码编译和基础入门操作
一、MySQL安装
(1)安装方式:
1 、程序包yum安装
优点:安装快,简单
缺点:定死了各个文件的地方,需要修改里边的相关配置文件,很麻烦
2 、二进制格式的程序包:展开至特定路径,并经过简单配置后即可使用(推荐)
3 、源代码:编译安装,太麻烦
(2)mysql 的程序组成:
Client:
mysql :CLI 交互式客户端程序 mysqldump, mysqladmin...
Server:
mysqld_safe mysql的备份 mysqld mysqld_multi :多实例
服务器监听的两种socket 地址:
ip socket: 监听在tcp 的3306 端口,支持远程通信 unix sock: 监听在sock 文件上(/tmp/mysql.sock,/var/lib/mysql/mysql.sock) ,仅支持本机通信
实验一:yum源安装MySQL和开启设置服务
1、打开官方网站,上边有各种版本的yum源,找到自己想要的版本设置yum源
https://downloads.mariadb.org/mariadb/repositories/
若上不了网,也可以使用自己光盘里的老版本
2、若不用自己的光盘老版本,要配置yum源,这里我选了10.2的版本
vim /etc/yum.repos.d/mariadb.repo
[mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.2/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
yum源安装mariadb: yum install MariaDB-server
若有其他yum源,加一个enabled=0 先临时关闭,yum clean all 清除缓存,注意:官方给的yum源安装的Maria没有安装相依赖的包,还需自己安装相依赖的包
3、yum安装和开启服务
这里,就直接安装光盘里的老版本了
yum -y install mariadb-server
systemctl start mariadb 开启服务
ss -nutl 打开了3306的tcp端口
查询端口对应的进程信息 lsof -i :3306 或 netstat -tnlp | grep 3306
注意:开启服务后,会多一个mysql的用户,它的家目录:存放数据库,相当于数据库中的每个表
mysql用户是安装包时,执行了个脚本,创建了mysql用户,提示我们要是二进制安装需创建用户
rpm -q --scripts mariadb-server 可以查看这个脚本
4、mysql 运行
发现是root,能查能删,很不安全
还能mysql xxx 匿名登录
5、运行安全脚本
/usr/bin/mysql_secure_installation
实验二:二进制安装mariadb和开启设置服务
注意:安装之前要确保自己系统上没有mariadb服务,有老版本可以先卸掉,删除mysql用户
(1)去官网下载自己想要的版本 http://mariadb.org
rpm -qi mariadb 可以查询官网
上传,解包解压缩
rz,tar xvf mariadb-10.2.8-linux-x86_64.tar.gz -C /usr/local/
[root@centos77 local]# tar xvf mariadb-10.2.8-linux-x86_64.tar.gz -C /usr/local/
(不像编译安装一样,解包可以放在任何目录,这个二进制安装必须指定在这个目录)
(2)cd /usr/local/ 发现mariadb的目录名字不符合要求
ln -s mariadb-10.2.8-linux-x86_64 /usr/local/mysql 创建软链接
[root@centos77 local]# ln -s mariadb-10.2.29-linux-x86_64/ /usr/local/mysql 创建软链接
(3)修改当前的数据库文件所属组和所有者:
[root@centos77 local]# chown -R root.root /usr/local/mysql
(4)创建mysql用户:
[root@centos77 local]# useradd -r -s /sbin/nologin -d /data/mysql mysql 自己指定创建数据库文件,加上-r是系统创建,不加-r,就会在家目录自行创建隐藏目录,在数据库内查询show databases; 就会有其他乱码的数据库名称
(5)执行脚本,创建数据库文件:
mkdir /data/mysql 创建一个数据库目录 cd /usr/local/mysql 一定要在这个目录下执行脚本,不能进入scripts目录下,不然无法找到脚本路径 scripts/mysql_install_db --user=mysql(以mysql身份运行) --datadir=/data/mysql (指定数据库路径)
[root@centos77 mysql]# scripts/mysql_install_db --user=mysql --datadir=/data/mysql 指定当前的数据库路径
(6)修改mysql配置文件
[root@centos77 mysql]#mkdir /etc/mysql 新建mysql配置文件路径 [root@centos77 local]# cd /usr/local/mysql [root@centos77 mysql]# ls bin data INSTALL-BINARY mariadb-10.2.29-linux-x86_64 README-wsrep sql-bench COPYING EXCEPTIONS-CLIENT lib mysql-test scripts support-files CREDITS include man README.md share THIRDPARTY [root@centos77 mysql]# ls support-files/ binary-configure my-innodb-heavy-4G.cnf my-small.cnf(小配置文件) mysql.server wsrep_notify magic my-large.cnf mysqld_multi.server policy my-huge.cnf(大配置文件) my-medium.cnf(中等配置文件) mysql-log-rotate wsrep.cnf [root@centos77 mysql]#cp /usr/local/mysql/support-files/my-huge.cnf /etc/mysql/my.cnf 将本地存在的mysql配置文件复制到自己创建的目录下,并起名为my.cnf [root@centos77 mysql]#vim /etc/mysql/my.cnf 配置文件内容 [client] #password = your_password socket = /tmp/mysql.sock [mysqld] datadir=/data/mysql 修改数据库路径 port = 3306 socket = /tmp/mysql.sock
(7)复制centos自带的服务脚本,并将此服务脚本加入到运行服务列表内,启动该服务:
[root@centos77 mysql]# cp support-files/mysql.server /etc/init.d/将本地的mysql服务复制到配置文件中 [root@centos77 mysql]# cd /etc/init.d [root@centos77 init.d]# ls functions mysql.server netconsole network README [root@centos77 init.d]# mv mysql.server mysqld 将mysql.server 改名为mysqld [root@centos77 init.d]# chkconfig --list 查看mysqld 服务脚本是否在服务列表中 Note: This output shows SysV services only and does not include native systemd services. SysV configuration data might be overridden by native systemd configuration. If you want to list systemd services use 'systemctl list-unit-files'. To see services enabled on particular target use 'systemctl list-dependencies [target]'. netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off network 0:off 1:off 2:on 3:on 4:on 5:on 6:off [root@centos77 init.d]# chkconfig --add mysqld 添加mysqld 服务 [root@centos77 init.d]# chkconfig --list Note: This output shows SysV services only and does not include native systemd services. SysV configuration data might be overridden by native systemd configuration. If you want to list systemd services use 'systemctl list-unit-files'. To see services enabled on particular target use 'systemctl list-dependencies [target]'. mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
(8)启动mysql服务,并制定PATH变量路径:
[root@ansibleinit.d]#service mysqld start [root@ansibleinit.d]#echo 'PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh [root@ansibleinit.d]#. /etc/profile.d/mysql.sh 生效PATH变量路径
(9)查看当前的数据库目录:
[root@ansibleinit.d]#mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 13 Server version: 10.2.29-MariaDB-log MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show variables like 'datadir'; 查询当前的数据库目录 +---------------+--------------+ | Variable_name | Value | +---------------+--------------+ | datadir | /data/mysql/ | +---------------+--------------+ 1 row in set (0.01 sec) MariaDB [(none)]> select @@datadir; 查询当前的数据库目录 +--------------+ | @@datadir | +--------------+ | /data/mysql/ | +--------------+ 1 row in set (0.00 sec)
(8)对数据库进行安全初始化
[root@ansibleinit.d]#cd /usr/local/mysql/bin/ 切换到当前目录可以看到安全初始化脚本 [root@ansiblebin]#mysql_secure_installation 进行mysql数据库密码设置
实验三:源码编译安装mariadb
(1)安装依赖包
yum install bison bison-devel zlib-devel libcurl-devel libarchive-devel boost- devel gcc gcc-c++ cmake ncurses-devel gnutls-devel libxml2-devel openssl- devel libevent-devel libaio-devel
(2)创建账号
[root@centos77 ~]# useradd -r -s /sbin/nologin -d /data/mysql/ mysql
(3)创建mysql目录
[root@centos77 ~]# mkdir /data/mysql [root@centos77 ~]# chown mysql.mysql /data/mysql
(4)将网上下载的源码包传到linux系统上
mariadb源码包下载地址:https://mariadb.com/kb/en/mariadb-server-10-2-29/
rz mariadb-10.2.29.tar.gz 将源码传到电脑上 [root@centos77 ~]# tar xvf mariadb-10.2.29.tar.gz 解压源码 [root@centos77 ~]# cd mariadb-10.2.29 切换到此目录下 cmake . \ -DCMAKE_INSTALL_PREFIX=/app/mysql \ 指定程序路径 -DMYSQL_DATADIR=/data/mysql/ \ 数据库存放路径 -DSYSCONFDIR=/etc/mysql \ 配置文件路径 -DMYSQL_USER=mysql \ mysql账号 -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_ARCHIVE_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITH_PARTITION_STORAGE_ENGINE=1 \ -DWITHOUT_MROONGA_STORAGE_ENGINE=1 \ -DWITH_DEBUG=0 \ -DWITH_READLINE=1 \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DWITH_LIBWRAP=0 \ -DENABLED_LOCAL_INFILE=1 \ -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock \ socket文件路径 -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci [root@centos77 ~]# make -j 4 && make install 进行多线程编译安装
(5)生成数据库
cd /app/mysql/
[root@centos77 mysql]# scripts/mysql_install_db --user=mysql --datadir=/data/mysql
(6)指定PATH变量路径:
[root@centos77 mysql]# echo 'PATH=/app/mysql/bin:$PATH' > /etc/profile.d/mysql.sh 指定PATH变量路径 [root@centos77 mysql]# . /etc/profile.d/mysql.sh 让PATH变量路径生效
(7)准备配置文件
cd /app/mysql [root@centos77mysql]# cp support-files/my-huge.cnf /etc/mysql/my.cnf
(8)准备启动脚本
cd /app/mysql/ [root@centos77 mysql]# cp support-files/mysql.server /etc/init.d/mysql
(9)添加mysqld,并启动服务
[root@centos77 mysql]# chkconfig --add mysqld ,service mysqld start
(10)安全初始
cd /user/local/mysql/bin/ mysql_secure_installation 设置mysql密码
实验四:基于源码编译多实例
1 规划相关目录
mkdir /mysql/{3306,3307,3308}/{data,etc,socket,log,pid} -pv chown -R mysql.mysql /mysql
2 准备数据库数据文件
/app/mysql/scripts/mysql_install_db --user=mysql --datadir=/mysql/3306/data /app/mysql/scripts/mysql_install_db --user=mysql --datadir=/mysql/3307/data /app/mysql/scripts/mysql_install_db --user=mysql --datadir=/mysql/3308/data
3 准备配置文件
配置3308配置文件:
vim /mysql/3308/etc/my.cnf [mysqld] port=3308 datadir=/mysql/3308/data socket=/mysql/3308/socket/mysql.sock [mysqld_safe] log-error=/mysql/3308/log/mariadb.log pid-file=/mysql/3308/pid/mariadb.pid
配置3307配置文件:
vim /mysql/3307/etc/my.cnf [mysqld] port=3308 datadir=/mysql/3307/data socket=/mysql/3307/socket/mysql.sock [mysqld_safe] log-error=/mysql/3307/log/mariadb.log pid-file=/mysql/3307/pid/mariadb.pid
配置3306配置文件:
vim /mysql/3306/etc/my.cnf [mysqld] port=3308 datadir=/mysql/3306/data socket=/mysql/3306/socket/mysql.sock [mysqld_safe] log-error=/mysql/3306/log/mariadb.log pid-file=/mysql/3306/pid/mariadb.pid
编mysql启动脚本:vim mysqld
#!/bin/bash #chkconfig: 345 80 2 port=3308 #对应不同的监听端口进行修改,如3306,3307 mysql_user="root" mysql_pwd="centos" # 初始账号没有口令可以写成空“” cmd_path="/app/mysql/bin" mysql_basedir="/mysql" mysql_sock="${mysql_basedir}/${port}/socket/mysql.sock" function_start_mysql() { if [ ! -e "$mysql_sock" ];then printf "Starting MySQL...\n" ${cmd_path}/mysqld_safe --defaults-file=${mysql_basedir}/${port}/etc/my.cnf &> /dev/null & else printf "MySQL is running...\n" exit fi } function_stop_mysql() { if [ ! -e "$mysql_sock" ];then printf "MySQL is stopped...\n" exit else printf "Stoping MySQL...\n" ${cmd_path}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S ${mysql_sock} shutdown fi } function_restart_mysql() { printf "Restarting MySQL...\n" function_stop_mysql sleep 2 function_start_mysql } case $1 in start) function_start_mysql ;; stop) function_stop_mysql ;; restart) function_restart_mysql ;; *) printf "Usage: ${mysql_basedir}/${port}/bin/mysqld {start|stop|restart}\n" esac
4 准备启动脚本
chmod +x /mysql/3308/mysqld chmod +x /mysql/3307/mysqld chmod +x /mysql/3306/mysqld
5 启动mysql
以3308为例,进行启动
/mysql/3308/mysqld start mysql -uroot -h127.0.0.1 -P 3308 mysql -uroot -S /mysql/3308/socket/mysql.sock
6 安全加固
/app/mysql/bin/mysql_secure_installation -S /mysql/3308/socket/mysql.sock mysql -uroot -pcentos -h127.0.0.1 -P 3308 mysql -uroot -pcentos -S /mysql/3308/socket/mysql.sock
7 将数据库文件进行配置,添加到开机启动程序
cp /mysql/3308/mysqld /etc/init.d/mysql3308 chkconfig --list chkconfig --add mysqld3308
二、mysql基础入门操作
1、命令行交互式命令:mysql
mysql 命令的选项:
-uUSERNAME: 用户名;默认为root -hHOST: 服务器主机; 默认为localhost -pPASSWORD :用户的密码; 建议使用-p, 默认为空密码
关系型数据库的常见组件
数据库:database 表:table 行:row 列:column 索引:index 视图:view 用户:user 权限:privilege 存储过程:procedure 存储函数:function 触发器:trigger 事件调度器:event scheduler,任务计划
2、SQL语言规范
1、在数据库系统中,SQL语句不区分大小写(建议用大写) 2、SQL语句可单行或多行书写,以“;”结尾 3、关键词不能跨多行或简写 4、用空格和缩进来提高语句的可读性 5、子句通常位于独立行,便于编辑,提高可读性 6、注释: SQL标准: /*注释内容*/ 多行注释 -- 注释内容 单行注释,注意有空格 MySQL注释: #
3、数据库对象
1、数据库的组件(对象):
2、数据库、表、索引、视图、用户、存储过程、函数、触发器、事件调度器等 命名规则: 必须以字母开头 可包括数字和三个特殊字符(# _ $) 不要使用MySQL的保留字 同一database(Schema)下的对象不能同名
4、SQL语句分类
DDL: Data Defination Language 数据定义语言 CREATE,DROP,ALTER DML: Data Manipulation Language 数据操纵语言 INSERT,DELETE,UPDATE DCL:Data Control Language 数据控制语言 GRANT,REVOKE,COMMIT,ROLLBACK DQL:Data Query Language 数据查询语言 SELECT
5、SQL语句构成
1、Keyword组成clause
2、多条clause组成语句
示例:
SELECT * SELECT子句 FROM products FROM子句 WHERE price>400 WHERE子句
说明:一组SQL语句,由三个子句构成,SELECT,FROM和WHERE是关键字
三、数据库操作
1、查看数据库列表:show databases;
1)查看某个数据库中的表:show tables [from database_name] 如果已经在这个库下,不用加from
2)数据库有information_schema 库,这个库是只读库,只有root特殊权限的用户登录才能看到,不能drop删除
3)数据库有#mysql50#.mozilla 类似的库的处理方法,因为mysql家目录下有个隐藏文件导致,不能删除,将/usr/local/mysql/目录下的隐藏文件删除即可。
show create databases test; 可以查看当前数据库使用的是什么字符集:
2、创建数据库:
CREATE DATABASE(数据库) [IF NOT EXISTS](如果不存在,创建)'DB_NAME'; 创建成功一个,会生成一个表数据库文件
CHARACTER SET 'character set name' 设置字符集,不推荐设置,不建议调
COLLATE 'collate name' 设置排序规则,不推荐设置
字符集一般默认的utf8
注意:数据库对象的命名规则
必须以字母开头
可包括数字和三个特殊字符(# _ $)
不要使用MySQL 的保留字
同一Schema(数据库) 下的对象不能同名
以下是创建一个utf8mb4的字符集数据库:
MariaDB [(none)]> help create database;可以查询帮助,可以看出怎么去创建指定的字符集数据库 Name: 'CREATE DATABASE' Description: Syntax: CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [create_specification] ... create_specification: [DEFAULT] CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name CREATE DATABASE creates a database with the given name. To use this statement, you need the CREATE privilege for the database. CREATE SCHEMA is a synonym for CREATE DATABASE. URL: http://dev.mysql.com/doc/refman/5.5/en/create-database.html MariaDB [(none)]> create database utf8mb4 CHARACTER SET=utf8mb4; Query OK, 1 row affected (0.00 sec)
查看当前数据库的字符集:show create database utf8mb4;
3、删除数据库
DROP DATABASE [IF EXISTS] 'DB_NAME'; 删除成功,会删除对应的表数据库文件
查看支持所有字符集:SHOW CHARACTER SET; 不需要改
查看支持所有排序规则:SHOW COLLATION; 不需要改
获取命令使用帮助:mysql>help create database;
例:create database utf8mb4; 创建utf8mn4数据库
drop database utf8mn4; 删除utf8mn4数据库
四、创建表及操作表
表含义:
- 表:二维关系
- 设计表:遵循规范
- 定义:字段,索引
- 字段:字段名,字段数据类型,修饰符
- 约束,索引:应该创建在经常用作查询条件的字段上
1、查看数据库中所有的表:show tables from base_name;
查看表结构:desc tbl_name;
2、创建表:CREATE TABLE
(1) 直接创建
(2)CREATE TABLE [IF NOT EXISTS] 'tbl_name' (col1 type1 修饰符, col2 type2 修饰符, ...)
字段信息:
• col type1 指定类型
• PRIMARY KEY(col1,...) ()复合主键
• INDEX(col1, ...) 索引
• UNIQUE KEY(col1, ...) 唯一键
表选项:
• ENGINE [=] engine_name (引擎设置,默认就好)
SHOW ENGINES; 查看支持的engine 引擎类型
• ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT |COMPACT} 行的格式,默认就好
(3)create table students3 select * [id,name] from students; 也可以创建一个表,完全复制另一个表的结构[或自己选择的结构];复制的表没有约束,如主键
insert into students3 select * from students; 有students3这个表,完全复制另一个表的内容
获取创建表的帮助:mysql> HELP CREATE TABLE;
注意:
Storage Engine是指表类型,也即在表创建时指明其使用的存储引擎,同一库中不同表可以使用不同的存储引擎
同一个库中表建议要使用同一种存储引擎类型
MariaDB [(none)]> create database studentdb;创建一个studentdb数据库 Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> use studentdb; 切换到studentdb数据库内 Database changed
MariaDB [studentdb]> create table student (id int unsigned auto_increment primary key,name varchar(10) not null,sex enum('f','m') default 'm',age tinyint unsigned,mobile char(11),address varchar(50)); 创建表的详细信息
解释:创建studentdb库中名为student表;其中id:数据类型int为正、不为空、设为主键;name:数据类型VARCHAR (10)、不为空;age:数据类型tinyint UNSIGNED) sex:性别,分为f,m,不写,默认为m,mobile:固定的字符型11,address:地址为变长的50字符型。
查看自己创建的student表结果: desc student; 或者用show columns from student;
show columns from student;命令也可以查询当前自己创建的表格结构:
3、操作表
查看所有的引擎:SHOW ENGINES 查看表:SHOW TABLES [FROM db_name] 查看表结构:DESC [db_name.]tb_name SHOW COLUMNS FROM [db_name.]tb_name 删除表:DROP TABLE [IF EXISTS] tb_name 查看表创建命令:SHOW CREATE TABLE tbl_name 查看表状态:SHOW TABLE STATUS LIKE 'tbl_name’ 查看库中所有表状态:SHOW TABLE STATUS FROM db_name
4、数据类型:
1、数据类型: 数据长什么样 数据需要多少空间来存放 2、系统内置数据类型和用户定义数据类型 3、MySql支持多种列类型: 数值类型 日期/时间类型 字符串(字符)类型 https://dev.mysql.com/doc/refman/5.5/en/data-types.html 3、选择正确的数据类型对于获得高性能至关重要,三大原则: 更小的通常更好,尽量使用可正确存储数据的最小数据类型 简单就好,简单数据类型的操作通常需要更少的CPU周期 尽量避免NULL,包含为NULL的列,对MySQL更难优化
整型
- tinyint(m):1个字节 范围(-128~127)
- smallint(m):2个字节 范围(-32768~32767)
- mediumint(m): 3个字节 范围(-8388608~8388607)
- int(m): 4个字节 范围(-2147483648~2147483647)
- bigint(m): 8个字节 范围(+-9.22*10的18次方)
加了unsigned,则最大值翻倍,如:tinyint unsigned的取值范围为(0~255)
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储和计算来说,Int(1)和Int(20)是相同的
- BOOL,BOOLEAN:布尔型,是TINYINT(1)的同义词。zero值被视为假,非zero值视为真
5、修饰符
1、所有类型:
• NULL 数据列可包含NULL值 • NOT NULL 数据列不允许包含NULL值 • DEFAULT 默认值 • PRIMARY KEY 主键 • UNIQUE KEY 唯一键 • CHARACTER SET name 指定一个字符集
2、数值型
• AUTO_INCREMENT 自动递增,适用于整数类型 • UNSIGNED 无符号
五、修改表结构,尽量不要改表结构,很少用
1、查看表结构:DESC [db_name.]tb_name;
2、修改表结构 alter
ALTER TABLE 'tbl_name'
字段:
添加字段:add
ADD col1 data_type [FIRST加到第一段的后边|AFTER col_name某一段的后边]
删除字段:drop
修改字段:change (字段名), modify (字段属性)
索引:
添加索引:add
删除索引: drop
表选项:
修改:change
查看帮助:Help ALTER TABLE
3、例子:
Help ALTER TABLE 查看帮助
注:如果表或者数据库结构字符集出现问题,可用此方法进行解决:
alter database studentdb character set utf8mb4;将数据库的字符集改为utf8mb4
alter table student character set utf8mb4; 将新加的表格字符集改为utf8mb4,老的字符集不能修改
alter table student change name name varcharacter(20) character set utf8mb4; 将老的字符集名称改为新的字符集utf8mb4名称。
ALTER TABLE students3 RENAME s3; 改表名
ALTER TABLE s3 ADD phone varchar(11) AFTER name; 在s3表的name字段后加一个phone
ALTER TABLE s1 MODIFY phone int; 把phone的数据类型改为int
ALTER TABLE s1 CHANGE COLUMN phone mobile char(11); 把字段phone改名为字段mobile,数据类型为char(11)
ALTER TABLE s1 DROP COLUMN mobile; 删除字段mobile
ALTER TABLE students ADD gender ENUM('m','f') 增加gender字段,为枚举类型,只能是m或f
ALETR TABLE students CHANGE id sid int UNSIGNED NOT NULL PRIMARY KEY; 把修改id字段为sid,数据类型为正int、非空、主键
ALTER TABLE students ADD UNIQUE KEY(name); 在name字段加唯一键
ALTER TABLE students ADD INDEX(age); 在age字段加索引
DESC students; 查看这个表
SHOW INDEXES FROM students; 查看索引信息
ALTER TABLE students DROP age;更改表学生年龄
六、DML语句:插入、删除、更新
1、查看
select * from tab_name [WHERE clause [LIMIT [m,]n];] 查看表中的所有内容,Limit m,n 跳过m行,要n行
select id,name,... from tab_name; 查出指定的表中内容
select count(*) from tab_name; 查看表中的记录数量,count()是自带的函数
2、修改表内容:
• INSERT 添加,插入:
INSERT [INTO] tbl_name[(col_name,...)] VALUES(val1,...),(...),...
分析:① tbl_name后不加(),默认按表结构的列;若加(),前后()内容要对应,顺序可以不按表结构,也可以设null值,但最好不要,
② 选项不是数字,都要加'',例:name='along'
insert into tab_name1 select * from tab_name2; 批量导数据,
插入表的格式:
(1)INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
(2)INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
示例:
MariaDB [studentdb]> insert into student (name,age,mobile,address)values('wang',30,10086,'beijing'),
-> ('zhang',28,10010,'zhengzhou');
select * from student; 展开此表格的详细内容:
解释:insert into添加一个表,表名为student,括号内注释:指定名字,年龄,手机号,地址,values对应相应的值。
create table employee(员工的含义) select * from student; 可以复制克隆此表格,克隆后的表格,起名为employee(员工的含义)
此时表格结构和内容都被复制过去:
use studentdb; 切换到studentdb;数据库下
create table custom like student; 复制原有的像的表格结构,但是不能复制表格内容:
批量添加到一个新表中: insert custom select * from student; 含义:将student表格内容复制到custom表格内。注意:两张表格结构要一致才行,不然就会有问题。
status 可以查询数据库的字符集类型,此时客户端字符集和服务器端的字符集不一致:
MariaDB [studentdb]> status -------------- mysql Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1 Connection id: 3 Current database: studentdb Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server: MariaDB Server version: 5.5.60-MariaDB MariaDB Server Protocol version: 10 Connection: Localhost via UNIX socket Insert id: 3 Server characterset: latin1 Db characterset: latin1 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/lib/mysql/mysql.sock Uptime: 2 hours 31 min 34 sec Threads: 1 Questions: 76 Slow queries: 0 Opens: 8 Flush tables: 2 Open tables: 34 Queries per second avg: 0.008
修改当前的服务器端的字符集类型:
vim /etc/my.cnf
character-set-server=utf8mb4
修改客户端的字符集类型:
vim /etc/my.cnf.d/mysql-clients.cnf
default-character-set=utf8mb4
此时,我们再查看当前的数据库字符集类型,已经全部统一为utf8mb4:
查询字符集类型: status;
2、DELETE:删除表内容,下有例子
DELETE FROM tbl_name [WHERE clause] [ORDERBY 'col_name' [DESC]];可先排序再指定删除的行数
分析:若不加where,直接把所有列都删除了
• TRUNCATE TABLE tbl_name; 清空表,快速清空,删除的时候,不计日志,谨慎使用
示例:
delete from student where id >= 3; 删除id号大于等于3的表格:
3、我们来对比一下5.5版本的数据库和10.2的数据库区别:
(1)10.2版本的数据库:当前创建一个db1数据库,我们来看创建的db1数据库中,会有对应的frm和idb后缀的表生成。
(2)10.2版本的功能是打开的,所以会将数据库的表分类存放
show variables like '%per_table';
innodb_file_per_table ON
(3)5.5版本的数据库表:可以看到frm和idb后缀的数据库文件全部在一个文件中存放,不太合理,管理起来比较混乱。
(4)我们可以看到5.5版本的这个功能是关闭的,需要我们将此功能打开,才会分别存放数据。
show variables like '%per_table';
innodb_file_per_table 改为ON
(5)修改5.5版本的配置文件,将此功能打开,不写ON,默认是打开的意思:
vim /etc/my.cnf
innodb_file_per_table
(6)重启mysql 服务
[root@centos7studentdb]#systemctl restart mariadb
(7)我们在studentdb数据库中创建一个新表tt2,然后在数据库中/var/lib/mysql/studentdb/目录下查看当前新建的表是否有两个表存在(idb,frm后缀的文件),
可以看到,此时已经重新有期望的两个后缀(idb,frm)的表生成,设置完毕。
4、UPDATE: 更新,修改表内容,下有例子
UPDATE tbl_name SET col1=val1, col2=val2, ... [WHERE clause] [ORDER BY 'col_name' [DESC]] [LIMIT [m,]n];
分析:若不加where,直接把所有列都修改了,Limit m,n 跳过m行,要n行
注意:一定要有限制条件,否则将修改所有行的指定字段
限制条件:
WHERE
LIMIT
Mysql 选项:-U|--safe-updates| --i-am-a-dummy
避免人间惨案发生:可以将mysql -U 定义为别名,alias mysql='mysql -U',当删除时就会报错,提示你输入where语句,与delete用法一致,都要加where。
也可以将此功能放到配置文件中,也会低概率保证出错问题:
vim /etc/my.cnf.d/mysql-clients.cnf safe-updates
示例:
操作步骤如下:
mysql -uroot -pcentos -u指定用户名, -p指定密码 use studentdb; 切换至studentdb数据库下 select * from student; 查找当前的表中内容 update student set name='haha' id=1; 将表中第一行name的wang修改为haha
七、DQL语句:select (单表查询)
DQL :SELECT,用法很多
SELECT col1,col2,... FROM tbl_name [WHERE clause] [ORDER BY 'col_name' [DESC]] [LIMIT [m,]n]; 查询表内容信息,
1、字段表示法:
*: 所有字段
as :字段别名,若事先做好了表,想要把列的英语改成中文,不用修改,可以直接用别名,
2、排序:order by col_name [desc]
解释:by后指定列,desc反向排序,反向也可以-col_name
注意:若其中有空值,正向排序空值在第一行,反向排序空值在最后一行,可以order by -col_name desc 即正向排序,有把空值放在最后一行
3、WHERE clause:where 后的选项
操作符:下例3
>, <, >=, <=, ==, !=
BETWEEN ... AND ...
DISTINCT : 去重,
LIKE:模糊匹配,
% :任意长度的任意字符
_ :任意单个字符;
RLIKE :正则表达式模式匹配
IS NULL ,IS NOT NULL 寻找空值,不能用=,只能用is,所以最好不要有null,不好管理
IN (val1,val2,…) 离散值显示
条件逻辑操作:
and ,or ,not ,xor
4、GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算
avg(), max(), min(), count(), sum()
5、HAVING: 对分组聚合运算后的结果指定过滤条件
6、ORDER BY: 根据指定的字段对查询结果进行排序
升序:ASC
降序:DESC
7、LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制
8、对查询结果中的数据请求施加“锁”
FOR UPDATE: 写锁,独占或排它锁,只有一个读和写
LOCK IN SHARE MODE: 读锁,共享锁,同时多个读
示例:
(1)*:代表所有字段: select * from student; 在所有字段中显示表格内容。
(2)AS用法:select id as 编号,name 姓名,age 年龄,sex 性别,mobile 手机号,address 地址 from student; 定义好英文的字段,想改为中文,直接用as即可。
(3)where用法: select * from student where age > 20; 筛选年龄大于20以上的表。
(4) select * from student where age >=20 and age <=30; 筛选年龄在20到30之间
select * from student where age between 20 and 30; 筛选年龄在20到30之间。
(5)select * from student where age =10 or age = 30;筛选年龄10和30的行
select * from student where age in (10,30); 推荐使用此方法,简洁,好用
(6) select * from student where mobile is null;帅选手机号为空。 两个比较特殊,用is语句,表格中尽量不要为空。
select * from student where mobile is not null; 筛选手机号不为空。
(7)select * from student where name like %a%; 姓名 包含a的行。
select * from student where name like 'a%'; 显示姓名以a开头的行。
select * from student where name rlike '^a';以a开头的行,支持正则表达式,影响服务器性能,尽量不要用,最好精确匹配
select * from student where name rlike 'a$'; 以a结尾的行。
(8)select distinct sex from student; 将性别去重
(9)select count(*) from student; 统计全部的个数
select sex as 性别,count(*) as 人数 from student group by sex; 按性别统计人数
(10)select sex as 性别,avg(age) as 年龄 from student group by sex; 以性别统计平均年龄
(11)select name,sex,max(age) from student group by name,sex; 按姓名和性别统计年龄的最大值。 分组统计
(12)1、select sex,avg(age) from student group by sex having sex = 'm'; 先按性别筛选年龄,最后再过滤性别
2、select sex,avg(age) from student where sex='m' group by sex; 先过滤性别,再按性别筛选年龄
3、select classid,count(*) from student where age >=30 group by classid having classid >=3; 筛选年纪大于等于30岁人数,班级大于等于3的人数
4、 select classid,count(*) from student where age >= 30 group by classid; 筛选出年龄大于等于30岁以上的班级
(13)select * from student order by age asc; 按年龄从小到大排序
select * from student order by age desc; 按年龄从大到小排序
(14)select * from student order by age asc limit 1; 从小到大排序选第一个
select * from student order by age asc limit 3,4; 从小到大排序,跳过第三个选后面四个。
select * from student order by age asc,mobile desc; 将年龄先进行从小到大排序,再将mobile从大到小排序。
select * from student order by -clessid asc; 小技巧,classid 前面加一个-就会将null排序放到最后。
(15)以ClassID为分组依据,显示每组的平均年龄,再显示平均年龄大于30的分组及平均年龄
select classid,avg(age) from students group by classid having avg(age) > 30;
(16)查询年龄大于等于20岁,小于等于25岁的同学的信息
1、select * from student where age >= 20 and age <=25;
2、select * from student where age between 20 and 25;
小练习:
(1) 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄
第一种写法:select gender,age from students where gender = 'f' group by gender having age > 25; 第二种写法:select gender,age from students where age > 25 group by gender having gender ='f';
(2) 以ClassID为分组依据,显示每组的平均年龄
select classid,avg(age) from students group by classid;
(3) 显示第2题中平均年龄大于30的分组及平均年龄
select classid,avg(age) from students group by classid having avg(age) > 30;
(4) 显示以L开头的名字的同学的信息
select * from students where name like 'l%';
(5) 显示TeacherID非空的同学的相关信息
select * from students where teacherid is not null;
(6) 以年龄排序后,显示年龄最大的前10位同学的信息
select * from students order by age desc limit 10;
(7) 查询年龄大于等于20岁,小于等于25岁的同学的信息
select * from students where age >=20 and age <=25; select * from students where age between 20 and 25;
八、 DQL 语句 :SQL JOINS (SQL连接)
多表查询
(1)交叉连接:笛卡尔乘积 (2)内连接: 等值连接:让表之间的字段以“等值”建立连接关系; 不等值连接 自然连接:去掉重复列的等值连接 自连接 (3)外连接: 左外连接: FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col 右外连接 FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
子查询:在查询语句嵌套着查询语句,性能较差
(1)基于某语句的查询结果再次进行的查询 用在WHERE子句中的子查询 用于比较表达式中的子查询;子查询仅能返回单个值 (2)SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age)FROM students); (3)用于IN中的子查询:子查询应该单键查询并返回一个或多个值从构成列表 SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers); (4)用于EXISTS (5)用于FROM子句中的子查询 使用格式:SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause; 示例: SELECT s.aage,s.ClassID FROM (SELECT avg(Age) AS aage,ClassID FROM students WHERE ClassID IS NOT NULL GROUP BY ClassID) AS s WHERE s.aage>30; (6)联合查询:UNION SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;
(1)将筛选的表头(stuid,name,age,gender)再将一个teacher表合并到一起,teacher字段要和student字段一致,注:要筛选同一类型的表进行合并。
MariaDB [testdb]> select stuid as id,name,age,gender from student
-> union 联合在一起(有去重的功能)
-> select * from teacher;
select * from student union select * from haha;将student和haha两张表纵向合并。
(2)select * from haha union select * from haha; 将haha表中重复的行去除。
select distinct * from haha;等价上面的写法
(3)select * from student cross join haha; 将student 和haha竖向交叉合并,不常用。
内连接:
(4)select * from student,haha where student.id=haha.id;
select * from student inner join haha on student.id=haha.id;推荐使用此方法:将两张表ID相同的行进行合并
(5)select stuid,s.name as student_name,tid,t.name teacher_name from students as s inner join teachers t on s.teacherid=t.tid;筛选出特定的几列进行显示。
右外连接: 右部分全部显示,左部分只显示有内容部分
(6)select * from students as s right outer join teachers t on s.teacherid=t.tid;
右外连接特例:右部分非交集全部显示,左部分只显示空值。
select * from students as s right outer join teachers t on s.teacherid=t.tid where s.teacherid is null;
左外连接: 左部分全部显示,右部分显示有内容的部分
(7)select * from students as s left outer join teachers t on s.teacherid=t.tid;
左外连接特例:左部分非交集部分显示,右部分只显示空值
select * from students as s left outer join teachers t on s.teacherid=t.tid where t.tid is null;
子查询: select avg(age) from student;意思是学生的平均年龄
select * from teachers where age > (select avg(age) from student); 老师大于学生的平均年龄
(8)左右外连接:
1、select * from students full outer join teachers on students.teacherid=teachers.tid; MySQL暂时不支持此功能,其他数据库可能会支持。
2、select * from students as s left outer join teachers t on s.teacherid=t.tid union select * from students as s right outer join teachers t on s.teacherid=t.tid;
(9)左右外连接:将左右表的交集取反,后面慢慢理解。
select * from (select stuid,s.name as student_name,s.age as student_age,s.gender as student_gender ,classid,teacherid,tid,t.name as teacher_name,t.age as teacher_age,t.gender as teacher_gedner
from students as s left outer join teachers t on s.teacherid=t.tid
union
select stuid,s.name,s.age,s.gender,classid,teacherid,tid,t.name,t.age,t.gender
from students as s right outer join teachers t on s.teacherid=t.tid)
as f where f.teacherid is null or f.tid is null;
(10)自连接(自查询):在左边表筛选出右边相同的ID表的内容:
select * from a.name,b.name from emp as a left outer join emp as b on a.leaderid=b.id;
小练习:
三张表:处理交集,筛选三张表中学生姓名,并报了什么科目,得了多少分。
select st.name,co.Course,sc.score from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.CourseID;
1、以ClassID分组,显示每班的同学的人数
select classid,count(*) from students group by classid having classid is not null;
2、以Gender分组,显示其年龄之和
select gender,sum(age) from students group by gender;
3、以ClassID分组,显示其平均年龄大于25的班级
select classid,count(*) from students where classid is not null group by classid having avg(age) > 25;
4、以Gender分组,显示各组中年龄大于25的学员的年龄之和
select classid,sum(age) from students where age > 25 group by classid;
5、显示前5位同学的姓名、课程及成绩
select st.name,co.course,sc.score from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.courseid order by score desc limit 5;
6、显示其成绩高于80的同学的名称及课程
select st.name,co.course,sc.score from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.courseid having score > 80;
7、取每位同学各门课的平均成绩,显示成绩前三名的同学的姓名和平均成绩
select co.course,avg(sc.score) from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.courseid group by co.course;
8、显示每门课程课程名称及学习了这门课的同学的个数
select co.course,sum(st.stuid) from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.courseid group by co.course;
9、显示其年龄大于平均年龄的同学的名字
select name,age from students group by name having age > (select avg(age) from students);
10、显示其学习的课程为第1、2,4或第7门课的同学的名字
select st.name,co.course,co.courseid from students as st inner join scores as sc on st.stuid=sc.stuid inner join courses as co on sc.courseid=co.courseid where co.courseid in(1,2,4,7);
11、显示其成员数最少为3个的班级的同学中年龄大于同班同学平均年龄的同学
第一种写法:select * from students as a inner join (select classid,count(stuid),avg(age) as aage from students where classid >0 group by classid having count(stuid)>=3 ) as b on a.classid=b.classid where a.age>b.aage; 第二种写法: 拆分写:select classid,count(classid),avg(age) from students group by classid having count(classid)>=3; +---------+----------------+----------+ | classid | count(classid) | avg(age) | +---------+----------------+----------+ | 1 | 4 | 20.5000 | | 2 | 3 | 36.0000 | | 3 | 5 | 32.2000 | | 4 | 4 | 24.7500 | | 6 | 4 | 20.7500 | | 7 | 3 | 19.6667 | +---------+----------------+----------+ select * from students where classid=1 and age>20.5; select * from students where classid=2 and age>36.0;
12、统计各班级中年龄大于全校同学平均年龄的同学
select * from students where age >(select avg(age) from students);