SQL语言
SQL(Structured Query Language 即结构化查询语言)
作用:主要用于存取数据,查询数据,更新数据和管理关系数据库系统。
SQL语言类型
Data Definition Language(DDL)
DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE(创建) DROP(删除) ALTER
(修改) DECLARE(声明)
Data Manipulation Language(DML)
DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、SELECT查询
Data Query Language(DQL)
DQL语句 数据库查询语言: 查询数据SELECT(GRANT 授权, REVOKE 取消, COMMIT 提交, ROLLBACK 回滚)
Data Control Language(DCL)
DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE(SELECT)
涉及到的名词
数据库服务器
mysql> show databases;
information_schema 虚拟库,主要存储了系统中的一些数据库对象的信息,例如用户表信息,列信息,权限信
息,字符信息等
mysql 授权库,主要存储系统用户的权限信息
performance_schema 主要存储数据库服务器的性能参数
sys 主要存储数据库的性能参数
表 记录的管理单元
记录 字段的管理单元
字段 字段名,字段类型(长度),字段约束组成
类型 字符,数字,日期
约束 不能为空,自动增长
SQL语句注意事项
每条SQL语句结束时要以『;』做为结束符(除了『use』命令);
SQL语句的关键字不区分大小写(除了库名和表名);
在查询数据库信息和表信息时,可以以『\G』做为结束符,表示以文本模式输出;
当你不需要一条语句的输出结果时,可以以『\c』结束;
当我们想要在命令行上执行SQL语句时,可以用『mysql -e』的参数将结果显示到shell上,如:
# mysql -e “show databases \G”
mysql> help create
如需进一步获取帮助可以继续使用『help』命令,如:
mysql> help create database
mysql> ! ls 在mysql中执行shell命令
mysql> \q 退出mysql,等价于exit和quit
exit; \q; quit; 退出数据库
\c 取消本行命令
\G 将查询后的结果竖立起来
\s 显示当前的服务器状态
\h 帮助信息
specification规格
数值类型:
整数类型 TINYINT SMALLINT MEDIUMINT INT BIGINT
浮点数类型 FLOAT DOUBLE
定点数类型 DEC
位类型
BIT
FLOAT DOUBLE (近似值,类型代表近似数字数据值)
定点数类型 DEC (精确值,在保持精度很重时用这些类型,例如使用货币的数据)
位类型
BIT (该BIT数据类型被用于存储比特值。一种 能够存储位值的类型。 范围从1到64)
字符串类型:
CHAR系列
CHAR VARCHAR (其长度指示要存储的最大字符数)
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列
TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列 BINARY VARBINARY
枚举类型:
ENUM (多个选项,只能选择一个)
集合类型: SET (多个选项,可以多选)
时间和日期类型:
DATE TIME DATETIME TIMESTAMP YEAR
**===整数类型测试:tinyint,int **
作用:用于存储用户的年龄、游戏的Level、经验值等。
LAB1:
mysql> create table test1(
-> tinyint_test tinyint,
-> int_test int
-> );
mysql> desc test1;
+--------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+-------+
| tinyint_test | tinyint(4) | YES | | NULL | |
| int_test | int(11) | YES | | NULL | |
+--------------+------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into test1 values (111,111);Query OK, 1 row affected (0.09 sec)
mysql> insert into test1(tinyint_test) values(128);
ERROR 1264 (22003): Out of range value for column 'tinyint_test' at row 1
mysql> insert into test1(int_test) values(2147483647);
Query OK, 1 row affected (0.05 sec)
mysql> insert into test1(int_test) values(2147483648);
ERROR 1264 (22003): Out of range value for column 'int_test' at row 1
LAB2: 无符号整形测试
mysql> create table test2(
-> tinyint_test tinyint unsigned, //约束条件unsigned限定只能存正值(无符号)
-> int_test int unsigned
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> desc test2;
+--------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+-------+
| tinyint_test | tinyint(3) unsigned | YES | | NULL | |
| int_test | int(10) unsigned | YES | | NULL | |
+--------------+---------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into test2(tinyint_test) values(255);
Query OK, 1 row affected (0.06 sec)
mysql> insert into test2(int_test) values(2147483648);
Query OK, 1 row affected (1.87 sec)
mysql> insert into test2 values(-20,-20);
ERROR 1264 (22003): Out of range value for column 'tinyint_test' at row 1
测试整数类型的显示宽度
mysql> create table t1 (
-> id1 int,
-> id2 int(6)
-> );
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id1 | int(11) | YES | | NULL | |
| id2 | int(6) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
45/17846/178
mysql> insert into t1 values(1,1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+------+------+
| id1 | id2 |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)
mysql> create table t2 (
-> id1 int zerofill,
-> id2 int(6) zerofill
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> desc t2;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id1 | int(10) unsigned zerofill | YES | | NULL | |
| id2 | int(6) unsigned zerofill | YES | | NULL | |
+-------+---------------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into t2 values(2,2);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t2;
+------------+--------+
| id1 | id2 |
+------------+--------+
| 0000000002 | 000002 |
+------------+--------+
1 row in set (0.00 sec)
mysql> insert into t2 values(3,2222222);
//插入大于宽度限制的值,仍然可以存储
Query OK, 1 row affected (0.03 sec)
mysql> select * from t2;
+------------+---------+
| id1 | id2 |
+------------+---------+
| 0000000002 | 000002 |
| 0000000003 | 2222222 |
+------------+---------+
2 rows in set (0.00 sec)
显示宽度,不会影响,正常储存47/178
**===浮点数类型测试: **
作用:用于存储用户的身高、体重、薪水等
浮点数和定点数都可以用类型名称后加(M,D)的方式来表示,(M,D)表示一共显示M位数字(整数位
+小数位),其中D位于小数点后面,M和D又称为精度和标度。
float和double在不指定精度时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示,
而decimal在不指定精度时,默认的整数位为10,默认的小数位为0
定点数在MySQL内部以字符串形式存储,比浮点数更精确,适合用来表示货币等精度高的数据。
mysql> create table test4(float_test float(5,2));
//一共5位,小数占2位
Query OK, 0 rows affected (0.00 sec)
mysql> desc test4;
+------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| float_test | float(5,2) | YES | | NULL | |
+------------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> insert into test4 values (10.2), (70.243), (70.246);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from test4;
+------------+
| float_test |
+------------+
| 10.20 |
| 70.24 |
| 70.25 |
+------------+
3 rows in set (0.00 sec)
mysql> insert into test4 values (1111.2);
ERROR 1264 (22003): Out of range value for column 'float_test' at row 1
定点数decimal测试:(储存方式:字符串形式的储存!)
mysql> create table test5(decimal_test decimal(5,2));
mysql> insert into test5 values (70.245);
Query OK, 1 row affected, 1 warning (0.05 sec)
mysql> show warnings;
+-------+------+---------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------+
| Note | 1265 | Data truncated for column 'decimal_test' at row 1 |
+-------+------+---------------------------------------------------+
1 row in set (0.00 sec)
**===位类型测试:BIT **
BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位
对于位字段可以使用函数读取:
bin()显示为二进制
hex()显示为十六进制
mysql> create table test_bit (id bit(4));
Query OK, 0 rows affected (0.35 sec)
mysql> desc test_bit;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit(4) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.01 sec)
mysql> insert into test_bit values(4);
mysql> select * from test_bit;
+------+
| id |
+------+
| |
+------+
1 row in set (0.00 sec)
mysql> select bin(id),hex(id) from test_bit;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 100 | 4 |
+---------+---------+
1 row in set (0.00 sec)
插入超过指定宽度的值:
mysql> insert into test_bit values(8);
Query OK, 1 row affected (0.05 sec)
mysql> insert into test_bit values(9);
Query OK, 1 row affected (0.06 sec)
mysql> insert into test_bit values(16);
ERROR 1406 (22001): Data too long for column 'id' at row 1
**===时间和日期类型测试:year、date、time、datetime、timestamp **
作用:用于存储用户的注册时间,文章的发布时间,文章的更新时间,员工的入职时间等
48/17849/178
数据类型
“ 零 **”**值
DATE
‘0000-00-00’
TIME
‘00:00:00’
DATETIME
‘0000-00-00 00:00:00’
TIMESTAMP
‘0000-00-00 00:00:00’
YEAR
0000
mysql> create table test_time(
-> d date, 年月日
-> t time, 24小时(时分秒)
-> dt datetime 完整时间
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> desc test_time;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> insert into test_time values(now(),now(),now());
Query OK, 1 row affected, 1 warning (0.02 sec)
mysql> select * from test_time;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2013-12-18 | 00:06:10 | 2013-12-18 00:06:10 |
+------------+----------+---------------------+
1 row in set (0.00 sec)
mysql> insert into t3 values (20201001,'12:00:01','2022-12-12 20:00:15');
Query OK, 1 row affected (0.02 sec)
mysql> select * from t3;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2020-07-07 | 16:44:05 | 2020-07-07 16:44:05 |
| 2020-10-01 | 12:00:01 | 2022-12-12 20:00:15 |
+------------+----------+---------------------+
2 rows in set (0.00 sec)
mysql> insert into t3 values ();
Query OK, 1 row affected (0.00 sec)mysql> select * from t3;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2020-07-07 | 16:44:05 | 2020-07-07 16:44:05 |
| 2020-10-01 | 12:00:01 | 2022-12-12 20:00:15 |
| NULL | NULL | NULL |
+------------+----------+---------------------+
3 rows in set (0.00 sec)
mysql> create table t(id timestamp);
Query OK, 0 rows affected (0.01 sec)
mysql> desc t;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.00 sec)
mysql> insert into t values(null);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t;
+---------------------+
| id |
+---------------------+
| 2013-12-18 00:08:41 |
+---------------------+
1 row in set (0.00 sec)
注意事项:
其它的时间,按要求插入
==插入年份时,尽量使用4位值
==插入两位年份时,<=69,以20开头,比如65, 结果2065
\>=70,以19开头,比如82,结果1982
mysql> create table t3(born_year year);
Query OK, 0 rows affected (0.40 sec)
mysql> desc t3;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| born_year | year(4) | YES | | NULL | |
+-----------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
50/178mysql> insert into t3 values
-> (12),(80);
Query OK, 2 rows affected (0.06 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t3;
+-----------+
| born_year |
+-----------+
| 2012 |
| 1980 |
+-----------+
2 rows in set (0.00 sec)
**===字符串类型测试:CHAR、VARCHAR **
作用:用于存储用户的姓名、爱好、发布的文章等
CHAR 列的长度固定为创建表时声明的长度: 0 ~ 255
VARCHAR 列中的值为可变长字符串,长度: 0 ~ 65535
以 >create table t1(id1 char(10),id2 varchar(10));为例:
其中,char类型中的10个长度是固定的,无论你插入的是123,还是1234567890,都占用10个长度的储存空间。
然而varchar类型中的10个长度是可以收缩变化的,如果你插入的字符是123,那么系统值占用3个字符的长度,但是
会限制超过10个字符的长度。
注:在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留这些空格
mysql> create table vc (
-> v varchar(4),
-> c char(4)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> desc vc;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| v | varchar(4) | YES | | NULL | |
| c | char(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into vc values('ab ','ab ');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from vc;
+------+------+
| v | c |
+------+------+
51/17852/178
| ab | ab |
+------+------+
1 row in set (0.00 sec)
mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 4 | 2 |
+-----------+-----------+
1 row in set (0.00 sec)
mysql> select concat(v,'='), concat(c,'=') from vc; //在后面加字符'=',看的更清楚
+---------------+---------------+
| concat(v,'=') | concat(c,'=') |
+---------------+---------------+
| ab = | ab= |
+---------------+---------------+
1 row in set (0.00 sec)
**字符串类型测试:BINARY、VARBINARY **
BINARY 和 VARBINARY类似于CHAR 和 VARCHAR,不同的是它们包含二进制字符而不包含
非二进制字符串
mysql> create table binary_t (c binary(3));
Query OK, 0 rows affected (0.03 sec)
mysql> desc binary_t;
+-------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| c | binary(3) | YES | | NULL | |
+-------+-----------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> insert into binary_t set c='aaa';
Query OK, 1 row affected (0.00 sec)
mysql> select *,hex(c) from binary_t;
+------+--------+
| c | hex(c) |
+------+--------+
| aaa | 616161 |
+------+--------+
1 row in set (0.00 sec)
===字符串类型
**===ENUM类型即枚举类型、集合类型SET测试 **
字段的值只能在给定范围中选择
常见的是单选按钮和复选框
enum 单选
只能在给定的范围内选一个值,如性别 sex 男male/女female53/178
set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3…)
表school.student3
姓名
name
varchar(50)
性别
sex
enum(‘m’,‘f’)
爱好
hobby
set(‘music’,‘book’,‘game’,‘disc’)
mysql> use school
mysql> create table student3(
-> name varchar(50),
-> sex enum('m','f'),
-> hobby set('music','book','game','disc')
-> );
Query OK, 0 rows affected (0.31 sec)
mysql> desc student3;
+-------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------------------+------+-----+---------+-------+
| name | varchar(50) | YES | | NULL | |
| sex | enum('m','f') | YES | | NULL | |
| hobby | set('music','book','game','disc') | YES | | NULL | |
+-------+-----------------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student3 values
-> ('tom','m','book,game');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student3;
+------+------+-----------+
| name | sex | hobby |
+------+------+-----------+
| tom | boy | book,game |
+------+------+-----------+
1 row in set (0.00 sec)
mysql> insert into student3 values ('jack','m','film');
ERROR 1265 (01000): Data truncated for column 'hobby' at row 1
mysql> show create table student3\G;
*************************** 1. row ***************************
Table: student3
Create Table: CREATE TABLE `student3` (
`name` varchar(50) default NULL,
`sex` enum('m','f') default NULL,
`hobby` set('music','book','game','disc') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
整型
作用:可以用于存储用户的年龄、游戏的等级等,只能存整数。
分类:tinyint smallint mediumint int bigint这四类
有符号 :
有正负数
无符号 :
没有负数 类型后面使用unsigned和zerofill修饰符
tinyint 最短整型,后面**(+宽度,默认存在为4**,显示宽度**)**
int 后面**(+宽度,默认存在为11**,显示宽度**)**
将有符号变成无符号:
unsigned:
mysql> create table t6(id int(8) unsigned);
zerofill: 0填充
mysql> create table t2 (
-> id1 int zerofill,
54/178 -> id2 int(6)-显示宽度 zerofill
-> );
显示宽度:
类型后面小括号内的数字是显示宽度,不能限制插入数值的大小
比如:int(11) 11是显示宽度
浮点型 :单精度float(4)和双精度double
作用:用于存储用户的身高、体重、薪水等
float(M,D) M总宽度 D位小数
宽度不算小数点
mysql> create table t12(id float(6,2));
double(M,D)
0~24:单精度float,从第7位有效位,进行5舍6入存储
25~30:双精度double,从第16位有效位,进行4舍5入存储
定点型
定点数在MySQL内部以字符串形式存储,比浮点数更精确,适合用来表示货币等精度高的数据。
decimal(M,[D])
M:1-65 默认10
D:0-30 默认0
sql server数据类型
创建一个库 create database + 库名
要求:
• 可以由数字、字母、下划线、@、#、$
• 区分大小写
• 唯一性
• 不能使用关键字,如create select
• 不能单独使用数字
• 最长128位
进入库/切换 use +库名
查看自己处在那个库:select database();
杳看自己所在的用户:select user();
mysql> show databases;
information_schema 虚拟库,主要存储了系统中的一些数据库对象的信息,例如用户表信息,列信息,权限信
息,字符信息等
mysql 授权库,主要存储系统用户的权限信息
performance_schema 主要存储数据库服务器的性能参数
sys 主要存储数据库的性能参数
**表的管理单元 **
表 记录的管理单元
记录 字段的管理单元
字段 字段名,字段类型(长度),字段约束组成
类型 字符,数字,日期
约束 不能为空,自动增长
例:
表school.student1
id | name | sex |
---|---|---|
1 | u1 | male |
2 | u2 | male |
3 | u3 | fermale |
创建表
CREATE TABLE tbl_name (
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
…
) ;
创建表 create table +表名;
查看表 show tables; show create table +表名;详细查看
查看表状态 show table status like ‘+表名’ \G
查看表结构 desc 表名;
查看表的创建过程 show create table +表名; 查看表内容 seletc * from + 表名
使用\G结尾,按记录显示,每条记录显示一次
修改表
修改表名称 rename table 原名称 to 新名称; alter table 原名称 rename 新名称;
添加字段 alter table class add gender enum 枚举
删除表 drop table class
删除表字段 alter table cless drop ename;
修改字段
modify : 不可以改名 alter table info modify name char(20) after age;
change :可以改名 alter table info change name ename char(20) ;
添加记录(数据):
方式1:
insert into 表名(字段名1,字段名2…) values(数值1,数值2…)
方式2:
insert into 表名 values(数值1,数值2…) ;
insert into info(ename,age) values(“tom”,24),(“jim”,25),(“alan”,30);
insert into info set name=(“zy”),age=18; 添加单条记录
更新:
更新记录:update info set grade=4 where ename=“alan”;
查询 select * from 表名
删除记录:delete from 表名 where id=170301;
delete from 表名; 将表内所用记录删除
删除表 drop table 表名;
删除库 drop database 库名;
创建库:
语法:create database 库名;
创建表:
语法:create table 表名(表结构);
添加字段***
语法:alter table 表名 add 字段名 数据类型;
添加记录:
方法一:
语法:insert into 表名(字段1,字段2) values(数据1,数据2);
方法二、
语法:insert into 表名 set 字段=(“数据”);
insert into 表名 set 字段1=(“数据1”),字段2=(“数据2”);
删除库
语法: drop database 库名;
删除表:
语法:drop table 表名;
删除表字段
语法 : alter table 表名 drop 字段名;
删除记录:
方法一: delete from 表名 where 条件;
语法二:delete from 表名 ; (将表内所用记录删除)
修改表名称
语法一:rename table 旧表名 to 新表名;
语法二:alter table 旧表名 rename 新表名;
修改字段
方法一:modify-----不可以改名
语法:alter table 表名 modify字段名 新数据类型;
方法二:change-----可以改名
语法: alter table 表名 change 旧字段名 新字段名 新数据类型;
更新记录:
语法:update 表名 set 字段=数据 where 条件;
update test1 set name=‘tom’ where id=4; 意思是:将id=4所对应的name更改为tom。
切换库:
语法:use +库名[;]
查看所在库:
语法:select database();
查看表名:
语法:show tables;
查看表状态
语法:show table status like ‘表名’\G ;
其中,查看表的时候使用\G结尾,作用是按记录显示,每条记录显示一次
查看表结构
语法: desc 表名;
查看表的创建过程(详细查看表结构)
语法:show create table 表名;
查询数据:
语法:select 字段名 from 表名;
mysql> desc t3;
±------±---------±-----±----±--------±------+
67/178| Field | Type | Null | Key | Default | Extra |
±------±---------±-----±----±--------±------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
±------±---------±-----±----±--------±------+
3 rows in set (0.00 sec)
mysql> select * from t3
-> ;
±-----------±---------±--------------------+
| d | t | dt |
±-----------±---------±--------------------+
| 2020-07-07 | 16:44:05 | 2020-07-07 16:44:05 |
| 2020-10-01 | 12:00:01 | 2022-12-12 20:00:15 |
| NULL | NULL | NULL |
±-----------±---------±--------------------+
3 rows in set (0.00 sec)
mysql> **create table new_t3 select * from t3; 复制整张表 **
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> desc new_t3;
±------±---------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±---------±-----±----±--------±------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
±------±---------±-----±----±--------±------+
3 rows in set (0.00 sec)
mysql> select * from new_t3;
±-----------±---------±--------------------+
| d | t | dt |
±-----------±---------±--------------------+
| 2020-07-07 | 16:44:05 | 2020-07-07 16:44:05 |
| 2020-10-01 | 12:00:01 | 2022-12-12 20:00:15 |
| NULL | NULL | NULL |
±-----------±---------±--------------------+
3 rows in set (0.00 sec)
============================================
mysql> desc new1;
±------±----------------------------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±----------------------------------±-----±----±--------±------+
| names | char(15) | YES | | NULL | |
| sex | enum(‘男’,‘女’) | YES | | NULL | |
| ages | int(20) | YES | | NULL | |
68/178| hobby | set(‘music’,‘book’,‘game’,‘disc’) | YES | | NULL | |
±------±----------------------------------±-----±----±--------±------+
4 rows in set (0.00 sec)
mysql> select * from t2;
±----------±-----±-----±------+
| names | sex | ages | hobby |
±----------±-----±-----±------+
| 蜘蛛精 | 女 | 18 | disc |
| 唐曾 | 男 | 22 | book |
±----------±-----±-----±------+
2 rows in set (0.00 sec)
mysql> create table new1 select * from t2 where 1=2; 只复制表结构不复制内
容
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc new1;
±------±----------------------------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±----------------------------------±-----±----±--------±------+
| names | char(15) | YES | | NULL | |
| sex | enum(‘男’,‘女’) | YES | | NULL | |
| ages | int(20) | YES | | NULL | |
| hobby | set(‘music’,‘book’,‘game’,‘disc’) | YES | | NULL | |
±------±----------------------------------±-----±----±--------±------+
4 rows in set (0.00 sec)
mysql> select * from new1;
Empty set (0.00 sec)
**表的完整约束表的完整性约束 **
作用:用于保证数据的完整性和一致性。例如:不让年龄成为负值,不让ID相同。
约束有哪些?非空、唯一、默认值、主键、外键、自增语法:字段名数据类型[宽度|not null|unique|default 默认值|auto_increment]约束条件
UNSIGNED
ZEROFILL
NOT NULL
DEFAULT
UNIQUE KEY (UK)
PRIMARY KEY (PK)
AUTO_INCREMENT
FOREIGN KEY (FK)
on delete cascade
on update cascade
说明
是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值哪怕是空格也可以
字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
sex enum(‘male’,‘female’) not null default ‘male’
age int unsigned NOT NULL default 20
▪主键 primary key
▪外键 forengn key
▪索引 index,unique…
默认值:当用户向表中插入数据时,指定了该字段的值,那么就插入该值,否则就插入默认值
mysql> create table t1 (name char(4),sex enum ('男','女'));
Query OK, 0 rows affected (0.02 sec)
mysql> select * from t1;
Empty set (0.00 sec)
mysql> desc t1;
+-------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------------+------+-----+---------+-------+
| name | char(4) | YES | | NULL | |
| sex | enum('男','女') | YES | | NULL | |
+-------+-------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> select * from t1; sex字段记录默认为NULL
+-----------+------+
| name | sex |
+-----------+------+
| 白骨精 | NULL |
+-----------+------+
1 row in set (0.00 sec)
=======================================================mysql> create table t2 (name char(10),sex enum('男','女')default'男');
Query OK, 0 rows affected (0.02 sec)
mysql> desc t2;
+-------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------------+------+-----+---------+-------+
| name | char(10) | YES | | NULL | |
| sex | enum('男','女') | YES | | 男 | |
+-------+-------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into t2(name) value ('猪八戒');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t2;
+-----------+------+
| name | sex |
+-----------+------+
| 猪八戒 | 男 |
+-----------+------+
1 row in set (0.00 sec)
mysql> select * from t1;
+-----------+------+
| name | sex |
+-----------+------+
| 白骨精 | NULL |
+-----------+------+
1 row in set (0.00 sec)mysql> select * from t1 where sex is null ;
+-----------+------+
| name | sex |
+-----------+------+
| 白骨精 | NULL |
+-----------+------+
1 row in set (0.00 sec)mysql> select * from t1 where sex is not null ;Empty set (0.01 sec)mysql> create table t3(id int not null,name char(10),sex varchar(10),age int);Query OK, 0 rows affected (0.02 sec)mysql> desc t3;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | char(10) | YES | | NULL | |
| sex | varchar(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+4 rows in set (0.00 sec)mysql> insert into t3(name,sex,age) value('悟空','男','600'); ERROR 1364 (HY000): Field 'id' doesn't have a default value id 不能为空mysql> insert into t3(name,sex,age) value(2,'悟空','男','600');
ERROR 1136 (21S01): Column count doesn't match value count at row 1mysql> insert into t3(id,name,sex,age) value(2,'悟空','男','600');Query OK, 1 row affected (0.02 sec)
mysql> select * from t3;
+----+--------+------+-------+
| id | name | sex | age |
+----+--------+------+-------+
| 1 | 佛祖 | NULL | 10000 |
| 2 | 悟空 | 男 | 600 |
+----+--------+------+-------+
2 rows in set (0.00 sec)
mysql> create table t4(id int unique,name char(10));
Query OK, 0 rows affected (0.03 sec)
mysql> desc t4;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into t4 values (1,'沙曾');
Query OK, 1 row affected (0.01 sec)
mysql> select * from t4;
+------+--------+
| id | name |
+------+--------+
| 1 | 沙曾 |
+------+--------+
1 row in set (0.00 sec)
mysql> insert into t4 values (1,'长娥'); id 字段是唯一不能记录相同的记录
ERROR 1062 (23000): Duplicate entry '1' for key 'id'
主键主键是表中的特殊字段,这个字段能够唯一标识表中的每一条记录。
一张表只能有一个主键
主键的用途:快速定位数据
主键要满足的条件:非空且唯一
primary key == not null + unique
1)使用单个字段做主键
1.1 在字段后直接指定主键约束(列级约束,默认值为null)
mysql> create table t6(id int primary key,name char(10),age int);
Query OK, 0 rows affected (0.03 sec)
mysql> desc t6;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t6 values(1,'jim',18);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t6;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | jim | 18 |
+----+------+------+
1 row in set (0.00 sec)
mysql> insert into t6 values(1,'tom',20);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
unique 唯一mysql> insert into t6 values();
ERROR 1364 (HY000): Field 'id' doesn't have a default value
非空2)整张表的所有字段都定义完成之后再来指定主键(表级约束,默认值是0)mysql> create table t7(id int,name char(10),primary key (id));
Query OK, 0 rows affected (0.03 sec)
mysql> desc t7;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into t7 values();
ERROR 1364 (HY000): Field 'id' doesn't have a default value
mysql> insert into t7(id,name) values(1,'u1');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t7(id,name) values(2,'u2'),(2,'u3');
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
mysql> select * from t7;
+----+------+
| id | name |
+----+------+
| 1 | u1 |
+----+------+
1 row in set (0.00 sec)
3)多个字段做联合主键
注意:联合主键只能在所有字段都定义完成之后,才能定义主键。
mysql> create table t8(id int,name char(10), age char(10),primary key (id,age));
Query OK, 0 rows affected (0.03 sec)
mysql> desc t8;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | YES | | NULL | |
| age | char(10) | NO | PRI | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t8 values(1,'u1',18);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t8;
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | u1 | 18 |
+----+------+-----+
1 row in set (0.00 sec)
mysql> insert into t8 values(1,'u2',20);
Query OK, 1 row affected (0.02 sec)mysql> insert into t8 values(1,'u2',18);
ERROR 1062 (23000): Duplicate entry '1-18' for key 'PRIMARY'
mysql> insert into t8 values(1,'u2',19);
Query OK, 1 row affected (0.01 sec)
将两个或多个字段设置为联合主键,其中一个字段的值重了,另一个字段的值不同记录是可以添加成功的联合主键是将多个字段当做一个整体,只要多个字段的组合的值不是完全相同记录都可以添加成功
自增 auto_increment要求:
1)该字段必须是数值型
2)字段上要有唯一性索引或者主键
mysql> create table t5(id int primary key auto_increment, name char(4));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t5 values();
Query OK, 1 row affected (0.02 sec)
mysql> insert into t5 values();
Query OK, 1 row affected (0.02 sec)
mysql> insert into t5 values();
Query OK, 1 row affected (0.00 sec)
mysql> select * from t5;
+----+------+
| id | name |
+----+------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
+----+------+
3 rows in set (0.00 sec)
mysql> insert into t5 values(6,'观音');
Query OK, 1 row affected (0.02 sec)
mysql> select * from t5;
+----+--------+
| id | name |
+----+--------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 6 | 观音 |
+----+--------+
4 rows in set (0.00 sec)
mysql> insert into t5 values();
Query OK, 1 row affected (0.02 sec)
mysql> select * from t5;
+----+--------+
| id | name |
+----+--------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 6 | 观音 |
| 7 | NULL |
+----+--------+
5 rows in set (0.00 sec)
**总结: **
1.当自增字段发生断档时,值会从最大值继续自增
2.当delete删除最大值时,下一个值仍然从删除之前的最大值继续自增
3.当truncate表时,值从1开始重新计算
truncate 缩短
FOREIGN KEY外键外键 foreign key
外键:一个表的数据依赖另一张表的主键列的数据,如果在主键列没有出现的值,是不能够出现在外键字段的。
创建外键的条件:
1)存储引擎必须是innodb
2)相关联字段数据类型要一致
3)最好在外键列上建索引(目的是为了减少扫描范围,不创建也可以,只是影响性能)
innodb引擎支持外键,但是myisam引擎不支持外键
FOREIGN KEY 约束用于预防破坏表之间连接的动作。
FOREIGN KEY 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。创建父表
mysql> create table class(ID int primary key, class char(20));
Query OK, 0 rows affected (0.03 sec)
创建子表mysql> create table student(class_ID int,name char(20),age int,foreign key(class_ID) references class(ID));
Query OK, 0 rows affected (0.02 sec)
如果一张表中有一个非主键的字段指向了另一张表中的主键,就将该字段叫做外键向父表插入数据
mysql> insert into class values (1,'gao1'),(2,'gao2'),(3,'gao3');
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
向子表中插入数据
mysql> insert into student values(1,'u1',18),(2,'u2',19),(3,'u3',20);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from class;
+----+-------+
| ID | class |
+----+-------+
| 1 | gao1 |
| 2 | gao2 |
| 3 | gao3 |
+----+-------+
3 rows in set (0.00 sec)
mysql> select * from student;
+----------+------+------+
| class_ID | name | age |
+----------+------+------+
| 1 | u1 | 18 |
| 2 | u2 | 19 |
| 3 | u3 | 20 |
+----------+------+------+
3 rows in set (0.00 sec)
向子表中插入父表不存在的班级号
mysql> insert into student values(4,'u4',20);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`student`,
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_ID`) REFERENCES `class` (`ID`))
删除父表中有外键依赖的数据
mysql> delete from class where ID=2;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student`,
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_ID`) REFERENCES `class` (`ID`))
总结:
1)子表中的关联数据依赖于父表,不能向子表中插入父表中不存在的值
2)不能删除父表中被子表所依赖的记录
删除父表中被依赖的行的方法:
1)删除外键约束
2)指定级联操作的选项
cascade:级联模式, 父表操作后,子表关联的数据也跟着一起操作。
mysql> drop table student;
Query OK, 0 rows affected (0.03 sec)
mysql> create table student(class_id int,name char(20),age int,foreign key(class_id) references class(ID) on
delete cascade on update cascade);
Query OK, 0 rows affected (0.02 sec)
mysql> desc student;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| class_id | int(11) | YES | MUL | NULL | |
| name | char(20) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into student values(1,'u1',18),(2,'u2',19),(3,'u3',20);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from student;
+----------+------+------+
| class_id | name | age |
+----------+------+------+
| 1 | u1 | 18 |
| 2 | u2 | 19 |
| 3 | u3 | 20 |
+----------+------+------+
3 rows in set (0.00 sec)mysql> select * from class;
+----+-------+
| ID | class |
+----+-------+
| 1 | gao1 |
| 2 | gao2 |
| 3 | gao3 |
+----+-------+
3 rows in set (0.00 sec)
mysql> delete from class where ID=2;
Query OK, 1 row affected (0.00 sec)
mysql> select * from class
-> ;
+----+-------+
| ID | class |
+----+-------+
| 1 | gao1 |
| 3 | gao3 |
+----+-------+
2 rows in set (0.00 sec)
mysql> select * from student;
+----------+------+------+
| class_id | name | age |
+----------+------+------+
| 1 | u1 | 18 |
| 3 | u3 | 20 |
+----------+------+------+
2 rows in set (0.00 sec)
mysql> update class set ID=4 where ID=1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from class;
+----+-------+
| ID | class |
+----+-------+
| 3 | gao3 |
| 4 | gao1 |
+----+-------+
2 rows in set (0.00 sec)
mysql> select * from student;
+----------+------+------+
| class_id | name | age |
+----------+------+------+
| 4 | u1 | 18 |
| 3 | u3 | 20 |
+----------+------+------+
2 rows in set (0.00 sec)
总结:有了级联删除和级联更新选项,父表中的数据发生删除或者更新时,子表中相关数据也会发生相应的变化。删除外键
查看外键名字
mysql> show create table student \G;
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`class_id` int(11) DEFAULT NULL,
`name` char(40) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
KEY `class_id` (`class_id`),
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`ID`) ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
查看外键的名字,粗字体为外键的名字语法:
alter table 表名 drop FOREIGN KEY **student_ibfk_1**;
mysql> show create table student \G;
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`class_id` int(11) DEFAULT NULL,
`name` char(40) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
KEY `class_id` (`class_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select 字段名称,字段名称2 from 表名条件
简单查询:
mysql> select * from t3;
mysql> select name, salary, dep_id from employee5 where id <=5;
避免重复“DISTINCT”
SELECT post FROM employee5;SELECT distinct post FROM employee5;注:不能部分使用DISTINCT,通常仅用于结果集去重mysql> select * from employee;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 1 | jack | male | 2018-02-02 | instructor | teach | 5000.00 | 501 | 100 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 5 | Alan | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
10 rows in set (0.00 sec)
mysql> select name,sex,salary from employee;条件查询
+-----------+--------+----------+
| name | sex | salary |
+-----------+--------+----------+
| jack | male | 5000.00 |
| tom | male | 5500.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
+-----------+--------+----------+
10 rows in set (0.00 sec)
自定义显示字段
mysql> select name,sex,salary from employee where id<5;
+-------+--------+---------+
| name | sex | salary |
+-------+--------+---------+
| jack | male | 5000.00 |
| tom | male | 5500.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
+-------+--------+---------+
4 rows in set (0.00 sec)
======================================================
mysql> select name,salary from employee;
+-----------+----------+
| name | salary |
+-----------+----------+
| jack | 5000.00 |
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| Alan | 600.00 |
| harry | 6000.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
10 rows in set (0.00 sec)mysql> select distinct salary from employee; 只能部分使用DISTINCT,通常仅用于某一字段(一个一个的查询)
+----------+
| salary |
+----------+
| 5000.00 |
| 5500.00 |
| 8000.00 |
| 7200.00 |
| 600.00 |
| 6000.00 |
| 20000.00 |
| 2200.00 |
+----------+
8 rows in set (0.00 sec)mysql> select distinct name,salary from employee; 只能查询某一个字段查询多个不生效
+-----------+----------+
| name | salary |
+-----------+----------+
| jack | 5000.00 |
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| Alan | 600.00 |
| harry | 6000.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
10 rows in set (0.00 sec)
运算:
#mysql -u root -p’123’ -e ‘select 5+8’#mysql -u root -p’123’ -e ‘use company;select * from employee’
SELECT name, salary, salary*14 FROM employee5;
SELECT name, salary, salary14 AS Annual_salary FROM employee5;SELECT name, salary, salary14 Annual_salary FROM employee5;
数据库内也支持四则运算
mysql> select 5+8;
+-----+
| 5+8 |
+-----+
| 13 |
+-----+
1 row in set (0.00 sec)
mysql> select 10+5;
+------+
| 10+5 |
+------+
| 15 |
+------+
1 row in set (0.00 sec)
mysql> select 10*5;
+------+
| 10*5 |
+------+
| 50 |
+------+
1 row in set (0.00 sec)
mysql> select 10/5;
+--------+
| 10/5 |
+--------+
| 2.0000 |
+--------+
1 row in set (0.00 sec)
mysql> select 10-5;
+------+
| 10-5 |
+------+
| 5 |
+------+
1 row in set (0.00 sec)
“as” 给字段做别名可以和四则运算一起用
mysql> select name as 姓名,sex as 姓别,salary as 薪资,salary*13 as 年薪 from employee;
+-----------+--------+----------+-----------+
| 姓名 | 姓别 | 薪资 | 年薪 |
+-----------+--------+----------+-----------+
| jack | male | 5000.00 | 65000.00 |
| tom | male | 5500.00 | 71500.00 |
| robin | male | 8000.00 | 104000.00 |
| alice | female | 7200.00 | 93600.00 |
| Alan | male | 600.00 | 7800.00 |
| harry | male | 6000.00 | 78000.00 |
| emma | female | 20000.00 | 260000.00 |
| christine | female | 2200.00 | 28600.00 |
| zhuzhu | male | 2200.00 | 28600.00 |
| gougou | male | 2200.00 | 28600.00 |
+-----------+--------+----------+-----------+
10 rows in set (0.00 sec)
concat() 函数定义显示格式
CONCAT() 函数用于连接字符串(链接拼接的作用,并且可以添加想要的字符串)
SELECT concat(name, 's annual salary: ', salary14) AS Annual_salary FROM employee5;mysql> select concat(name,‘的月新是:’,salary,‘年薪是:’,salary13 ,'部门编号
为:’,dep_id) from employee;
±--------------------------------------------------------------------------------------+
| concat(name,‘的月新是:’,salary,‘年薪是:’,salary*13 ,‘部门编号为:’,dep_id) |
±--------------------------------------------------------------------------------------+
| jack的月新是:5000.00年薪是:65000.00部门编号为:100 |
| tom的月新是:5500.00年薪是:71500.00部门编号为:100 |
| robin的月新是:8000.00年薪是:104000.00部门编号为:100 |
| alice的月新是:7200.00年薪是:93600.00部门编号为:100 |
| Alan的月新是:600.00年薪是:7800.00部门编号为:101 |
| harry的月新是:6000.00年薪是:78000.00部门编号为:101 |
| emma的月新是:20000.00年薪是:260000.00部门编号为:102 |
| christine的月新是:2200.00年薪是:28600.00部门编号为:102 |
| zhuzhu的月新是:2200.00年薪是:28600.00部门编号为:102 |
| gougou的月新是:2200.00年薪是:28600.00部门编号为:102 |
±--------------------------------------------------------------------------------------+
10 rows in set (0.06 sec)
单条件查询
mysql> select 字段名 from 表名 where 条件;
mysql>select name,salary from employee where salary>5000;
±------±---------+
| name | salary |
±------±---------+
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
| emma | 20000.00 |
±------±---------+
5 rows in set (0.00 sec)
多条件查询(and 和 or)
mysql> select name,sex,salary from employee where salary>=5000 and salary<=7000;
±------±-----±--------+
| name | sex | salary |
±------±-----±--------+
| jack | male | 5000.00 |
| tom | male | 5500.00 |
| harry | male | 6000.00 |
±------±-----±--------+
3 rows in set (0.00 sec)
mysql>select name,sex,salary from employee where not salary>=5000;
±----------±-------±--------+
| name | sex | salary |
±----------±-------±--------+
| Alan | male | 600.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±----------±-------±--------+
4 rows in set (0.01 sec)
mysql> select name,sex,salary from employee where salary>=5000 or salary<=500;±------±-------±---------+
| name | sex | salary |
±------±-------±---------+
| jack | male | 5000.00 |
| tom | male | 5500.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
±------±-------±---------+
6 rows in set (0.00 sec)
关键字BETWEEN AND & between(两者之间) and
mysql> select name,sex,salary from employee where salary between 2000 and 5000;
±----------±-------±--------+
| name | sex | salary |
±----------±-------±--------+
| jack | male | 5000.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±----------±-------±--------+
4 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where salary not between 2000 and 5000;
±------±-------±---------+
| name | sex | salary |
±------±-------±---------+
| tom | male | 5500.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
±------±-------±---------+
6 rows in set (0.00 sec)
关键字IS NULL
mysql> SELECT name,job_description FROM employee WHERE job_description IS NULL;
±-------±----------------+
| name | job_description |
±-------±----------------+
| harry | NULL |
| zhuzhu | NULL |
±-------±----------------+
2 rows in set (0.00 sec)
mysql> SELECT name,job_description FROM employee WHERE job_description IS NOT NULL;
±----------±----------------+
| name | job_description |
±----------±----------------+
| jack | teach |
| tom | teach |
| robin | teach |
| alice | teach |
| Alan | hrcc |
| emma | salecc |
| christine | salecc |
| gougou | |
±----------±----------------+
8 rows in set (0.00 sec)
mysql> SELECT name,job_description FROM employee WHERE job_description=’’;
±-------±----------------+
| name | job_description |
±-------±----------------+
| gougou | |
±-------±----------------+
1 row in set (0.00 sec)
NULL说明:
1、等价于没有任何值、是未知数。
2、NULL与0、空字符串、空格都不同,NULL没有分配存储空间。
3、对空值做加、减、乘、除等运算操作,结果仍为空。
4、比较时使用关键字用“is null”和“is not null”。
5、排序时比其他数据都小(索引默认是降序排列,小→大),所以NULL值总是排在最前。
**关键字IN集合查询 **
mysql> select name,sex,salary from employee where salary=4000 or salary=5000 or salary=80000
±------±-----±--------+
| name | sex | salary |
±------±-----±--------+
| jack | male | 5000.00 |
| robin | male | 8000.00 |
±------±-----±--------+
2 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where salary in(4000,5000,8000,9000);
±------±-----±--------+
| name | sex | salary |
±------±-----±--------+
| jack | male | 5000.00 |
| robin | male | 8000.00 |
±------±-----±--------+
2 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where salary not in(4000,5000,8000,9000);
±----------±-------±---------+
| name | sex | salary |
±----------±-------±---------+
| tom | male | 5500.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±----------±-------±---------+
8 rows in set (0.00 sec)
**排序查询 DESC 、ASC 、 order by 注:order by按…排序 **
ascending 美音 /ə’sɛndɪŋ/ 升序
descending 美音 /dɪ’sɛndɪŋ/ 降序
mysql> select name,sex,hire_date,salary,dep_id from employee order by salary desc;
±----------±-------±-----------±---------±-------+
| name | sex | hire_date | salary | dep_id |
±----------±-------±-----------±---------±-------+
| emma | female | 2018-02-06 | 20000.00 | 102 |
| robin | male | 2018-02-02 | 8000.00 | 100 |
| alice | female | 2018-02-02 | 7200.00 | 100 |
| harry | male | 2018-02-02 | 6000.00 | 101 |
| tom | male | 2018-02-03 | 5500.00 | 100 |
| jack | male | 2018-02-02 | 5000.00 | 100 |
| christine | female | 2018-02-05 | 2200.00 | 102 |
| zhuzhu | male | 2018-02-05 | 2200.00 | 102 |
| gougou | male | 2018-02-05 | 2200.00 | 102 |
| Alan | male | 2018-02-02 | 600.00 | 101 |
±----------±-------±-----------±---------±-------+
10 rows in set (0.00 sec)
mysql> select name,sex,hire_date,salary,dep_id from employeeorder by salary asc;
±----------±-------±-----------±---------±-------+
| name | sex | hire_date | salary | dep_id |
±----------±-------±-----------±---------±-------+
| Alan | male | 2018-02-02 | 600.00 | 101 |
| christine | female | 2018-02-05 | 2200.00 | 102 |
| zhuzhu | male | 2018-02-05 | 2200.00 | 102 |
| gougou | male | 2018-02-05 | 2200.00 | 102 |
| jack | male | 2018-02-02 | 5000.00 | 100 |
| tom | male | 2018-02-03 | 5500.00 | 100 |
| harry | male | 2018-02-02 | 6000.00 | 101 |
| alice | female | 2018-02-02 | 7200.00 | 100 |
| robin | male | 2018-02-02 | 8000.00 | 100 |
94/178| emma | female | 2018-02-06 | 20000.00 | 102 |
±----------±-------±-----------±---------±-------+
10 rows in set (0.00 sec)
**按多列排序:入职时间相同的人薪水不同 **
mysql> SELECT name,hire_date,salary FROM employee ORDER BY hire_date DESC,salary ASC;
±----------±-----------±---------+
| name | hire_date | salary |
±----------±-----------±---------+
| emma | 2018-02-06 | 20000.00 |
| christine | 2018-02-05 | 2200.00 |
| zhuzhu | 2018-02-05 | 2200.00 |
| gougou | 2018-02-05 | 2200.00 |
| tom | 2018-02-03 | 5500.00 |
| Alan | 2018-02-02 | 600.00 |
| jack | 2018-02-02 | 5000.00 |
| harry | 2018-02-02 | 6000.00 |
| alice | 2018-02-02 | 7200.00 |
| robin | 2018-02-02 | 8000.00 |
±----------±-----------±---------+
10 rows in set (0.00 sec)
限制查询的记录数 limit :(限制,控制)
mysql> mysql> SELECT name,salary FROM employee ORDER BY salary DESC;
±----------±---------+
| name | salary |
±----------±---------+
| emma | 20000.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
| tom | 5500.00 |
| jack | 5000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
| Alan | 600.00 |
±----------±---------+
10 rows in set (0.00 sec)
mysql> SELECT name,salary FROM employee ORDER BY salary DESC limit 5; 对结果集限制
±------±---------+
| name | salary |
±------±---------+
| emma | 20000.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
| tom | 5500.00 |
±------±---------+
5 rows in set (0.00 sec)
//默认初始位置为0 SELECT * FROM employee5 ORDER BY salary DESCLIMIT 3,5;
//从第4条开始,共显示5条
mysql> SELECT name,salary FROM employee ORDER BY salary DESC ;
±----------±---------+
| name | salary |
±----------±---------+
| emma | 20000.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
| tom | 5500.00 |
| jack | 5000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
| Alan | 600.00 |
±----------±---------+
10 rows in set (0.00 sec)
mysql> SELECT name,salary FROM employee ORDER BY salary DESC limit 3,2;
±------±--------+
| name | salary |
±------±--------+
| harry | 6000.00 |
| tom | 5500.00 |
±------±--------+
2 rows in set (0.00 sec)
**集合函数 **
count() 计数(统计)
max() 最大
min() 最小
avg() 平均
sum() 总和
concat() 用于连接字符串
count() 计数(统计)
mysql> select count(*) from employee; 统计有表中有多少条记录
±---------+
| count(*) |
±---------+
| 10 |
±---------+
1 row in set (0.00 sec)
mysql> SELECT COUNT(*) FROM employee WHERE post=‘hr’; 统计表中字段post是hr的有多少条记录
±---------+
| COUNT(*) |
±---------+
| 2 |
±---------+
1 row in set (0.00 sec)
mysql> select count(distinct salary) from employee; 统计薪资不重复的有多少个?
±-----------------------+
| count(distinct salary) |
±-----------------------+
| 8 |
±-----------------------+
1 row in set (0.00 sec)
max() 最大(如是数字比大小,如果字母比开头字母)
mysql> select max(salary) from employee; 查找salary最大的记录
±------------+
| max(salary) |
±------------+
| 20000.00 |
±------------+
1 row in set (0.00 sec)
min() 最小(如是数字比大小,如果字母比开头字母)
mysql> select min(salary) from employee;
±------------+
| min(salary) |
±------------+
| 600.00 |
±------------+
1 row in set (0.00 sec)
avg() 平均
mysql> select avg(salary) from employee;
±------------+
| avg(salary) |
±------------+
| 5890.000000 |
±------------+
1 row in set (0.00 sec)
mysql> select sum(salary) from employee;
±------------+
| sum(salary) |
±------------+
| 58900.00 |
±------------+
1 row in set (0.00 sec)
sum() 总和
mysql> select sum(salary) from employee;
±------------+
| sum(salary) |
±------------+
| 58900.00 |
±------------+
1 row in set (0.00 sec)
mysql> SELECT SUM(salary) FROM employee WHERE dep_id=102;
±------------+
| SUM(salary) |
±------------+
| 26600.00 |
±------------+
1 row in set (0.00 sec)
**模糊查询(通配符) **
_ 任意单个字符(不包括零个字符) % 所有字符,注意与*的区别
mysql> select name,salary from employee5 where name like ‘al___’;
mysql> select * from employee5 where name like ‘al%’;
mysql> select name,sex,salary from employee where name like ‘to_’;
±-----±-----±--------+
| name | sex | salary |
±-----±-----±--------+
| tom | male | 5500.00 |
±-----±-----±--------+
1 row in set (0.00 sec)
mysql> select name,sex,salary from employee where name like ‘%a%’;
±------±-------±---------+
| name | sex | salary |
±------±-------±---------+
| jack | male | 5000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
±------±-------±---------+
5 rows in set (0.00 sec)
正则查询(REGEXP):regular expression
mysql> select name,sex,salary from employee where name regexp ‘^j’; j开头
±-----±-----±--------+
| name | sex | salary |
±-----±-----±--------+
| jack | male | 5000.00 |
±-----±-----±--------+
1 row in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘u$’; u开头
±-------±-----±--------+
| name | sex | salary |
±-------±-----±--------+
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±-------±-----±--------+
2 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘^a|k$’;a开头或k结尾
±------±-------±--------+
| name | sex | salary |
±------±-------±--------+
| jack | male | 5000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
±------±-------±--------+
3 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘r{2}’; r连续出现2次
±------±-----±--------+
| name | sex | salary |
±------±-----±--------+
| harry | male | 6000.00 |
±------±-----±--------+
1 row in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘m+’; m出现至少一次
±-----±-------±---------+
| name | sex | salary |
±-----±-------±---------+
| tom | male | 5500.00 |
| emma | female | 20000.00 |
±-----±-------±---------+
2 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘[^tom]’;除tom字段以外
±----------±-------±---------+
| name | sex | salary |
±----------±-------±---------+
| jack | male | 5000.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±----------±-------±---------+
9 rows in set (0.00 sec)
mysql> select name,sex,salary from employee where name regexp ‘.*’; 任意字符串
±----------±-------±---------+
| name | sex | salary |
±----------±-------±---------+
| jack | male | 5000.00 |
| tom | male | 5500.00 |
| robin | male | 8000.00 |
| alice | female | 7200.00 |
| Alan | male | 600.00 |
| harry | male | 6000.00 |
| emma | female | 20000.00 |
| christine | female | 2200.00 |
| zhuzhu | male | 2200.00 |
| gougou | male | 2200.00 |
±----------±-------±---------+
10 rows in set (0.00 sec)
子查询
子查询是将一个查询语句嵌套在另一个查询语句中。
内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN、EXISTS 和 NOT EXISTS等关键字
还可以包含比较运算符:= 、 !=、> 、<等
子查询的主要优点是:
• 它们允许结构化的查询,以便可以隔离语句的每个部分。
• 它们提供了执行操作的替代方法,否则这些操作将需要复杂的联接和联合。
• 子查询比复杂的联接或联合更易读。
mysql> select name,sex,salary from employee where salary=(select max(salary) from employee);
±-----±-------±---------+
| name | sex | salary |
±-----±-------±---------+
| emma | female | 20000.00 |
±-----±-------±---------+
1 row in set (0.00 sec)
mysql> select name,sex,salary from employee where salary=20000;
±-----±-------±---------+
| name | sex | salary |
±-----±-------±---------+
| emma | female | 20000.00 |
±-----±-------±---------+
1 row in set (0.01 sec)
分组查询
GROUP BY和GROUP_CONCAT()函数一起使用
SELECT dep_id,GROUP_CONCAT(name) FROM employee GROUP BY dep_id;
SELECT dep_id,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY dep_id;
GROUP BY:以什么条件分组
GROUP_CONCAT:分组后的数据,显示那个字段
以sex做为分组,分组后显示job_description的信息
mysql> select sex,group_concat(job_description) from employee group by sex;
±-------±------------------------------+
| sex | group_concat(job_description) |
±-------±------------------------------+
| male | teach,teach,teach,hrcc, |
| female | teach,salecc,salecc |
±-------±------------------------------+
2 rows in set (0.01 sec)
mysql> select name,sex,job_description from employee;
±----------±-------±----------------+
| name | sex | job_description |
±----------±-------±----------------+
| jack | male | teach |
| tom | male | teach |
| robin | male | teach |
| alice | female | teach |
| Alan | male | hrcc |
| harry | male | NULL |
| emma | female | salecc |
| christine | female | salecc |
| zhuzhu | male | NULL |
| gougou | male | |
±----------±-------±----------------+
10 rows in set (0.00 sec)
笛卡尔积原理
内链接
外链接 (左连接,右连接)
多表连接查询
复合条件连接查询
子查询
内链接
内连接(inner join):inner join(等值连接) 只返回两个表中联结字段相等的行
select a表字段1,a表字段2,… ,b表字段1,b表字段2,… from a表 as 别名 inner join b表 as 别名
(where/on) a表字段=b表字段;
mysql> select * from employee1;
±-------±---------±-----±-------+
| emp_id | emp_name | age | dep_id |
±-------±---------±-----±-------+
| 1 | jim | 19 | 200 |
| 2 | tom | 20 | 201 |
| 3 | jack | 25 | 201 |
| 4 | alice | 26 | 202 |
| 5 | robin | 40 | 200 |
| 6 | natasha | 28 | 204 |
±-------±---------±-----±-------+
6 rows in set (0.00 sec)
mysql> select * from department1;
±-------±---------+
| dep_id | dep_name |
±-------±---------+
| 200 | hr |
| 201 | it |
| 202 | sale |
| 203 | fd |
±-------±---------+
4 rows in set (0.00 sec)
mysql> select emp_name,age,dep_name from employee1,department1 where
employee1.dep_id=department1.dep_id;
±---------±-----±-------±---------+
| emp_name | age | dep_id | dep_name |
±---------±-----±-------±---------+
| jim | 19 | 200 | hr |
| tom | 20 | 201 | it |
| jack | 25 | 201 | it |
| alice | 26 | 202 | sale |
| robin | 40 | 200 | hr |
±---------±-----±-------±---------+
5 rows in set (0.00 sec)
mysql> select emp_id, emp_name,age,dep_name from employee1 as einner join department1 as d where
e.dep_id=d.dep_id;
±-------±---------±-----±---------+
| emp_id | emp_name | age | dep_name |
±-------±---------±-----±---------+
| 1 | jim | 19 | hr |
| 2 | tom | 20 | it |
| 3 | jack | 25 | it |
| 4 | alice | 26 | sale |
| 5 | robin | 40 | hr |
±-------±---------±-----±---------+
5 rows in set (0.00 sec)
外链接
外连接左连接:left join(左联接) 返回包括左表中的所有记录和右表中联结字段相
等的记录
右连接:right join(右联接) 返回包括右表中的所有记录和左表中联结字段
相等的记录
外连接语法:
SELECT 字段列表
FROM 表1 LEFT|RIGHT JOIN表2ON表1.字段 = 表2.字段;左连接 left join mysql> select * from employee1;
±-------±---------±-----±-------+
| emp_id | emp_name | age | dep_id |
±-------±---------±-----±-------+
| 1 | jim | 19 | 200 |
| 2 | tom | 20 | 201 |
| 3 | jack | 25 | 201 |
| 4 | alice | 26 | 202 |
| 5 | robin | 40 | 200 |
| 6 | natasha | 28 | 204 |
±-------±---------±-----±-------+
6 rows in set (0.00 sec)
mysql> select * from department1;
±-------±---------+
| dep_id | dep_name |
±-------±---------+
| 200 | hr |
| 201 | it |
| 202 | sale |
| 203 | fd |
±-------±---------+
4 rows in set (0.00 sec)
mysql> select emp_id,emp_name,age,employee1.dep_id,dep_name from employee1 left join department1 on
employee1.dep_id=deepartment1.dep_id;
±-------±---------±-----±-------±---------+
| emp_id | emp_name | age | dep_id | dep_name |
±-------±---------±-----±-------±---------+
| 1 | jim | 19 | 200 | hr |
| 5 | robin | 40 | 200 | hr |
| 2 | tom | 20 | 201 | it |
| 3 | jack | 25 | 201 | it |
| 4 | alice | 26 | 202 | sale |
| 6 | natasha | 28 | 204 | NULL |
±-------±---------±-----±-------±---------+
6 rows in set (0.01 sec)
mysql> select emp_name,age,employee1.dep_id,dep_name from employee1 left join department1 on
employee1.dep_id=department1.dep_id where department1.dep_id is null;
±---------±-----±-------±---------+
| emp_name | age | dep_id | dep_name |
±---------±-----±-------±---------+
| natasha | 28 | 204 | NULL |
±---------±-----±-------±---------+
1 row in set (0.00 sec)
右链接:right join
mysql> select emp_id,emp_name,age,employee1.dep_id,dep_name from employee1 right join department1 on
employee1.dep_id=ddepartment1.dep_id;
±-------±---------±-----±-------±---------+
| emp_id | emp_name | age | dep_id | dep_name |
±-------±---------±-----±-------±---------+
| 1 | jim | 19 | 200 | hr |
| 2 | tom | 20 | 201 | it |
| 3 | jack | 25 | 201 | it |
| 4 | alice | 26 | 202 | sale |
| 5 | robin | 40 | 200 | hr |
| NULL | NULL | NULL | NULL| fd |
±-------±---------±-----±-------±---------+
6 rows in set (0.00 sec)
mysql> select emp_name,age,employee1.dep_id,dep_name from employee1 right join department1 on
employee1.dep_id=department1.dep_id where employee1.dep_id is null;
±---------±-----±-------±---------+
| emp_name | age | dep_id | dep_name |
±---------±-----±-------±---------+
| NULL | NULL | NULL | fd |
±---------±-----±-------±---------+
1 row in set (0.00 sec)
复合连接查询
复合条件连接查询示例1:以内连接的方式查询employee1和department1表,并且employee1表中的age字段值必须大于25 找出公司所有部门中,年龄大于25岁的员工
mysql> select emp_name,age,dep_name from employee1 inner join department1 where employee1.dep_id=department1.dep_id ;
+----------+------+----------+
| emp_name | age | dep_name |
+----------+------+----------+
| jim | 19 | hr |
| tom | 20 | it |
| jack | 25 | it |
| alice | 26 | sale |
| robin | 40 | hr |
+----------+------+----------+
5 rows in set (0.00 sec)
mysql> select emp_name,age,dep_name from employee1 inner join department1 where employee1.dep_id=department1.dep_id and age>25;
+----------+------+----------+
| emp_name | age | dep_name |
+----------+------+----------+
| robin | 40 | hr |
| alice | 26 | sale |
+----------+------+----------+
2 rows in set (0.00 sec)
mysql> select emp_name,age,dep_name from employee1 inner join department1 where employee1.dep_id=department1.dep_id order by age asc;
+----------+------+----------+
| emp_name | age | dep_name |
+----------+------+----------+
| jim | 19 | hr |
| tom | 20 | it |
| jack | 25 | it |
| alice | 26 | sale |
| robin | 40 | hr |
+----------+------+----------+
5 rows in set (0.00 sec)
子查询
子查询子查询是将一个查询语句嵌套在另一个查询语句中。
内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN、EXISTS 和 NOT EXISTS等关键字
还可以包含比较运算符:= 、 !=、> 、<等
子查询的主要优点是:• 它们允许结构化的查询,以便可以隔离语句的每个部分。• 它们提供了执行操作的替代方法,否则这些操作将需要复杂的联接和联合。• 子查询比复杂的联接或联合更易读。1.带in关建字的子查询查询employee表,但dept_id必须在department表中出现过
mysql> select * from employee1 where dep_id in (select dep_id from department1);
+--------+----------+------+--------+
| emp_id | emp_name | age | dep_id |
+--------+----------+------+--------+
| 1 | jim | 19 | 200 |
| 2 | tom | 20 | 201 |
| 3 | jack | 25 | 201 |
| 4 | alice | 26 | 202 |
| 5 | robin | 40 | 200 |
+--------+----------+------+--------+
5 rows in set (2.37 sec)
mysql> select dep_id from department1;
+--------+
| dep_id |
+--------+
| 200 |
| 201 |
| 202 |
| 203 |
+--------+
4 rows in set (0.00 sec)
mysql> select * from department1 where dep_id in (200,201,202,203);
+--------+----------+
| dep_id | dep_name |
+--------+----------+
| 200 | hr |
| 201 | it |
| 202 | sale |
| 203 | fd |
+--------+----------+
4 rows in set (0.00 sec)
带比较运算符的子查询
=、!=、>、>=、<、<=、<>
查询年龄大于等于25岁员工所在部门(查询老龄化的部门)
注意:department1表中的dep_id 必须在employee1表中出现过
mysql> select * from department1 where dep_id in (select distinct dep_id from employee1 where age>=25);
+--------+----------+
| dep_id | dep_name |
+--------+----------+
| 201 | it |
| 202 | sale |
| 200 | hr |
+--------+----------+
3 rows in set (0.00 sec)
Ture或False,当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
mysql> select emp_name,age,dep_id from employee1 where exists (select * from department1 where
dep_id=500);
Empty set (0.00 sec)
mysql> select emp_name,age,dep_id from employee1 where not exists (select * from department1 where
dep_id=500);
+----------+------+--------+
| emp_name | age | dep_id |
+----------+------+--------+
| jim | 19 | 200 |
| tom | 20 | 201 |
| jack | 25 | 201 |
| alice | 26 | 202 |
| robin | 40 | 200 |
| natasha | 28 | 204 |
+----------+------+--------+
6 rows in set (0.00 sec)
MySQL索引========================================================
创建索引
创建表时创建索引
CREATE在已存在的表上创建索引
ALTER TABLE在已存在的表上创建索引
查看并测试索引
删除索引
索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,
尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。
索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。
索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。
MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制,通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能
普通索引
唯一索引
全文索引
单列索引
多列索引
空间索引
===创建表时
语法:help create table;
CREATE TABLE 表名 (字段名1 数据类型 [完整性约束条件…],
字段名2 数据类型 [完整性约束条件…],
[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[索引名] (字段名[(长度)] [ASC |DESC])
);
创建普通索引示例:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值
和空值,纯粹为了查询数据更快一点。
CREATE TABLE department10 (dept_id INT,
dept_name VARCHAR(30) ,
comment VARCHAR(50),
INDEXindex_dept_name (dept_name)
);
创建唯一索引示例:索引列中的值必须是唯一的,但是允许为空值CREATE TABLE department11 (dept_id INT,
dept_name VARCHAR(30) ,
comment VARCHAR(50),
UNIQUE INDEX index_dept_name (dept_name)
);
创建全文索引示例:全文索引,只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类
型字段上使用全文索引;用全文索引去某个列查一个字符串,返回匹配度,匹配关健字.
CREATE TABLE department12 (dept_id INT,
dept_name VARCHAR(30) ,
comment VARCHAR(50),
log text,
FULLTEXT INDEXindex_log (log)
);
创建多列索引示例:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左
边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合
CREATE TABLE department13 (dept_id INT,
dept_name VARCHAR(30) ,
comment VARCHAR(50),
INDEXindex_dept_name_comment (dept_name, comment)
);
===CREATE在已存在的表上创建索引
语法:
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名 ON 表名 (字段名[(长度)] [ASC |DESC]) ;
创建普通索引示例:CREATE INDEX index_dept_name ON department (dept_name);
创建唯一索引示例:CREATE UNIQUE INDEX index_dept_name ON department (dept_name);
例:mysql> desc t3;
±------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±------------±-----±----±--------±------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
±------±------------±-----±----±--------±------+
3 rows in set (0.01 sec
mysql> select * from t3;
±-----±-----±-----+
| id | name | age |
±-----±-----±-----+
| 1 | jim | 18 |
| 2 | tom | 19 |
| 3 | jack | 20 |
±-----±-----±-----+
3 rows in set (0.00 sec)
mysql> create unique index index_age on t3 (age);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t3 \G;
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE t3
(
id
int(11) DEFAULT NULL,
name
varchar(20) DEFAULT NULL,
age
int(11) DEFAULT NULL,
UNIQUE KEY index_age
(age
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> insert into t3 values(4,‘lucy’,18); 唯一索引必须是唯一的不能有相同的值(空值除外)。
ERROR 1062 (23000): Duplicate entry ‘18’ for key ‘index_age’
创建全文索引示例:CREATE FULLTEXT INDEX index_dept_name ON department (dept_name);例:
mysql> create FULLTEXT index index_name on t3 (name);
mysql> show create table t3\G;
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE t3
(
id
int(11) DEFAULT NULL,
name
varchar(20) DEFAULT NULL,
age
int(11) DEFAULT NULL,
UNIQUE KEY index_age
(age
),
FULLTEXT KEY index_name
(name
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
show engines\G; 查看数据库当前默认引擎
mysql> show engines\G;
*************************** 1. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 5. row ***************************
Engine: MyISAMSupport: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
mysql> create FULLTEXT index index_id on t3 (id); 只能对char 、varchar、text数据类型设置全文索引
ERROR 1283 (HY000): Column ‘id’ cannot be part of FULLTEXT index
创建多列索引示例:CREATE INDEXindex_dept_name_ comment ON department (dept_name, comment);例:
mysql> create index index_id_name on t3 (id,name);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t3\G;
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE t3
(
id
int(11) DEFAULT NULL,
name
varchar(20) DEFAULT NULL,
age
int(11) DEFAULT NULL,
KEY index_id_name
(id
,name
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
===ALTER TABLE在已存在的表上创建索引
语法:help alter table
ALTER TABLE 表名ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX索引名 (字段名[(长度)] [ASC |DESC]) ;
创建普通索引示例:ALTER TABLE department ADD INDEXindex_dept_name (dept_name);
创建唯一索引示例:ALTER TABLE department ADD UNIQUE INDEX index_dept_name (dept_name);
创建全文索引示例:ALTER TABLE department ADD FULLTEXT INDEX index_dept_name (dept_name);
创建多列索引示例:ALTER TABLE department ADDINDEX index_dept_name_comment (dept_name,comment);
**查看索引 **
SHOW CRETAE TABLE 表名\G
测试示例
EXPLAIN SELECT * FROM department WHERE dept_name=‘hr’;
**删除索引 **
show create table employee6;
DROP INDEX 索引名 ON 表名;
索引测试实验
mysql> create table school.t2(id int,name varchar(30));
Query OK, 0 rows affected (1.33 sec)
mysql> desc school.t2;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(30) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> delimiter $$
mysql> create procedure autoinsert1()
-> BEGIN
-> declare i int default 1;
-> while(i<100000)do
-> insert into school.t2 values(i,'ccc');
-> set i=i+1;
-> end while;
-> END$$
mysql> use school
Database changed
mysql> delimiter ;
mysql> call autoinsert1();
未创建索引
mysql> explain select * from school.t2 where id=20000;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 44848 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)
mysql> create index index_id on school.t2(id);
Query OK, 0 rows affected (0.91 sec)
Records: 0 Duplicates: 0 Warnings作用: 0
mysql> explain select * from school.t2 where id=20000;
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | t2 | ref | index_id | index_id | 5 | const | 1 | Using where |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)
id:查询序列号。表示查询中执行 select 子句或操作表的顺序,id 值越大优先级越高,越先被执行。id 相同,执行
顺序由上至下。
select_type:查询类型
table:输出行所引用的表
possible_keys:指出 MySQL 能在该表中使用哪些索引有助于查询。如果为空,说明没有可用的索引
key:MySQL 实际从 possible_key 选择使用的索引。
key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref:显示索引的哪一列被使用了
rows:MYSQL 认为必须检查的用来返回请求数据的d行数
33
SHOW CREATE TABLE 表名\G
EXPLAIN:命令的作用是查看查询优化器如何决定执行查询
花费时间比较:
创建索引前
mysql> select * from school.t2 where id=20000;
±------±-----+
| id | name |
±------±-----+
| 20000 | ccc |
±------±-----+
1 row in set (0.03 sec)
创建索引后
mysql> create index index_id on school.t2(id);
Query OK, 0 rows affected (0.39 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from school.t2 where id=20000;
±------±-----+
| id | name |
±------±-----+
| 20000 | ccc |
±------±-----+
1 row in set (0.00 sec)
========================================================
MySQL安全机制 DDL DCL
========================================================
MySQL权限表
MySQL用户管理
MySQL权限管理
SSL加密连接
user:全局授权
db:库级授权
tables_priv:表级授权
columns_priv:列级授权
procs_priv:存储与函数授权
proxies_priv:代理授权
示例:
mysql -h192.168.5.240 -P 3306 -u root -p123 mysql -e ‘select user,host from user’
-h指定主机名【默认为localhost】
【默认3306】
-PMySQL服务器端口 -u
-p
指定用户名
指定登录密码
此处mysql为指定登录的数据库
【默认root】【默认为空密码】 -e接SQL语句(非交互访问)2. 创建用户(结合help理解)
方法一:CREATE USER语句创建
create user 用户名@‘主机192.168.1.131’ IDENTIFIED BY ‘密码’;
mysql> create user ‘mysql2’@‘192.168.10.%’; 给192.168.10.0/24的所有网段授权一个账户CREATE USER user1@’localhost’ IDENTIFIED BY ‘123456’;mysql> select user,host from mysql.user;查看mysql所有用户mysql>show create user ‘用户名’@‘ip’ 查看创建的用户信息方法二:GRANT语句创建(建议使用这一种方法!~)
grant 权限 on 库名.表名 to 用户@‘主机’ IDENTIFIED BY ‘授权密码(随便写)’
‘up1806’@‘192.168.1.%’
mysql> grant all on . to ‘u1’@’%’ identified by ‘123’;Query OK, 0 rows affected, 1 warning (0.00 sec)mysql> grant select on . to ‘u2’@’%’ identified by ‘1’;Query OK, 0 rows affected, 1 warning (0.01 sec)mysql>FLUSH PRIVILEGES;(更新)或者重启一下服务器
flush privileges;
上边两步一般一起使用!mysql> select * from mysql.user where user=‘u1’\G; 查看用户的权限列表
*************************** 1. row ***************************
Host: %
User: u1
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Reload_priv: Y
Shutdown_priv: Y
Process_priv: Y
File_priv: Y
Grant_priv: N
References_priv: Y
Index_priv: Y
Alter_priv: Y
Show_db_priv: Y
Super_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Execute_priv: Y
Repl_slave_priv: Y
Repl_client_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: Y
Create_user_priv: Y
Event_priv: Y
Trigger_priv: Y
Create_tablespace_priv: Y
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257
password_expired: N
password_last_changed: 2020-07-16 17:31:08
password_lifetime: NULL
account_locked: N
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select * from mysql.user where user=‘u2’\G;
*************************** 1. row ***************************
Host: %
User: u2
Select_priv: Y
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string: *E6CC90B878B948C35E92B003C792C46C58C4AF40
password_expired: N
password_last_changed: 2020-07-16 17:34:09
password_lifetime: NULL
account_locked: N
1 row in set (0.00 sec)
ERROR:
No query specified
==============================================================
DROP USER语句删除
DROP USER ‘user1’@’localhost’;
权限应用的顺序:
user(Y|N)>db>tables_priv==>columns_priv
语法格式:
grant 权限列表 on 库名.表名 to ‘用户名’@‘客户端主机’ [identified by ‘密码’ with option参数];
==权限列表all 所有权限(不包括授权权限)select,update ==数据库.表名*.*所有库下的所有表
web.* web库下的所有表
Global levelDatabase levelweb.stu_info web库下的stu_info表Table levelSELECT (col1), INSERT (col1,col2) ON mydb.mytbl Columnlevel==客户端主机 %所有主机
192.168.2.% 192.168.2.0网段的所有主机
192.168.2.168 指定主机
localhost 指定主机
with_option参数(选择性掌握)
GRANT OPTION:
MAX_QUERIES_PER_HOUR:
MAX_UPDATES_PER_HOUR:
MAX_CONNECTIONS_PER_HOUR:
MAX_USER_CONNECTIONS:
授权选项
定义每小时允许执行的查询数
定义每小时允许执行的更新数
定义每小时可以建立的连接数
定义单个用户同时可以建立的连接数Grant示例:
GRANT ALL ON . TO admin1@’%’ IDENTIFIED BY ‘(123)’;
GRANT ALL ON . TO admin2@’%’ IDENTIFIED BY ‘(123)’ WITH GRANT OPTION;(赋予授权权限)GRANT ALL ON bbs.* TO admin3@’%’ IDENTIFIED BY ‘(123)’;
GRANT ALL ON bbs.* TO admin3@‘192.168.122.220’ IDENTIFIED BY ‘(123)’;(最常用,并且安全)
GRANT ALL ON bbs.user TO admin4@’%’ IDENTIFIED BY ‘(123)’; GRANT SELECT(col1),INSERT(col2,col3) ON bbs.user TO admin5@’%’ IDENTIFIED BY ‘(123)’;回收权限REVOKE
查看权限
SHOW GRANTS\G
SHOW GRANTS FOR 用户名@‘登陆IP’\G
回收权限REVOKE语法:
REVOKE 权限列表 ON 数据库名 FROM用户名@‘客户端主机’
示例:
REVOKE DELETE ON . FROM admin1@’%’; //回收部分权限
REVOKE ALL PRIVILEGES ON . FROM admin2@’%’; //回收所有权限
REVOKE ALL PRIVILEGES,GRANT OPTION ON . FROM ‘admin2’@’%’;PRIVILEGES:特权删除用户:
5.6 revoke all privilege drop user
5.7 drop user
查看给那些用户了权限:
mysql>show grants;
mysql>show grants for ‘用户名’; 查看指定用户的权限.