赞
踩
目录
· 查询当前数据库内所有表(前提是已通过USE指令使用该数据库)
以下内容学习自黑马程序员老师课程整理而来
针对数据库和表的一系列操作,包含查询、创建、删除等操作。
SHOW DATABASES;
SELECT DATABASE();
代码中[ ]部分都是可以省略的,看需求添加。IF NOT EXIISTS表示若要创建的这个数据库存在则不执行该创建操作,不存在才创建。DEFAULT CHARSET是编码方式,有两种选择,一种是我们常见的utf8,但这种编码方式最多只能支持3字节的字符编码,对于需要占据4字节的就不可以了,所以基本不用utf8可以忽略,需要使用第二种utf8mb4。COLLATE在国内比较常用的有三种都是与utf8mb4编码配套的,utf8mb4_bin是区分大小写,会依据此排序,utf8mb4_general_ci(默认)和utf8mb4_unicode_ci不区分大小写,对于中英文来讲并没有什么区别,随便选哪个都可以。
- CREATE DATABASE [IF NOT EXISTS] 数据库名称 [DEFAULT CHARSET 字符集] [COLLATE 排序规则];
-
- # 示例
- CREATE DATABASE stu;
- CREATE DATABASE IF NOT EXISTS stu;
- CREATE DATABASE IF NOT EXISTS stu DEFAULT CHARSET utf8mb4;
- CREATE DATABASE IF NOT EXISTS stu DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_bin;
DROP DATABASE [IF EXISTS] 数据库名称;
这里涉及使用某数据库后若忘记所处数据库位置,可以调用我们这里讲的第二个命令,查询当前数据库。若要切换数据库,直接USE 新数据库名称即可。
USE 数据库名称;
注意这里的sys是系统里的数据库,不要随意在系统库中创建表结构。
- SHOW TABLES;
-
- # 示例
- USE sys;
- SHOW TABLES;
DESC 表名称;
SHOW CREATE TABLE 表名称;
创建表,这里是分行输入的,同样[]里的内容是可选参数,可以省略选用默认值,需要注意,最后一行不要丢掉分号,最后一个字段n对应这行没有逗号
- CREATE TABLE 表名(
- 字段1 字段1类型 [ COMMENT 字段1注释 ],
- 字段2 字段2类型 [COMMENT 字段2注释 ],
- 字段3 字段3类型 [COMMENT 字段3注释 ],
- ......
- 字段n 字段n类型 [COMMENT 字段n注释 ]
- ) [ COMMENT 表注释 ] ;
-
- # 示例
- CREATE TABLE try(
- id INT COMMENT '编号',
- name VARCHAR(50) COMMENT '姓名',
- age INT COMMENT '年龄',
- gender VARCHAR(1) COMMENT '性别'
- ) COMMENT '用户表';
-
- # 展示一下前面两个命令
- DESC try; # 查询表结构
- SHOW CREATE TABLE try; # 查询指定表的建表语句

查询的结果如下
这里可以设置的字段类型有很多种,主要可以分为三类:数值型、字符串型、日期时间型
数值类型大致可分为整数和小数,然后在对他们细分精度,范围越广精度越高,则所占大小就会越大。DECIMAL对应的范围需要用户自己设置,精度指这个数总共的位数,标度指小数点后的位数,如123.45,精度为5,标度为2,设置就是decimal(5,2) ,取值范围是-999.99~999.99,因此具体大小与设置有关。 float和double也可以这样设置,注意float的有效位为7,double为15,decimal为28,即当精度超出有效位时会四舍五入为有效位。例如float f = 345.98756f,结果显示为345.9876,只显示7个有效位,对最后一位数四舍五入。
如何能够更巧妙的利用这些数据类型来节省存储空间呢?例如针对年龄而言,不会出现负数,且不会很大,采用小整数即可,且选择无符号范围(即不需要负号)。
- CREATE TABLE try(
- age TINYINT UNSIGNED COMMENT '年龄'
- ) COMMENT '用户表' ;
分类 | 类型 | 大小 | 有符号(SIGNED)范围 | 无符号(UNSIGNED)范围 | 描述 |
数值类型 | TINYINT | 1 byte | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 bytes | (-32768,32767) | (0,65535) | 大整数值 | |
MEDIUMINT | 3 bytes | (-8388608,8388607) | (0,16777215) | 大整数值 | |
INT或INTEGER | 4 bytes | (-2147483648,2147483647) | (0,4294967295) | 大整数值 | |
BIGINT | 8 bytes | (-2^63,2^63-1) | (0,2^64-1) | 极大整数值 | |
FLOAT | 4 bytes | (-3.402823466 E+38,3.402823466351 E+38) | 0 和 (1.175494351 E-38,3.402823466 E+38) | 单精度浮点数值 | |
DOUBLE | 8 bytes | (-1.7976931348623157 E+308,1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308,1.7976931348623157 E+308) | 双 度浮点数值 | |
DECIMAL | 依赖于M(精度)和D(标度)的值 | 依赖于M(精度)和D(标度)的值 | 小数值(精确定点数) |
字符串类型的可大致分为CHAR、VARCHAR、BLOB、TEXT。
BLOB主要针对二进制数据,例如视频、音频、软件安装包,都是可以储存的,但很少这样做。
CHAR和VARCHAR后面必须要跟一参数,即当前字符串最大存储的字符数,而这两个的区别在于CHAR是定长字符串,设置的参数是多少他就是多长,哪怕存储的并没有达到,也会采用空格进行补位,但VARCHAR则是会根据输入的具体长度,参数只是限制最长输入长度。但正因为VARCHARVARCHAR是可变的,会根据内容来计算所占用的空间,所以相比CHAR而言性能较差。
举两个例子,若是设置用户名,我们要求用户输入不得大于50个字符,但这时有用户会输入1个2个或是49个,有很多种可能,这时应该选择哪个去存储呢?答案是VARCHAR(50),因为选用CHAR会存在很大的内存浪费。若是设置性别变量呢?只有男或女,此时CHAR则更好,CHAR(1)。
分类 | 类型 | 大小 | 描述 |
字符串类型 | CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 | |
TINYBLOB | 0-255 bytes | 不超过255个字符的二进制数据 | |
TINYTEXT | 0-255 bytes | 短文本字符串 | |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 | |
TEXT | 0-65 535 bytes | 长文本数据 | |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 | |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 | |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 | |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
日期类型里需要注意的是TIMESTAMP是个时间戳,范围最大只取到了2038年。
分类 | 类型 | 大小 | 范围 | 格式 | 描述 |
日期类型 | DATE | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 时间值或持续时间 | |
YEAR | 1 | 1901 至 2155 | YYYY | 年份值 | |
DATETIME | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 | |
TIMESTAMP | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
设计一张员工信息表,要求如下:
- CREATE TABLE information(
- num INT COMMENT '编号',
- number VARCHAR(10) COMMENT '员工工号',
- name VARCHAR(10) COMMENT '姓名',
- gender CHAR(1) COMMENT '性别',
- age TINYINT UNSIGNED COMMENT '年龄',
- idcard CHAR(18) COMMENT '身份证号',
- entrydate DATE COMMENT '入职时间'
- ) COMMENT '员工信息表';
- ALTER TABLE 表名 ADD 字段名 类型 (长度) [COMMENT 注释] [约束];
-
- # 示例:为information表增加一个新的字段“昵称”,nickname,类型为varchar(20)
- ALTER TABLE information ADD nickname VARCHAR(20) COMMENT '昵称';
ALTER TABLE 表名 MODIFY 字段名 新数据类型 (长度);
- ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];
-
- # 示例:将information表的nickname字段修改为username,类型为varchar(30)
- ALTER TABLE information CHANGE nickname username varchar(30) COMMENT '昵称';
- ALTER TABLE 表名 DROP 字段名;
-
- # 示例:将emp表的字段username删除
- ALTER TABLE emp DROP username;
- ALTER TABLE 表名 RENAME TO 新表名;
-
- # 示例:将information表的表名修改为 inform
- ALTER TABLE information RENAME TO inform;
有两种操作,第一种是直接删除,表内数据和该表都不再存在
DROP TABLE [ IF EXISTS ] 表名;
第二种删除表,并重新创建表,只删除表内数据,但该表依旧存在
TRUNCATE TABLE 表名;
- SHOW DATABASES;
- CREATE DATABASE 数据库名;
- USE 数据库名;
- SELECT DATABSES();
- DROP DATABASES 数据库名;
- SHOW TABLES;
- CREATE TABLE 表名(字段 字段类型,字段字段类型);
- DESC 表名;
- SHOW CREATE TABLE 表名;
- ALTER TABLE 表名 ADD/MODIFY/CHANGE/DROP/RENAME TO ...;
- DROP 表名;
- TRUNCATE 表名;
针对的是数据库中表的数据记录,也就是对每一行数据的操作,包括三部分:添加数据、修改数据和删除数据
- # 给指定字段添加数据
- INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
- # 给全部字段添加数据
- INSERT INTO 表名 VALUES (值1, 值2, ...);
- # 批量添加数据
- INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...),(值1, 值2, ...),(值1, 值2, ...);
- INSERT INTO 表名 VALUES (值1, 值2, ...),(值1, 值2, ...),(值1, 值2, ...);
-
- # 示例
- INSERT INTO information(num, number, name, gender, age, idcard, entrydate) VALUES(1,'1','lucy','女',22,'x12345678912345678','2000-01-01');
- INSERT INTO information VALUES(2,'2','lily','女',22,'x12345678912345678','2000-01-01');
- INSERT INTO information VALUES(3,'3','jony','男',25,'145845678912345678','2005-01-01'),(4,'4','Jack','男',28,'145845678912345678','2003-01-01');
注意:插入时,指定字段需要与值的顺序一致;除数值型数据外,即字符型和日期型都要包含在单引号内;输入的数据需要符合对应字段类型的要求
- UPDATE 表名 SET 字段名1 = 值1 , 字段名2 = 值2 , .... [ WHERE 条件 ] ;
-
- # 示例
- UPDATE information SET name = 'ZHANGSAN' WHERE num = 1; # 将id为1对应那条数据的name值改为ZHANGSAN
- UPDATE information SET name = '李四', gender = '男' WHERE num = 2; # 修改一条数据中的两个字段数据,用逗号隔开
- UPDATE information SET entrydate = '2000-01-01'; # 不加条件即修改表内所有数据
where后加条件,若不加,则修改整张表对应字段数据
- DELETE FROM 表名 [ WHERE 条件 ] ;
-
- # 示例
- DELETE FROM information WHERE gender = '女'; # 删除符合条件的数据
- DELETE FROM information; # 会删除整张表的数据
同样,where后加条件,若没有,则删除整张表的所有数据
该命令不能删除某一字段的值(可以用UPDATE),更新为空字符串,似乎数字类型的也要写上'',是不可以直接空着的
UPDATE information SET name = '' WHERE num = 2;
查询的应用有很多,例如一些购物网站、学习网站等,想要在这些网站中看到我们想看到的数据,都是需要从数据库中进行查询并展示的。而且在查询的过程中,可能还会涉及到条件搜索、范围搜索或者排序、分页等操作。关键命令就是select,但不同的查询任务会跟不同的内容。
注意编写顺序如下,顺序不能换:
- SELECT
-
- 字段列表
-
- FROM
-
- 表名列表
-
- WHERE
-
- 条件列表
-
- GROUP BY
-
- 分组字段列表
-
- HAVING
-
- 分组后条件列表
-
- ORDER BY
-
- 排序字段列表
-
- LIMIT
-
- 分页参数

这里的起别名,和之前创建表时的字段注释是不一样的
- SELECT 字段1, 字段2, 字段3 ... FROM 表名 ; # 查询多个字段
- SELECT * FROM 表名 ; # 返回所有字段
- SELECT 字段1 [ AS 别名1 ] , 字段2 [ AS 别名2 ] ... FROM 表名; # 设置别名,AS可省略,增强字段可读性
- SELECT DISTINCT 字段列表 FROM 表名; # 查询时会去除重复记录
-
- # 示例
- select name,workno,age from information; # 查询指定字段并返回
- select * from information; # 查询所有字段
- select id, workno, name, gender, age, idcard, workaddress, entrydate from information;
- select workaddress as '工作地址' from information; # 起别名,方便查看,as可省略
- select distinct workaddress as '工作地址' from information; # 对查询结果进行去重
SELECT 字段列表 FROM 表名 WHERE 条件列表 ;
常见条件
若要满足多个条件查询,则要运用逻辑运算符进行组装
- -- 查询年龄为88的员工
- select * from information where age = 88;
-
- -- 年龄小于等于20
- select * from information where age <= 20;
-
- -- 查询没有身份证号的信息
- select * from information where idcard is null;
-
- -- 查询有身份证号的员工信息
- select * from information where idcard is not null;
-
- -- 查询年龄不为88
- select * from information where age != 88;
- select * from information where age <> 88;
-
- -- 查询年龄在[15,20]的员工
- select * from information where age >= 15 and age <=20;
- select * from information where age >= 15 && age <=20;
- select * from information where age between 15 and 20; # 注意数字的顺序不能颠倒
-
- -- 查询性别为女且年龄小于25的员工信息
- select * from information where gender = '女' and age <25;
-
- -- 查询年龄等于18或20或40的员工信息
- select * from information where age = 18 or age = 20 or age = 40;
- select * from information where age in(18,20,40);
-
- -- 查询姓名为两个字的员工信息 _ %
- select * from information where name like '__'; # 注意加''
-
- -- 查询身份证号最后一位是X的员工信息
- select * from information where idcard like '%X';

在进行分组查询时通常会配合聚合函数,即将一列数据作为整体进行计算,作用于表中的某一列数据,常见的5个聚合函数有:
SELECT 聚合函数(字段列表) FROM 表名 ;
注意,null值不参与所有聚合函数的运算
- -- 统计该企业员工数量
- select count(*) from information;
- select count(id) from information; # 统计id中有值的总数量
-
- -- 统计平均年龄
- select avg(age) from information;
-
- -- 统计最大年龄
- select max(age) from information;
-
- -- 统计西安地区的员工年龄之和
- select sum(age) from information where workaddress = '西安';
SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ];
where与having后面都加条件,那么这两个之间有什么区别呢?
• 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组
之后对结果进行过滤。
• 判断条件不同:where不能对聚合函数进行判断,而having可以。
- -- 根据性别分组,统计男性员工和女性员工的数量
- select gender, count(*) from information group by gender;
- # selec加上gender是为了分辨输出的数量各属于哪一组
-
- -- 根据性别分组,统计男性员工和女性员工的平均年龄
- select gender, avg(age) from information group by gender;
-
- -- 查询年龄小于45的员工,根据工作地址分组,获得员工数量大于等于3的工作地址
- select workaddress, count(*) address_count from information where age < 45 group by workaddress having count(*)>3;
- # selec加上count可以具体看到对应的员工数量,可以数量起个别名
分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义,一般会显示对应组的第一个数据,或者报错。
• 执行顺序: where > 聚合函数 > having ,在分组之前对满足条件的数据进行分组,然后进行相应聚合函数,聚合完成后通过having进一步设置条件筛选数据。
• 支持多字段分组, 具体语法为 : group by columnA,columnB
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 , 字段2 排序方式2 ;
ASC : 升序(默认值,故如果是升序, 可以不指定排序方式ASC)
DESC: 降序
支持多字段排序, 如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序 ;
- -- 根据年龄对公司的员工进行升序排序
- select * from information order by age ; # 升序可省略ASC
- select * from information order by age desc ; # 降序排序
-
- -- 根据入职时间, 对员工进行降序排序
- select * from information order by entrydate desc ;
-
- -- 根据年龄对公司的员工进行升序排序 , 年龄相同 , 再按照入职时间进行降序排序
- select * from information order by age , entrydate desc ;
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ;
可以理解为分页,也可以理解为对显示的数据限制其展示条数,或对应位置数据。
• 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数。我理解的就是:从所有页数据合并在一起形成的大数据库中查询,起始索引表示的就是这个总的大数据库中,我们从第几条数据开始查,查询记录数就是从起始索引开始查,查几条。
例如我在网站上点击第三页,每页展示10条信息,那么起始索引=(3-1)* 10 = 20,也就是计算出第三页之前有多少条数据,从那之后查询。
• 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。
• 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10。
- -- 查询第1页员工数据, 每页展示10条记录
- select * from information limit 10 ;
-
- -- 查询第2页员工数据, 每页展示10条记录,起始索引 = (页码-1)*页展示记录数
- select * from information limit 10, 10 ;
7.案例
- -- 查询年龄为20,21,22,23岁的女性员工信息。
- select * from information where gender = '女' and age in (20,21,22,23) ;
-
- -- 查询性别为 男 ,并且年龄在 20-40 岁(含)以内的姓名为三个字的员工。
- select * from information where gender = '男' and ( age between 20 and 40 ) and name like '___' ; # 条件较多,可以用小括号括起条件
-
- -- 统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数。
- select gender, count(*) from information where age < 60 group by gender ;
-
- -- 查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序。
- select name, age from information where age <= 35 order by age , entrydate desc ;
-
- -- 查询性别为男,且年龄在20-40 岁(含)以内的员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序排序,只显示前5条数据。
- select * from information where gender = '男' and age between 20 and 40 order by age , entrydate limit 5 ;
最后一条要求编写时注意,limit语句都是放在最后的,可以回看下标题三后面写的执行顺序。
8. 执行顺序
编写顺序不等于执行顺序
例如,在select中设置的别名,在where和group by时是不可以使用的,但在order by和limit可以。
用于管理数据库用户、控制数据库的访问权限,对数据开发人员可能并不常用
用户所具有的权限信息都是存放在系统数据库mysql的user表当中的,所以我们可以直接访问mysql数据库,查询user表来看用户信息
- use mysql;
- select * from user;
可以查询到有以下四个用户,Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问,是不可以远程访问的。 User代表的是访问该数据库的用户名。在MySQL中需要通过Host和User来唯一标识一 个用户,也就是说我们要创建或删除一个用户,需要用houst和user同时定位。Y,N表示对应是否有权限
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
主机名限制的就是这个用户名在哪一个主机上可以访问当前mysql
- -- 创建用户new, 只能够在当前主机localhost访问, 密码123456;
- create user 'new'@'localhost' identified by '123456' ;
-
- -- 创建用户new, 可以在任意主机访问该数据库, 密码123456;
- create user 'new'@'%' identified by '123456' ;
- # %可以充当任何长度的字符,所以相当于任意主机都可以访问
用户创建好后,并没有为其分配权限,所以新创建的用户在各数据库的权限是N
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ;
- -- 修改用户new的访问密码为1234;
- alter user 'new'@'%' identified with mysql_native_password by '1234' ;
DROP USER '用户名'@'主机名' ;
- -- 删除new'@'%用户
- DROP USER 'new'@'%' ;
常用的几种权限:
SHOW GRANTS FOR '用户名'@'主机名' ;
show grants for 'root'@'localhost' ;
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
- create user 'new'@'localhost' identified by '1234' ;
- grant all on study.* to 'new'@'localhost'
- show grants for 'new'@'localhost' ;
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
revoke all on study.* from 'new'@'localhost' ;
多个权限之间,使用逗号分隔 ,授权时, 数据库名和表名可以使用 * 进行通配,代表所有。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。