一、用户管理
1.权限表
(1)user表
User表是MySQL中最重要的一个权限表,记录允许连接到服务器的帐号信息,里面的权限是全局级的。
(2)db表和host表
db表和host表是MySQL数据中非常重要的权限表。db表中存储了用户对某个数据库的操作权限,决定用户能从哪个主机存取哪个数据库。host表中存储了某个主机对数据库的操作权限,配合db权限表对给定主机上数据库级操作权限做更细致地控制。
(3)tables_priv表和columns_priv表
tables_priv表用来对表设置操作权限。
columns_priv表用来对表的某一列设置权限。
(4)procs_priv表
procs_priv表可以对存储过程和存储函数设置操作权限。
2.账户管理
(1)登录和退出MySQL服务器
mysql命令的常用参数以及登录和退出mysql服务器的方法。
使用root用户登录到本地mysql服务器的test库中
mysql -u root -p -h localhost test
使用root用户登录到本地mysql服务器的test库中,执行一条查询语句
mysql -u root -p -h localhost test -e "DESC person;"
(2)新建普通用户
a.使用CREATE USER或GRANT语句。
使用CREATE USER创建一个用户,用户名是jeffrey,密码是mypass,主机名是localhost
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
使用GRANT语句创建一个新的用户testUser,密码为testpwd。用户 testUser对所有的数据有查询和更新权限,并授于对所有数据表的SELECT和UPDATE权限
GRANT SELECT,UPDATE ON *.* TO 'testUser'@'localhost' IDENTIFIED BY 'testpwd'; /*创建账户并授予权限*/
SELECT Host,User,Select_priv,Update_priv, FROM mysql.user where user='testUser'; /*查看账户权限信息*/
b.直接操作MySQL授权表。
使用INSERT创建一个新账户,其用户名称为customer1,主机名称为localhost,密码为customer1:
INSERT INTO user (Host,User,Password) VALUES('localhost','customer1',PASSWORD('customer1'));
(3)删除普通用户
a.使用DROP USER语句删除用户
使用DROP USER删除用户'jeffrey'@'localhost'
DROP USER 'jeffrey'@'localhost';
b.使用DELETE语句删除用户
使用DELETE删除用户'customer1'@'localhost'
DELETE FROM mysql.user WHERE host='localhost' and user='customer1';
(4)root用户修改自己的密码
a.使用mysqladmin命令在命令行指定新密码
使用mysqladmin将root用户的密码修改为“rootpwd”
mysqladmin -u root -p password "123456"
b.修改mysql数据库的user表
使用UPDATE语句将root用户的密码修改为“rootpwd2”:
UPDATE mysql.user set authentication_string=password("rootpwd2")
WHERE User="root" and Host="localhost";
c.使用SET语句修改root用户的密码
使用SET语句将root用户的密码修改为“rootpwd3”:
SET PASSWORD=password("rootpwd3");
(5)root用户修改普通用户密码
a.使用SET语句修改普通用户的密码
使用SET语句将testUser用户的密码修改为“newpwd”:
SET PASSWORD FOR 'testUser'@'localhost'=password("newpwd");
b.使用UPDATE语句修改普通用户的密码
使用UPDATE语句将testUser用户的密码修改为“newpwd2”:
UPDATE mysql.user set authentication_string=PASSWORD("newpwd2")
WHERE User="testUser" and Host="localhost";
c.使用GRANT语句修改普通用户密码
使用GRANT语句将testUser用户的密码修改为“newpwd3”:
GRANT USAGE ON *.* TO 'testUser'@'localhost' IDENTIFIED BY 'newpwd3';
(6)普通用户修改密码
普通用户登录MySQL服务器后,通过SET语句设置自己的密码。
SET PASSWORD = PASSWORD(‘newpassword’);
testUser用户使用SET语句将自身的密码修改为“newpwd4”:
SET PASSWORD = PASSWORD("newpwd4");
(7)root用户密码丢失的解决办法
a.使用--skip-grant-tables选项启动MySQL服务
mysql start-mysqld --skip-grant-tables
b.使用root用户登录和重新设置密码
mysql -u root
update mysql.user set authentication_string=password('mypass') where user='root' and host='localhost';
c.加载权限表
flush privileges;
3.权限管理
(1)MySQL的各种权限
账户权限信息被存储在mysql数据库的user、db、host、tables_priv、columns_priv和procs_priv表中。在MySQL启动时,服务器将这些数据库表内容读入内存。
(2)授权
授权就是为某个用户授于权限。合理的授权可以保证数据库的安全。MySQL中可以使用GRANT语句为用户授于权限。
使用GRANT语句创建一个新的用户grantUser,密码为“grantpwd”。用户grantUser对所有的数据有查询、插入权限,并授于GRANT权限。GRANT语句及其执行结果如下:
MySQL> GRANT SELECT,INSERT ON *.* TO 'grantUser'@'localhost' IDENTIFIED BY 'grantpwd' WITH GRANT OPTION;
Query OK, 0 rows affected (0.03 sec)
结果显示执行成功,使用SELECT语句查询用户testUser2的权限:
MySQL> SELECT Host,User,Select_priv,Insert_priv, Grant_priv FROM mysql.user where user='grantUser';
+-----------+------------+-------------+--------------+-------------+
| Host | User | Select_priv | Insert_priv | Grant_priv |
+-----------+------------+-------------+--------------+--------------+
| localhost | testUser2 | Y | Y | Y |
+-----------+------------+-------------+--------------+--------------+
1 row in set (0.00 sec)
(3)收回权限
收回权限就是取消已经赋于用户的某些权限。收回用户不必要的权限可以在一定程度上保证系统的安全性。MySQL中使用REVOKE语句取消用户的某些权限。
使用REVOKE语句取消用户testUser的更新权限。REVOKE语句及其执行结果如下:
MySQL> REVOKE UPDATE ON *.* FROM 'testUser'@'localhost';
Query OK, 0 rows affected (0.00 sec)
执行结果显示执行成功,使用SELECT语句查询用户test的权限:
MySQL> SELECT Host,User,Select_priv,Update_priv,Grant_priv FROM MySQL.user where user='testUser';
+-----------+------+--------------+---------------+--------------+
| Host | User | Select_priv | Update_priv | Grant_priv |
+-----------+------+--------------+---------------+--------------+
| localhost | test | Y | N | Y |
+-----------+------+-------------+---------------+--------------+
1 row in set (0.00 sec)
(4)查看权限
SHOW GRANTS语句可以显示指定用户的权限信息,使用SHOW GRANT语句查看账户信息。
SHOW GRANTS FOR ‘user’@’host’ ;
使用SHOW GRANTS语句查询用户testUser的权限信息。SHOW GRANTS语句及其执行结果如下:
MySQL> SHOW GRANTS FOR 'testUser'@'localhost';
+------------------------------------------------------------------------------------------------------------------------------+
| Grants for testUser@localhost |
+------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO 'testUser'@'localhost' IDENTIFIED BY PASSWORD
'*53835E70E1FC57BE1A455169C761A8778D307C81' WITH GRANT OPTION |
+------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
二、高级SQL语句
2.1 MySQL 进阶查询
创建测试数据库和表:
create database auth;
use auth
create table t1(id int(10), name char(20),level int(10));
insert into t1 value(10,'sagou',42);
insert into t1 value(8,'senoku',45);
insert into t1 value(15,'useless',47);
insert into t1 value(27,'guess',52);
insert into t1 value(199,'useless',48);
insert into t1 value(272,'Theshy',36);
insert into t1 value(298,'leslieF',40);
insert into t1 value(30,'shirley',58);
insert into t1 value(190,'zhangsan',48);
insert into t1 value(271,'lisi',52);
insert into t1 value(299,'wangwu',52);
insert into t1 value(31,'zhaoliu',58);
create table t2(id int(10), name char(20),level int(10));
insert into t2 value(10,'sagou',42);
insert into t2 value(8,'senoku',45);
insert into t2 value(15,'useless',47);
insert into t2 value(27,'guess',52);
insert into t2 value(199,'useless',48);
insert into t2 value(272,'Theshy',36);
insert into t2 value(298,'leslieF',40);
insert into t2 value(30,'shirley',58);
insert into t2 value(190,'zhangsan',48);
insert into t2 value(271,'lisi',52);
insert into t2 value(299,'wangwu',52);
insert into t2 value(31,'zhaoliu',58);
1.常用查询介绍
(1)按关键字排序
使用SELECT 语句可以将需要的数据从MySQL 数据库中查询出来,如果对查询的结果进行排序,该如何去实现呢?可以使用ORDER BY 语句来完成排序,并最终将排序后的结果返回给用户。这个语句的排序不光可以针对某一个字段,也可以针对多个字段。
【语法】
SELECT column1, column2, ... FROM table_name ORDER BY column1, column2, ... ASC|DESC;
SELECT 语句中如果没有指定具体的排序方式,则默认按ASC 方式进行排序。DESC 是按降序方式进行排列。当然ORDER BY 前面也可以使用WHERE 子句对查询结果进一步过滤。
执行以下操作可查询等级大于等于45 级的用户,并按降序进行排序
mysql> select id,name,level from t1 where level>=45 order by level desc;
ORDER BY 语句也可以使用多个字段来进行排序,当排序的第一个字段相同的记录有多条的情况下,这些多条的记录再按照第二个字段进行排序。
执行以下操作可查询等级在45 级及以上的用户,并以level降序排列和id 降序排列
mysql> select id,name,level from t1 where level>=45 order by level desc, id desc;
备注:
- ORDER BY A,B desc 指A 用升序,B 用降序;
- ORDER BY A asc,B desc 指A 用升序,B 用降序;
- ORDER BY A desc,B desc 指A 用降序,B 用降序;
(2)对结果进行分组
通过SQL 查询出来的结果,还可以对其进行分组,使用GROUP BY 语句来实现。GROUP BY 从字面上看,是以BY 后面的内容对查询出的数据进行分组,就是将一个“数据集”划分成若干个“小区域”,然后针对这些个“小区域”进行数据处理。GROUP BY 通常都是结合聚合函数一起使用的,常用的聚合函数包括:计数(COUNT)、求和(SUM)、求平均数(AVG)、最大值(MAX)、最小值(MIN),这些聚合函数的用法在后面函数小节会有更详细的讲解。GROUP BY 分组的时候可以按一个或多个字段对结果进行分组处理
【语法】
SELECT column_name, aggregate_function(column_name)FROM table_name WHERE column_name operator valueGROUP BY column_name;
GROUP BY 除了配合聚合函数一起使用外,还可以引入WHERE 子句。首先通过WHERE 过滤掉一部分不符合需求的查询结果,然后再对结果进行分组。如果有排序的需求,也可以引入ORDER BY 语句。
执行以下操作即可统计等级在45 级及以上,以等级为分组,每个等级有多少人
mysql> select count(name),level from t1 where level>=45 group by level;
而GROUP BY 结合ORDER BY 即可实现分组并排序的查询。
查询等级在45 级及以上,按等级进行分组,并将每个等级的人数按降序排序,具体操作如下所示
mysql> select count(name),level from t1 where level>=45 group by level order by count(name) desc;
(3)限制结果条目
在使用MySQL SELECT 语句进行查询时,结果集返回的是所有匹配的记录。有时候仅需要返回第一行或者前几行,这时候就需要用到LIMIT 子句
【语法】
SELECT column1, column2, ... FROM table_name LIMIT [offset,] number
LIMIT 子句是一种简单的分页方法,它的使用减少了数据结果的返回时间,提高了执行效率,也解决了由于数据量过大从而导致的性能问题。
执行以下操作即可查询表的前3 个用户的信息
mysql> select id,name,level from t1 limit 3;
LIMIT 子句的使用也可以结合ORDER BY:先进行排序,然后再LIMIT 限制固定的记录。也就是说LIMIT 是放在最后的,将处理好的结果集按要求选出几行来。
将查询记录按等级level 降序排列,只取前三条记录
mysql> select id,name,level from t1 order by level desc limit 3;
在显示结果的时候也可以不从第一行开始,引入offset 参数。
执行以下操作即可从第3 条记录开始显示之后的3 条数据
mysql> select id,name,level from t1 limit 2,3;
(4)设置别名
在MySQL 查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了,增强可读性。
【列的别名语法】
SELECT column_name AS alias_nameFROM table_name;
【表的别名语法】
SELECT column_name(s)FROM table_name AS alias_name;
在统计表内所有记录共有多少条时,使用count(*),这么写不便于识别,可以将其别名设置为number
mysql> select count(*) as number from t1;
mysql>select count(*) number from t1;
执行以下操作即可将t1 表的别名设置成p。
mysql> select p.id,p.name from t1 as p limit 3;
mysql>select p.id,p.name from t1 p limit 3;
执行以下操作即可实现用一条SQL语句完成在创建表t1 的时候将t1 表内的数据写入t1表。
mysql> create table t1 as select * from t1;
mysql>select count(*) from t1;
(5)通配符
通常通配符都是跟LIKE 一起使用的,并协同WHERE 子句共同来完成查询任务
- %:百分号表示零个、一个或多个字符
- _:下划线表示单个字符
查询t1 表内name 字段分别以s 开头的名字、以s 结尾的名字和名字中间包含es 的字段,具体操作如下所示
name 字段以s 开头的记录
mysql> select id,name,level from t1 where name like 's%';
name 字段以s 结尾的记录
mysql> select id,name,level from t1 where name like '%s';
name 字段中间含es 的记录
mysql> select id,name,level from t1 where name like '%es%';
利用下划线替换表内name 字段开头的字符、结尾的字符或者中间的字符
替换开头的一个字符
mysql> select id,name,level from t1 where name like '_uess';
替换结尾的四个字符
mysql> select id,name,level from t1 where name like 'use____';
替换中间的一个字符
mysql> select id,name,level from t1 where name like 'shi_ley';
name 字段中,开头有一个字符,接着是es 两个字符,后面再跟着零个、一个或多个字符,从t1 表中查询这样的数据
mysql> select id,name,level from t1 where name like '_es%';
(6)子查询
子查询也被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句。子查询语句是先于主查询语句被执行的,其结果作为外层的条件返回给主查询进行下一步的查询过滤。子查询不仅可以在SELECT 语句中使用,在INERT、UPDATE、DELETE中也同样适用。在嵌套的时候,子查询内部还可以再次嵌套新的子查询,也就是说可以多层嵌套。
先查出等级大于等于45级的ID,然后在判断t1 表内的ID 是不是在这个结果集内,如果在就打印此行的名字和等级
mysql> select name,level from t1 where id in (select id from t1 where level>=45);
子查询还可以用在INSERT 语句中。子查询的结果集可以通过INSERT 语句插入到其他的表中。
先清空之前使用的t2 表,然后通过子查询的方式将t1 的内容插入到t2 表中。
mysql> truncate table t2;
mysql> select * from t2;
mysql> insert into t2 select * from t1 where id in (select id from t1);
mysql> insert into t2 select * from t1;
UPDATE 语句也可以使用子查询。UPDATE 内的子查询,在set 更新内容时,可以是单独的一列,也可以是多列。
执行以下操作即可通过子查询实现将等级大于等于47的用户减去7
mysql>select id,name,level from t2 where id=30;
mysql> update t2 set level = level - 7 where id in (select id from (select id from t2 where level >= 47) a);
mysql> select id,name,level from t2 where id=30;
DELETE 也适用于子查询。
先将原来47 级的用户等级恢复,然后通过子查询的方式将47 级用户删除。实现方式类似UPDATE 的子查询
mysql> update t2 set level=47 where id=30;
mysql> delete from t2 where id in (select id from (select id from t2 where level=47) a);
mysql>select id,name,level from t2 where id=30;
除了以上所列举的IN 操作符,在IN 前面还可以添加NOT,其作用与IN 相反,表示否定(即不在子查询的结果集里面)。
执行以下操作即可查询用户等级不小于45 级的用户
mysql> select name,level from t2 where id not in (select id from t2 where level < 45);
子查询上也可以使用比较运算符(=、<、>、>=、<=),这些运算符主要是对运算符前面的表达式和后面的子查询进行比较运算。
查询出名字是shirley 的记录,并输出其ID、名字和等级信息
mysql> select id,name,level from t2 where id = (select id from t2 where name='shirley');
EXIST 这个关键字在子查询时,主要用于判断子查询的结果集是否为空。如果不为空,则返回TRUE;反之,则返回FALSE。
先通过子查询判断返回是否为TRUE,如果用户shirley 存在,则计算整个t1 表的总记录数量,具体操作如下所示。
mysql> select count(*) as number from t1 where EXISTS (select id from t1 where name='shirley');
2.NULL值
在SQL 语句使用过程中,经常会碰到NULL 这几个字符。通常使用NULL 来表示缺失的值,也就是在表中该字段是没有值的。如果在创建表时,限制某些字段不为空,则可以使用NOT NULL 关键字,不使用则默认可以为空。
创建一个表test,该表包含不设置NOT NULL 的字段,然后向表中插入不同的记录值,其中包括NULL 值和实际有值的记录,最后通过SELECT 查询字段中包括NULL 和不包括NULL 的记录值
CREATE TABLE test (
id int(10) NOT NULL AUTO_INCREMENT,
NAME varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
level int(10) NOT NULL,
coin int(32),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入的记录中不包括coin 字段
mysql> insert into test(name,level) values('aa',10);
插入的记录中包括coin 字段
mysql>insert into test(name,level,coin) values('ab',20,100);
查询coin 字段为空值的记录
mysql>select * from test where coin is null;
查询coin 字段不为空的记录
mysql> select * from test where coin is not null;
备注:
NULL值和空值有什么区别:
- 空值的长度为0,不占用空间的;而NULL 值的长度是NULL,是占用空间的。
- IS NULL 或者IS NOT NULL,是用来判断字段是不是为NULL 或者不是NULL,不能查出是不是空值的。
- 空值的判断使用=’’或者<>’’来处理。
- 在通过count()计算有多少记录数时,如果遇到NULL 值会自动忽略掉,遇到空值会加入到记录中进行计算。
3.正则表达式
^str | 以什么开始 |
str$ | 以什么结尾 |
. | 匹配任何单个字符包括回车换行 |
[a-z] | 匹配在方阔内的任意字符列表 |
^[a-z] | 匹配以什么字符开头的 |
[^a-z] | 匹配不包含方阔内的任意字符列表 |
p1|p2|p3 | 匹配任何模式p1,p2,p3 |
* | 0个或多个前面的元素 |
+ | 1个或多个前面的元素 |
? | 0个或1个前面的元素 |
{n} | 前面元素连续出现的n个实例 |
.{n} | 前面元素出现的n个实例 |
{m,n} | 匹配前面元素m到n个实例 |
(1)以特定字符串开头的记录
在t1 表中查询以 zhang 开头的name 字段并打印对应的id、name 和level 记录
mysql>select id,name,level from t1 where name REGEXP '^zhang';
(2)以特定字符串结尾的记录
在t1 表中查询以ss 结尾的name 字段并打印对应的id、name 和level 记录
mysql> select id,name,level from t1 where name REGEXP 'ss$';
(3)包含指定字符串的记录
在t1 表中查询包含 an 字符串的name 字段并打印对应的id、name 和level记录
mysql>select id,name,level from t1 where name REGEXP 'an';
(4)以“.”代替字符串中的任意一个字符的记录
在t1 表中查询包含字符串shir 与ey,且两个字符串之间只有一个字符的name 字段并打印对应的id、name 和level 记录
mysql>select id,name,level from t1 where name REGEXP 'shir.ey';
(5)匹配包含或者关系的记录
在t1 表中查询包含字符串on 或者in 的name 字段并打印对应的id、name 和level 记录
mysql> select id,name,level from t1 where name REGEXP 'on|in';
(6)“*”匹配前面字符的任意多次
在t1 表中查询包含一个或者更多个连续的o 的name 字段并打印对应的id、name 和level 记录
mysql>select id,name,level from t1 where name REGEXP 'oo*';
(7)“+”匹配前面字符至少一次
在t1 表中查询包含一个或者更多个o 的name 字段并打印对应的id、name 和level 记录
mysql>select id,name,level from t1 where name REGEXP 'oo+';
(8)匹配指定字符集中的任意一个
在t1 表中查询包含以a-n 开头的name 字段并打印对应的id、name 和level 记录
mysql>select id,name,level from t1 where name REGEXP '^[a-n]';
4.运算符
(1)算术运算符
以SELECT 命令来实现最基础的加减乘除运算
mysql>select 1+2 as addition, 2-1 as subtraction, 2*3 as multiplication, 4/2 as division, 7%2 as remainder;
(2)比较运算符
等于运算符在数字、字符串和表达式上的使用
mysql> select 2=4,2='2','e'='e',(2+2)=(3+1),'r'=NULL;
关于数字、字符串和表达式的不等于运算符的使用
mysql>SELECT 'kgc'<>'bdqn', 1<>2, 3!=3, 2.5!=2, NULL<>NULL ;
关于大于、大于等于、小于、小于等于运算符的使用
mysql> select 5>4,'a'>'b',2>=3,(2+3)>=(1+2),4.4<3,1<2,'x'<='y',5<=5.5,'u'>=NULL;
关于数字、字符和NULL 值的运用
mysql>select 2 IS NULL,'f' IS NOT NULL,NULL IS NULL;
判断某数字是否在另外两个数字之间,也可以判断某英文字母是否在另外两个字母之间
mysql>select 4 BETWEEN 2 AND 6,5 BETWEEN 6 AND 8,'c' BETWEEN 'a' AND 'f';
若要判断一组数字或字母中哪个最小、哪个最大,可以通过使用LEAST 和GREATEST 来实现
mysql>SELECT least(1,2,3),least('a','b','c'),greatest(1,2,3),greatest('a','b','c');
备注:
- LEAST:当有两个或者多个参数时,返回其中的最小值。如果其中一个值为NULL,则返回结果就为NULL。
- GREATEST:当有两个或者多个参数时,返回其中的最大值。如果其中一个值为NULL,则返回结果就为NULL。
判断某数字是否在一组数字中,也可判断某字符是否在一组字符中
mysql>SELECT 2 in (1,2,3,4,5),'c' not in ('a','b','c');
备注:
- IN 判断一个值是否在对应的列表中,如果是返回1,否则返回0。
- NOT IN 判断一个值是否不在对应的列表中,如果不是返回1,否则返回0。
若要判断某字符串能否匹配成功,分单字符匹配和多字符匹配,也可以判断不匹配
mysql>SELECT 'bdqn' LIKE 'bdq_','kgc' LIKE '%c','etc' NOT LIKE '%th';
备注:
LIKE 用来匹配字符串,如果匹配成功则返回1,反之返回0。LIKE 支持两种通配符:’%’ 用于匹配任意数目的字符,而’_’只能匹配一个字符。NOT LIKE 正好跟LIKE 相反,如果没有匹配成功则返回1,反之返回0。
(3)逻辑运算符
- 逻辑非:NOT 或 !
- 逻辑与:AND 或&&
- 逻辑或:R 或||
- 逻辑异或:XOR
逻辑非:对 非0值 和0值 分别作逻辑非运算
mysql>SELECT not 2,!3,not 0,!(4-4);
逻辑与:对非0 值、0 值和NULL 值分别作逻辑与运算
mysql>SELECT 2 AND 3,4 && 0,0 && NULL,1 AND NULL;
逻辑或:对非0 值、0 值和NULL 值分别作逻辑或运算
mysql>SELECT 2 OR 3,4 || 0,0 OR NULL,1 || NULL;
逻辑异或:对非0 值、0 值和NULL 值分别作逻辑异或运算
mysql>SELECT 2 XOR 3,0 XOR 0,0 XOR 5,1 XOR NULL,NULL XOR NULL;
(4)位运算符
对数字进行按位与、或和取反运算,具体操作如下所示
mysql> SELECT 10 & 15, 10 | 15, 10 ^ 15, 5 &~1;
与运算规则:任何一个值为0,则结果就为0 1 & 1=1 1 & 0=0 0 & 0=0
或运算规则:任何一个值为1,则结果就为1 1 | 1 =1 1| 0 =1 0 | 0=0
参与^运算的两个二进制位不同时,结果为 1,相同时,结果为 0。
10 ^ 15:10 的补码为 1010,15 的补码为 1111,按位异或运算之后,结果为 0101
5 &~1:由于位取反运算符‘~’的级别高于位与运算符‘&’,因此先对 1 进行取反操作,结果为 63 个‘1’加一个‘0’,然后再与整数 5 进行与运算,结果为 0100,即整数 4。
备注:
常量 1 的补码为 63 个‘0‘加 1 个’1‘,位取反后就是 63 个’1‘加一个’0‘
备注:
补码为64位的二进制,比如十进制5,换算成二进制为101,在左侧补出61个0,就成了5的补码
对数字进行左移或右移的运算
mysql>SELECT 1<<2, 2<<2,10>>2,15>>2;
备注:
运算符 | 说明 | 使用形式 | 举例 |
| | 或 | a | b | 5 | 8 |
& | 与 | a & b | 5 & 8 |
^ | 异或 | a ^ b | 5 ^ 8 |
~ | 取反 | ~a | ~5 |
<< | 左移 | a << b | 5 << 2,表示整数 5 按位左移 2 位 |
>> | 右移 | a >> b | 5 >> 2,表示整数 5 按位右移 2 位 |
5.连接查询
MySQL 的连接查询,通常都是将来自两个或多个表的行结合起来,基于这些表之间的共同字段,进行数据的拼接。首先,要确定一个主表作为结果集,然后将其他表的行有选择性的连接到选定的主表结果集上。使用较多的连接查询包括:内连接、左连接和右连接。
创建测试用表:
CREATE TABLE `a_t1` (
`a_id` int(11) DEFAULT NULL,
`a_name` varchar(32) DEFAULT NULL,
`a_level` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `b_t1` (
`b_id` int(11) DEFAULT NULL,
`b_name` varchar(32) DEFAULT NULL,
`b_level` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into a_t1(a_id, a_name, a_level) values(1, 'aaaa', 10);
insert into a_t1(a_id, a_name, a_level) values(2, 'bbbb', 20);
insert into a_t1(a_id, a_name, a_level) values(3, 'cccc', 30);
insert into a_t1(a_id, a_name, a_level) values(4, 'dddd', 40);
insert into b_t1(b_id, b_name, b_level) values(2, 'bbbb', 20);
insert into b_t1(b_id, b_name, b_level) values(3, 'cccc', 30);
insert into b_t1(b_id, b_name, b_level) values(5, 'eeee', 50);
insert into b_t1(b_id, b_name, b_level) values(6, 'ffff', 60);
(1)内连接
在刚才创建的a_t1 和b_t1 表中使用内连接查询出通过判断a_id 和b_id 相等,包含在两个表内的部分
mysql>select a_id,a_name,a_level from a_t1 inner join b_t1 on a_id=b_id;
(2)左连接
从a_t1 和b_t1 表中,查询出a_t1 表中所有内容,并且查询出通过a_id 和b_id 相等判断出的b_t1 中的部分
mysql>select * from a_t1 a left join b_t1 b on a.a_id=b.b_id;
(3)右连接
从a_t1 和b_t1 表中,查询出在b_t1 表内的所有记录,并且通过判断a_id 和b_id 相等,在a_t1 表内的部分
mysql>select * from a_t1 a right join b_t1 b on a.a_id=b.b_id;
2.2 数据库函数
MySQL 数据库函数提供了能够实现各种功能的方法,使我们在查询记录时能够更高效的输出。MySQL 内建了很多函数,常用的包括数学函数、聚合函数、字符串函数和日期时间函数。
1.数学函数
- abs(x) :返回x 的绝对值
- rand() :返回0 到1 的随机数
- mod(x,y) :返回x 除以y 以后的余数
- power(x,y) :返回x 的y 次方
- round(x) :返回离x 最近的整数
- round(x,y) :保留x 的y 位小数四舍五入后的值
- truncate(x,y) :返回数字x 截断为y 位小数的值
- ceil(x) :返回大于或等于x 的最小整数
- floor(x) :返回小于或等于x 的最大整数
- least(x1,x2...) :返回集合中最小的值
- sqrt(x) :返回x 的平方根
- greatest(x1,x2...) :返回集合中最大的值
mysql>select abs(-1), rand(), mod(5,3), power(2,3), round(1.89);
mysql>select round(1.8937,3), truncate(1.235,2), ceil(5.2), floor(2.1), least(1.89,3,6.1,2.1);
2.聚合函数
MySQL 数据库函数中专门有一组函数是特意为库内记录求和或者对表中的数据进行集中概括而设计的,这些函数被称作聚合函数。
- avg() :返回指定列的平均值
- count() :返回指定列中非NULL 值的个数
- min() :返回指定列的最小值
- max() :返回指定列的最大值
- sum(x) :返回指定列的所有值之和
mysql>select sum(level) as sum_level from t1;
mysql>select max(level) as max_level from t1;
mysql>select min(level) as min_level from t1;
3.字符串函数
- length(x) 返回字符串x 的长度第
- trim() 移除字符串两侧的空白字符或其他预定义字符
- concat(x,y) 将提供的参数x 和y 拼接成一个字符串
- upper(x) 将字符串x 的所有字母变成大写字母
- lower(x) 将字符串x 的所有字母变成小写字母
- left(x,y) 返回字符串x 的前y 个字符
- right(x,y) 返回字符串x 的后y 个字符
- repeat(x,y) 将字符串x 重复y 次
- space(x) 返回x 个空格
- replace(x,y,z) 将字符串z 替代字符串x 中的字符串y
- strcmp(x,y) 比较x 和y,返回的值可以为-1,0,1
- substring(x,y,z) 获取从字符串x 中的第y 个位置开始长度为z 的字符串
- reverse(x) 将字符串x 反转
mysql>select length('bdqn'), trim(' yellow '), concat('bd', 'qn'), upper('abc'), right('hello', 3);
mysql>select repeat('kgc', 2), replace('hello', 'll', 'kgc'), strcmp(4, 5), substring('bjbdqn', 4, 2), reverse('hello');
4.日期时间函数
- curdate() 返回当前时间的年月日
- curtime() 返回当前时间的时分秒
- now() 返回当前时间的日期和时间
- month(x) 返回日期x 中的月份值
- week(x) 返回日期x 是年度第几个星期
- hour(x) 返回x 中的小时值
- minute(x) 返回x 中的分钟值
- second(x) 返回x 中的秒钟值
- dayofweek(x) 返回x 是星期几,1 星期日,2 星期一
- dayofmonth(x) 计算日期x 是本月的第几天
- dayofyear(x) 计算日期x 是本年的第几天
mysql>select curdate(), curtime(), now(), month('2020-02-09'), week('2020-02-09'), hour('21:13:53');
mysql>select minute('21:13:53'), second('21:13:53'), dayofweek('2020-02-09'), dayofmonth('2020-02-09'), dayofyear('2020-02-09');
2.3 存储过程
1.存储过程简介
MySQL 数据库存储过程是一组为了完成特定功能的SQL 语句的集合,存储过程在数据库中创建并保存,它不仅仅是SQL 语句的集合,还可以加入一些特殊的控制结构,也可以控制数据的访问方式。
备注:存储过程的优点
- 存储过程执行一次后,生成的二进制代码就驻留在缓冲区,之后如果再次调用的话,将直接调用二进制代码,使得存储过程的执行效率和性能得到大幅提升。
- 存储过程是SQL 语句加上控制语句的集合,有很强的灵活性,可以完成复杂的运算。
- 存储过程存储在服务器端,客户端调用时,直接在服务器端执行,客户端只是传输的调用语句,从而可以降低网络负载。
- 存储过程被创建后,可以多次重复调用,它将多条SQL 封装到了一起,可随时针对SQL语句进行修改,不影响调用它的客户端。
- 存储过程可以完成所有的数据库操作,也可以通过编程的方式控制数据库的信息访问权限。
2.创建存储过程
通过存储过程查询 t1 表的三条数据,存储过程是不带参数的
mysql> DELIMITER $$
mysql> CREATE PROCEDURE t1Role()
BEGIN
SELECT id,name,level from t1 limit 3;
END $$
备注:
DELIMITER:用于定义SQL语句的结束符,默认的结束符是分号。
mysql> DELIMITER ;
mysql> call t1Role();
通过存储过程查询t1 表中某一条记录,存储过程是带参数的
mysql>DELIMITER $$
mysql>CREATE PROCEDURE GetRole(IN inname VARCHAR(16))
BEGIN
SELECT id,name,level from t1 where name=inname;
END $$
mysql>DELIMITER ;
mysql>call GetRole('shirley');
备注:
DELIMITER ;分号前有空格
3.修改存储过程
存储过程在创建之后,随着开发业务的不断推进,业务需求难免有所调整,相应的存储过程也会发生变动,这个时候就需要修改存储过程。存储过程的修改分为特征的修改和业务内容的修改。
特征的修改:修改存储过程,将其权限修改为modifies sql data,并且指明调用者可以执行
ALTER PROCEDURE t1Role
modifies sql data
sql security invoker;
存储过程内容的修改方法是通过删除原有存储过程,之后再以相同的名称创建新的存储过程。