mysql实践一:SQL基础

mysql简介

mysql是有名的开放源代码关系型数据库。它最早是AB公司开源的,后来到Sun公司手中。之后Sun公司被Oracle公司收购,mysql就归Oracle所有。从此mysql走向商业化,又有名为mariadb数据库作为mysql的分支被开源,之后mysql又出了社区版和企业版。mysql大致的历史就这样,更详细的可以百度,这里不多展开。

对于开发者来说,数据库是绕不开的一门技术,所有mysql这个有名,使用又频繁的开源数据库当然又学习的必要。

mysql的安装

mysql的安装可以是源代码编译安装,或者是在mysql的官网直接下载二进制文件,然后安装。当然,在容器技术这么火的2019,直接在docker上安装并使用mysql对开发者来说更合适。

先准备一台CentOS7虚拟机,安装docker。直接下载mysql镜像:

docker pull mysql:5.7

如果因为是在国内使用安装慢,可以使用阿里云的镜像加速。

然后启动mysql镜像

docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

默认mysql数据库root用户的登陆密码为123456,。本机使用mysql命令登陆,未安装可以使用yum命令安装:

yum install -y mysql

使用mysql命令登陆:

mysql -uroot -p123456 -h 127.0.0.1

SQL简介

SQL全称为Structure Query Language(结构化查询语言),它是使用关系型模型的数据库应用语言。SQL语句主要分为三类:

  • DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象。常用的语句关键字主要包括create、drop、alter等。
  • DML(Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性。常用的语句关键字主要包括insert、delete、update和select等。
  • DCL(Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。

注:SQL语句中的 ; 或者 \g 都是语句的结束符。\G 表示行显示输出。

DDL语句

DDL是针对数据库内部的对象进行创建、删除、修改等操作,一般是数据库管理员(DBA)来使用。我们看列举常用的DDL语句。

创建数据库

创建数据库使用的命令为:

1CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name 2 [create_specification] ... 3 4create_specification: 5 [DEFAULT] CHARACTER SET [=] charset_name 6 | [DEFAULT] COLLATE [=] collation_name

例如创建一个名为test的数据库:

1MySQL [(none)]> CREATE DATABASE test DEFAULT CHARSET utf8; 2Query OK, 1 row affected (0.00 sec)

注:mysql中sql是不区别大小写的,所以上面的命令等同于 create database test default charset utf8;

选择数据库

创建数据库之后,就可以针对对应的数据库进行操作了,使用命令为:

USE dbname

例如使用数据库test:

1MySQL [(none)]> use test; 2Database changed 3MySQL [test]>

可以看到[]内的内容变成test数据库的名称了。

删除数据库

创建数据库对应的就是删除数据库了,命令为:

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

例如查看test数据库:

1MySQL [test]> drop database if exists test; 2Query OK, 0 rows affected (0.00 sec) 3 4MySQL [(none)]>

注:数据库删除后,下面的所有表数据都会全部删除,所以在删除前需要检查并备份。

查看所有数据库

命令为:

1SHOW DATABASES 2 3 4MySQL [(none)]> show databases; 5+--------------------+ 6| Database | 7+--------------------+ 8| information_schema | 9| mysql | 10| performance_schema | 11| sys | 12+--------------------+

创建表

在数据库中创建一张表的语法如下:

1CREATE TABLE [IF NOT EXISTS] tablename ( 2column_name_1 column_type_1 constraints, 3column_name_2 column_type_2 constraints, 4... 5column_name_n column_type_n constraints 6);

例如创建一张user表,包含字段id,name,age。

1MySQL [test]> create table if not exists user ( 2 -> id int(11) primary key, 3 -> name varchar(32) not null, 4 -> age int(11) 5 -> );

注:创建表之前需要先选择数据库。

查看所有表

同样也是使用show

SHOW tables

例如:查看test数据库下的所有表

1MySQL [test]> show tables; 2+----------------+ 3| Tables_in_test | 4+----------------+ 5| user | 6+----------------+ 71 row in set (0.00 sec)

查看表结构

查看表结构命令为:

DESC tablename

例如查看之前创建的user的结构。

1MySQL [test]> desc user; 2+-------+-------------+------+-----+---------+-------+ 3| Field | Type | Null | Key | Default | Extra | 4+-------+-------------+------+-----+---------+-------+ 5| id | int(11) | NO | PRI | NULL | | 6| name | varchar(32) | NO | | NULL | | 7| age | int(11) | YES | | NULL | | 8+-------+-------------+------+-----+---------+-------+ 93 rows in set (0.00 sec)

和这个命令相似功能的命令是show create table tbname:

1MySQL [test]> show create table user\G; 2*************************** 1. row *************************** 3 Table: user 4Create Table: CREATE TABLE `user` ( 5 `id` int(11) NOT NULL, 6 `name` varchar(32) NOT NULL, 7 `age` int(11) DEFAULT NULL, 8 PRIMARY KEY (`id`) 9) ENGINE=InnoDB DEFAULT CHARSET=utf8 101 row in set (0.00 sec) 11 12ERROR: No query specified

删除表

表的删除命令如下:

DROP TABLE [IF EXISTS] tablename

例如:删除之前创建的user表:

1MySQL [test]> drop table if exists user; 2Query OK, 0 rows affected (0.00 sec)

修改表

修改表使用关键字alter。它修改的内容可以是修改表的字段类型,还可以添加删除表字段。

1.修改表类型:

ALTER TABLE tablename MODIFY [COLUMN] column_definition [FIRST|ALTER col_name]

例如:修改user表的name字段,将varchar(32)修改为varchar(64)

1MySQL [test]> alter table user modify name varchar(64); 2Query OK, 0 rows affected (0.11 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+-------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+-------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| name | varchar(64) | YES | | NULL | | 11| age | int(11) | YES | | NULL | | 12+-------+-------------+------+-----+---------+-------+ 133 rows in set (0.00 sec)

2.添加表字段

ALTER TABLE tbname ADD [COLUMN] column_definition [FIRST|ALTER col_name]

例如:user中添加一个字段,名为email,类型是varchar(64)

1MySQL [test]> alter table `user` add `email` varchar(64) not null; 2Query OK, 0 rows affected (0.34 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+-------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+-------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| name | varchar(64) | YES | | NULL | | 11| age | int(11) | YES | | NULL | | 12| email | varchar(64) | NO | | NULL | | 13+-------+-------------+------+-----+---------+-------+ 144 rows in set (0.00 sec)

3.删除表字段

语法如下:

ALTER TABLE tablename DROP [COLUMN] col_name

例如:删除user中的email字段

1MySQL [test]> alter table `user` drop `email`; 2Query OK, 0 rows affected (0.02 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+-------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+-------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| name | varchar(64) | YES | | NULL | | 11| age | int(11) | YES | | NULL | | 12+-------+-------------+------+-----+---------+-------+ 133 rows in set (0.00 sec)

4.字段改名

语法如下:

ALTER TABLE tablename CHANGE [COLUMN] old_col_name column_definition [FIRST|ALTER col_name]

例如:将name改名为username,类型为varchar(32):

1MySQL [test]> alter table `user` change `name` `username` varchar(32); 2Query OK, 0 rows affected (0.00 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+----------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+----------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| username | varchar(32) | YES | | NULL | | 11| age | int(11) | YES | | NULL | | 12+----------+-------------+------+-----+---------+-------+ 133 rows in set (0.00 sec)

注:change 和 modify 都可以修改表的定义,不同的是 change 后面需要写两次列名,不方便。但 change 可以改名,modify 则不能。

5.修改字段排列顺序。

修改字段的关键字ADD、CHNAGE、MODIFY中都支持可选项first|after,用于修改字段的位置。

例如:新增一个字段email,并置于username字段之前:

1MySQL [test]> alter table `user` add `email` varchar(64) after `id`; 2Query OK, 0 rows affected (0.00 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+----------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+----------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| email | varchar(64) | YES | | NULL | | 11| username | varchar(32) | YES | | NULL | | 12| age | int(11) | YES | | NULL | | 13+----------+-------------

例如:修改字段email在username字段之后:

1MySQL [test]> alter table `user` modify `email` varchar(64) after `username`; 2Query OK, 0 rows affected (0.01 sec) 3Records: 0 Duplicates: 0 Warnings: 0 4 5MySQL [test]> desc user; 6+----------+-------------+------+-----+---------+-------+ 7| Field | Type | Null | Key | Default | Extra | 8+----------+-------------+------+-----+---------+-------+ 9| id | int(11) | NO | PRI | NULL | | 10| username | varchar(32) | YES | | NULL | | 11| email | varchar(64) | YES | | NULL | | 12| age | int(11) | YES | | NULL | | 13+----------+-------------+------+-----+---------+-------+ 144 rows in set (0.00 sec)

注:CHNAGE|FIRST|ALTER 这些关键字都属于MySQL在标准SQL上的扩展,在其他数据库上不一定适用。

6.修改表名

语法如下:

ALTER TABLE tablename RENAME [TO] new_name  

例如:将表user修改为tb_user:

1MySQL [test]> alter table `user` rename `tb_user`; 2Query OK, 0 rows affected (0.00 sec) 3 4MySQL [test]> desc tb_user; 5+----------+-------------+------+-----+---------+-------+ 6| Field | Type | Null | Key | Default | Extra | 7+----------+-------------+------+-----+---------+-------+ 8| id | int(11) | NO | PRI | NULL | | 9| username | varchar(32) | YES | | NULL | | 10| email | varchar(64) | YES | | NULL | | 11| age | int(11) | YES | | NULL | | 12+----------+-------------+------+-----+---------+-------+ 134 rows in set (0.01 sec)

DML语句

DML语句为数据库表的操作语句,可以对数据库表的内容做增(insert)、删(delete)、改(update)、查(select)操作。

插入记录

表创建完毕后就往表中插入记录了,语法如下:

INSERT INTO tablename (field1,field2,field3,...,fieldn) VALUES (value1,value2,value3,...,valuen)

例如:在user表中插入一条记录,id为1,name为xiaoming,age为20:

1MySQL [test]> insert into `user` (`id`,`name`,`age`) values (1,'xiaoming',20); 2Query OK, 1 row affected (0.01 sec) 3 4MySQL [test]> select id, name, age from `user`; 5+----+----------+------+ 6| id | name | age | 7+----+----------+------+ 8| 1 | xiaoming | 20 | 9+----+----------+------+ 101 row in set (0.00 sec)

注:如果表中的字段类型设置了初始值,那插入时可以不指定该字段的值,这样它就以默认的值插入到表中。

select是SQL查询操作的关键字,之后再说明。insert语句支持同时插入多条记录:

1INSERT INTO tablename (field1,field2,field3,...,fieldn) 2VALUES 3 (value1,value2,value3,...,valuen), 4 (value1,value2,value3,...,valuen) 5 ... 6 (value1,value2,value3,...,valuen);

例如:同时在user表中插入多条记录:

1MySQL [test]> insert into `user` (`id`,`name`,`age`) 2 -> values 3 -> (2,'John',40), 4 -> (3,'Lisa',18); 5Query OK, 2 rows affected (0.00 sec) 6Records: 2 Duplicates: 0 Warnings: 0 7 8MySQL [test]> select id, name, age from `user`; 9+----+----------+------+ 10| id | name | age | 11+----+----------+------+ 12| 1 | xiaoming | 20 | 13| 2 | John | 40 | 14| 3 | Lisa | 18 | 15+----+----------+------+ 163 rows in set (0.00 sec)

注:同时插入可以节省很多的网络开销,提高插入效率。

更新记录

更新表的记录语法如下:

UPDATE tablename SET field1=value1,field2=value2,...,fieldn=valuen [WHERE CONDITION]

例如:修改John的年龄为30:

1MySQL [test]> update `user` set age=30 where name='John'; 2Query OK, 1 row affected (0.00 sec) 3Rows matched: 1 Changed: 1 Warnings: 0 4 5MySQL [test]> select id, name, age from `user` where name='John'; 6+----+------+------+ 7| id | name | age | 8+----+------+------+ 9| 2 | John | 30 | 10+----+------+------+ 111 row in set (0.00 sec)

注:修改操作时需要使用关键字where指定条件,否则表中的所有记录的指定字段都会被修改。

UPDATE支持同时修改多个表的记录,语法如下:

UPDATE t1,t2,...tn SET t1.field1=value1,...,tn.fieldn=valuen [WHERE CONDITION]

删除记录

删除数据库表记录使用命令delete,语法如下:

DELETE FROM tablename [WHERE CONDITION]

例如:删除name为'xiaoming'的记录:

1MySQL [test]> delete from `user` where name='xiaoming'; 2Query OK, 1 row affected (0.00 sec) 3 4MySQL [test]> select * from user; 5+----+------+------+ 6| id | name | age | 7+----+------+------+ 8| 2 | John | 30 | 9| 3 | Lisa | 18 | 10+----+------+------+ 112 rows in set (0.00 sec)

同样的,删除操作也支持多表删除,语法如下:

DELETE t1,t2,...,tn FROM t1,t2,...,tn [WHERE CONDITION]

在进行多表操作时,为了简化SQL命令,可以给表添加别名。如果使用了别名,则在字段前也需要用别名表示该表。

注:删除时也一定要指定条件,不加where条件会删除表的所有记录。

查询记录

查询记录使用命令select,语法如下:

SELECT * FROM tablename [WHERE CONDITION]

例如:查询user表的所有记录:

1MySQL [test]> select * from user; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 2 | John | 30 | 6| 3 | Lisa | 18 | 7+----+------+------+ 82 rows in set (0.00 sec)

*表示输出所有的字段,所以上面的select命令等同于 select id, name, age from user。并且select命令也是使用最频繁的命令,它支持各种方式的查询。

1.查询去重。

使用关键字distinct对某一个字段的值去重。例如:字段name去重查询。

1MySQL [test]> select * from user; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 1 | John | 40 | 6| 2 | John | 30 | 7| 3 | Lisa | 18 | 8| 4 | Lisa | 18 | 9+----+------+------+ 104 rows in set (0.00 sec) 11 12MySQL [test]> select distinct name from user; 13+------+ 14| name | 15+------+ 16| John | 17| Lisa | 18+------+ 192 rows in set (0.00 sec)

2.条件查询。

用where关键字指定查询条件。例如:查询name为John且age为30的记录:

1MySQL [test]> select * from user where name='John' and age=30; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 2 | John | 30 | 6+----+------+------+ 71 row in set (0.01 sec)

使用and连接多个查询条件,也可以使用or表示查询满足多个条件中某个条件的记录。例如:查询name为John或id=3的记录:

1MySQL [test]> select * from user where name='John' or id=3; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 1 | John | 40 | 6| 2 | John | 30 | 7| 3 | Lisa | 18 | 8+----+------+------+ 93 rows in set (0.00 sec)

where后面的条件时一个表达式,支持各种运算符:>、<、>=、<=、!=。

3.排序

使用关键字ORDER BY可以对查询的记录进行排序,语法如下:

SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 [DESC|ASC], field2 [DESC|ASC],...,fieldn [DESC|ASC]

DESC和ASC是排序顺序的关键字,DESC表是按照字段进行降序排列,ASC则表示升序排列,默认为升序排列。如果有多个字段,则先对第一个字段排序,字段相同的情况下再根据第二个排序,依次类推。例如:按照age字段对user表的记录排序:

1MySQL [test]> select * from user order by age desc; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 1 | John | 40 | 6| 2 | John | 30 | 7| 3 | Lisa | 18 | 8| 4 | Lisa | 18 | 9+----+------+------+ 104 rows in set (0.00 sec) 11 12MySQL [test]> select * from user order by age asc; 13+----+------+------+ 14| id | name | age | 15+----+------+------+ 16| 3 | Lisa | 18 | 17| 4 | Lisa | 18 | 18| 2 | John | 30 | 19| 1 | John | 40 | 20+----+------+------+ 214 rows in set (0.01 sec)

4.限制和偏移

使用关键字OFFSETLIMIT限制查询记录的数量,已经查询的范围。语法如下:

SELECT * FROM LIMIT N OFFSET M

例如:查询user表的第一条记录:

1MySQL [test]> select * from user limit 2; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 1 | John | 40 | 6| 2 | John | 30 | 7+----+------+------+ 82 rows in set (0.00 sec)

例如:查询user表的第二条记录:

1MySQL [test]> select * from user limit 1 offset 1; 2+----+------+------+ 3| id | name | age | 4+----+------+------+ 5| 2 | John | 30 | 6+----+------+------+ 71 row in set (0.00 sec)

而且OFFSETLIMIT配合使用还能实现查询的分页效果:如查询user表的第2页,每页5条记录:

MySQL [test]> select * from user limit 5 offset 5;

注:limit属于MySQL扩展SQL92后的语法,在其他数据库上不一定通用。

5.聚合

聚合操作的语法如下:

1SELECT [field1,field2,...,fieldn] func_name 2FROM tablename 3[WHERE CONDITION] 4[GROUP BY field1,field2,...,fieldn] 5[WITH ROLLUP] 6[HAVING CONDITION]

其参数说明如下:

  • func_name 表示聚合函数,常用的有sum(求和)、count(*)(记录数)、max(最大值)、min(最小值)。
  • GROUP BY 关键字表示要进行分类聚合的字段。
  • WITH ROLLUP 表示是否对分类聚合后的结果进行再汇总。
  • HAVING 关键字表示对分类后的结果再进行条件的过滤。

注:having 和 where 都能对查询的数据进行条件过滤。但where是再聚合前就对记录进行过滤,having则是在聚合后再根据逻辑进行过滤。

例如:统计user表的记录数:

1MySQL [test]> select count(1) from user; 2+----------+ 3| count(1) | 4+----------+ 5| 4 | 6+----------+ 71 row in set (0.00 sec)

例如:在上面统计的基础上再统计各个性别的人数。

1MySQL [test]> select gender,count(1) from user group by gender; 2+--------+----------+ 3| gender | count(1) | 4+--------+----------+ 5| man | 2 | 6| woman | 2 | 7+--------+----------+ 82 rows in set (0.00 sec)

例如:再加上总人数

1MySQL [test]> select gender,count(1) from user group by gender with rollup; 2+--------+----------+ 3| gender | count(1) | 4+--------+----------+ 5| man | 2 | 6| woman | 2 | 7| NULL | 4 | 8+--------+----------+ 93 rows in set (0.00 sec)

例如:统计人数大于1的性别

1MySQL [test]> select gender,count(1) from user group by gender having count(1)>1; 2+--------+----------+ 3| gender | count(1) | 4+--------+----------+ 5| man | 2 | 6| woman | 2 | 7+--------+----------+ 82 rows in set (0.00 sec)

例如:统计user表的最大年龄,最小年龄,年龄总和。

1MySQL [test]> select max(age),min(age),sum(age) from user; 2+----------+----------+----------+ 3| max(age) | min(age) | sum(age) | 4+----------+----------+----------+ 5| 40 | 18 | 106 | 6+----------+----------+----------+ 71 row in set (0.00 sec)

6.表连接

当需要同时显示对各表的字段时,就可以使用表连接实现。表连接分为:

  • 内连接:语法 SELECT * FROM tb1 INNER JOIN tb2 ON CONDITION 。它会根据条件输出两张表中都匹配的记录,简单讲就是取交集。
  • 左连接:语法 SELECT * FROM tb1 LEFT JOIN tb2 ON CONDITION 。在多张表中以最左边的表为基础配置记录,如果其他表没有对应的记录,就留空。
  • 左连接:语法 SELECT * FROM tb1 RIGHT JOIN tb2 ON CONDITION 。它和左连接对应,在多张表中以最右边的表为基础配置记录,如果其他表没有对应的记录,就留空。右连接和左连接可以互相转化。

这里user(用户表)和role(角色表),其内容如下:

1MySQL [test]> select * from user; 2+----+------+--------+------+---------+ 3| id | name | gender | age | role_id | 4+----+------+--------+------+---------+ 5| 1 | Bob | man | 40 | 2 | 6| 2 | John | man | 30 | 1 | 7| 3 | Anna | woman | 18 | 3 | 8| 4 | Lisa | woman | 18 | NULL | 9+----+------+--------+------+---------+ 104 rows in set (0.00 sec) 11 12MySQL [test]> select * from role; 13+----+---------------+ 14| id | name | 15+----+---------------+ 16| 1 | administrator | 17| 2 | manager | 18| 3 | visitor | 19| 4 | unknow | 20+----+---------------+ 214 rows in set (0.00 sec)

例如:内连接方式查询user中对应的角色名称:

1MySQL [test]> select u.name,u.gender,u.age,r.name from user u inner join role r on u.role_id=r.id; 2+------+--------+------+---------------+ 3| name | gender | age | name | 4+------+--------+------+---------------+ 5| Bob | man | 40 | manager | 6| John | man | 30 | administrator | 7| Anna | woman | 18 | visitor | 8+------+--------+------+---------------+

例如:同样的需求用左连接实现:

1MySQL [test]> select u.name,u.gender,u.age,r.name from user u left join role r on u.role_id=r.id; 2+------+--------+------+---------------+ 3| name | gender | age | name | 4+------+--------+------+---------------+ 5| John | man | 30 | administrator | 6| Bob | man | 40 | manager | 7| Anna | woman | 18 | visitor | 8| Lisa | woman | 18 | NULL | 9+------+--------+------+---------------+ 104 rows in set (0.00 sec)

因为Lisa用户没有对应的角色id,所以显示NULL。 例如:以右连接方式实现:

1MySQL [test]> select u.name,u.gender,u.age,r.name from user u right join role r on u.role_id=r.id; 2+------+--------+------+---------------+ 3| name | gender | age | name | 4+------+--------+------+---------------+ 5| Bob | man | 40 | manager | 6| John | man | 30 | administrator | 7| Anna | woman | 18 | visitor | 8| NULL | NULL | NULL | unknow | 9+------+--------+------+---------------+ 104 rows in set (0.00 sec)

unknow角色没有查询到对应的用户,显示NULL。

7.子查询

在某些情况下,进行查询时需要的条件是另一个select语句的结果,这种情况就要用到子查询。用于子查询的关键字主要包括 in、not in、=、!=、exists、not exists、like、>、<等。语法如下:

1SELECT * FROM table_name 2WHERE CONDITION 3 SELECT * FROM table_name

例如:查询角色id为Manager或Administrator的用户:

1MySQL [test]> select * from user where role_id in (select id from role where name in ('manager','administrator')); 2+----+------+--------+------+---------+ 3| id | name | gender | age | role_id | 4+----+------+--------+------+---------+ 5| 1 | Bob | man | 40 | 2 | 6| 2 | John | man | 30 | 1 | 7+----+------+--------+------+---------+ 82 rows in set (0.00 sec)

上面的子查询可以用表连接实现:

1MySQL [test]> select u.name,u.gender,u.age,r.name from user u inner join role r where r.name in ('manager','administrator') and r.id=u.role_id; 2+------+--------+------+---------------+ 3| name | gender | age | name | 4+------+--------+------+---------------+ 5| Bob | man | 40 | manager | 6| John | man | 30 | administrator | 7+------+--------+------+---------------+ 82 rows in set (0.00 sec)

注:很多情况下表连接和子查询是可以互相转化的。而且很多情况下表连接查询效率优于子查询。

8.联合查询

当需要查询的数据散落在不同的表中,且表之间没有连接关系。语法如下:

1SELECT * FROM t1 2UNION | UNION ALL 3SELECT * FROM t2 4... 5UNION | UNION ALL 6SELECT * FROM tn

UNION 和 UNION ALL 的区别在于UNION会去点查询结果中的重复值,而UNION ALL则保留重复值。 例如:查询student表和user表中的人名:

1MySQL [test]> select id, name from user union select id,name from student; 2+----+------+ 3| id | name | 4+----+------+ 5| 1 | Bob | 6| 2 | John | 7| 3 | Anna | 8| 4 | Lisa | 9| 1 | Mark | 10| 2 | Li | 11+----+------+ 126 rows in set (0.00 sec)

DCL语句

DCL主要用于管理数据库的权限。语法如下:

GRANT PRI ON databasename.tablename TO 'user'@'ip' IDENTIFIED BY 'password'

例如:创建一个数据用户ks,具有对test数据库的所有表的select/insert权限:

1MySQL [test]> grant select,insert on test.* to 'ks'@'172.17.1.254' identified by '123'; 2Query OK, 0 rows affected, 2 warnings (0.00 sec) 3 4MySQL [test]> flush privileges; 5Query OK, 0 rows affected (0.00 sec)
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移