MySQL基础
MySQL 是最流行的关系型数据库管理系统,市场占有率比较高,在 CTF 比赛中也经常出现。
基础语法
SQL 语法的核心要点总结如下:
-
语句开头:所有 SQL 语法都必须以关键字(命令)开头,如 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP、CREATE、USE、SHOW 等。
-
语句结尾:所有 SQL 语句必须以分号 ; 结尾。
-
书写格式:SQL 语句可跨行书写,既可以写在一行,也可以分多行。
-
大小写规则:
- SQL 不区分大小写,关键字(如 SELECT 与 select)效果相同,但通常关键字使用大写形式
- 表名区分大小写,必须与数据库中已存在的表名严格一致
注释
MySQL中的注释符号有三种
# 这里是注释的内容,在浏览器中有特殊含义,代表锚点,在 GET 请求中不会被发送到后端,如果需要发送到后端,可以使用URL编码格式:%23
--[空格] 这里是注释的内容,(空格,tab,换符)都行,通常写--+,+会被浏览器解析为空格,也可以使用URL编码:--%20,有些浏览器或者应用会把 + 编码为 %2B ,因为不同的应用遵循的RFC规范不一样。
/*这里是注释的内容*/,多行注释,常用来替换空格
基本操作
创建数据库:
删除数据库:
查询所有数据库:
选择数据库:
查询数据库下的表名:
删除表:
创建表:
1CREATE TABLE IF NOT EXISTS `tbl`(
2 `id` INT UNSIGNED AUTO_INCREMENT,
3 `title` VARCHAR(500) NOT NULL,
4 `author` VARCHAR(40) NOT NULL,
5 PRIMARY KEY ( `id` )
6)ENGINE=InnoDB DEFAULT CHARSET=utf8;
往表中插入数据:
1INSERT INTO tbl
2 -> (title, author)
3 -> VALUES
4 -> ("你看得到我打在屏幕上的字,看不到我落在键盘上的泪。", "画船听雨");
5
6INSERT INTO tbl
7 -> (title, author)
8 -> VALUES
9 -> ("成功的花,人们只惊羡她现时的明艳!然而当初她的芽儿,浸透了奋斗的泪泉,洒遍了牺牲的血雨。", "冰心");
10
11INSERT INTO tbl
12 -> (title, author)
13 -> VALUES
14 -> ("The quieter you become, the more you are able to hear", "Kali Linux");
更新表中的数据:
1update tbl set title='好好学习 天天向上' WHERE author='画船听雨';
删除表中的数据:
1delete from tbl where id=1;
查询操作
select
直接使用 select 查询任意字符串或者函数:
1mysql> select 'Hello World';
2+-------------+
3| Hello World |
4+-------------+
5| Hello World |
6+-------------+
71 row in set (0.00 sec)
也可以带入相关的函数查询:
1mysql> select user(),version(),database();
2+------------------+-----------+------------+
3| user() | version() | database() |
4+------------------+-----------+------------+
5| root@10.211.55.2 | 5.5.53 | test |
6+------------------+-----------+------------+
71 row in set (0.00 sec)
也可以查询数据表中的信息:
1select * from tbl; -- 所有值
2select title from tbl; -- 查询title的值
3select author from tbl; -- 查询author的值
4select id,title,author from tbl; -- 等同于 * 查询
mysql 允许 select 语句没有 from
作用:判断列回显的位置
语法:select 常量
where
精确查询,默认是无法区分大小写的,如果要区分大小的的话,只需要在 where 的后面加个 binary 就可以了
1select author from tbl where anthor='冰心'; #查询作者为冰心的内容
like
模糊查询,默认是无法区分大小写的,如果要区分大小的的话,只需要在 like 的后面加个 binary 就可以了
1select * from tbl where author like 'a%';
2select * from tbl where author like binary 'a%';
union
连接两个以上的 SELECT 语句的结果组合到一个结果集合中,前提列数必须相同
1mysql> select * from users union select version(),database(),user();
2+--------+----------+------------------+
3| id | username | password |
4+--------+----------+------------------+
5| 1 | Dumb | Dumb |
6| 2 | Angelina | I-kill-you |
7| 3 | Dummy | p@ssword |
8| 4 | secure | crappy |
9| 5 | stupid | stupidity |
10| 6 | superman | genious |
11| 7 | batman | mob!le |
12| 8 | admin | admin |
13| 9 | admin1 | admin1 |
14| 10 | admin2 | admin2 |
15| 11 | admin3 | admin3 |
16| 12 | dhakkan | dumbo |
17| 14 | admin4 | admin4 |
18| 5.5.53 | security | root@10.211.55.2 |
19+--------+----------+------------------+
2014 rows in set (0.00 sec)
order by
将查询的结果按照指定的列数进行排序
1# 按照id升序排序
2select * from users order by id asc;
3
4# 按照id降序排序
5select * from users order by id desc;
6
7# 根据第1个字段排序
8mysql> select * from users order by 1;
9+----+----------+------------+
10| id | username | password |
11+----+----------+------------+
12| 1 | Dumb | Dumb |
13| 2 | Angelina | I-kill-you |
14| 3 | Dummy | p@ssword |
15| 4 | secure | crappy |
16| 5 | stupid | stupidity |
17| 6 | superman | genious |
18| 7 | batman | mob!le |
19| 8 | admin | admin |
20| 9 | admin1 | admin1 |
21| 10 | admin2 | admin2 |
22| 11 | admin3 | admin3 |
23| 12 | dhakkan | dumbo |
24| 14 | admin4 | admin4 |
25+----+----------+------------+
26
27# 根据第2个字段排序
28mysql> select * from users order by 2;
29+----+----------+------------+
30| id | username | password |
31+----+----------+------------+
32| 8 | admin | admin |
33| 9 | admin1 | admin1 |
34| 10 | admin2 | admin2 |
35| 11 | admin3 | admin3 |
36| 14 | admin4 | admin4 |
37| 2 | Angelina | I-kill-you |
38| 7 | batman | mob!le |
39| 12 | dhakkan | dumbo |
40| 1 | Dumb | Dumb |
41| 3 | Dummy | p@ssword |
42| 4 | secure | crappy |
43| 5 | stupid | stupidity |
44| 6 | superman | genious |
45+----+----------+------------+
group by
分组排序,假设有数据如下:
1+----+--------+---------------------+--------+
2| id | name | date | singin |
3+----+--------+---------------------+--------+
4| 1 | 小明 | 2016-04-22 15:25:33 | 1 |
5| 2 | 小王 | 2016-04-20 15:25:47 | 3 |
6| 3 | 小丽 | 2016-04-19 15:26:02 | 2 |
7| 4 | 小王 | 2016-04-07 15:26:14 | 4 |
8| 5 | 小明 | 2016-04-11 15:26:40 | 4 |
9| 6 | 小明 | 2016-04-04 15:26:54 | 2 |
10+----+--------+---------------------+--------+
使用分组排序:
1mysql> SELECT name, COUNT(*) FROM table GROUP BY name;
2+--------+----------+
3| name | COUNT(*) |
4+--------+----------+
5| 小丽 | 1 |
6| 小明 | 3 |
7| 小王 | 2 |
8+--------+----------+
93 rows in set (0.01 sec)
limit
限制查询的结果显示
1mysql> select * from users order by id;
2+----+----------+------------+
3| id | username | password |
4+----+----------+------------+
5| 1 | Dumb | Dumb |
6| 2 | Angelina | I-kill-you |
7| 3 | Dummy | p@ssword |
8| 4 | secure | crappy |
9| 5 | stupid | stupidity |
10| 6 | superman | genious |
11| 7 | batman | mob!le |
12| 8 | admin | admin |
13| 9 | admin1 | admin1 |
14| 10 | admin2 | admin2 |
15| 11 | admin3 | admin3 |
16| 12 | dhakkan | dumbo |
17| 14 | admin4 | admin4 |
18+----+----------+------------+
19
20# 从第1条数据查询 查询2个数据
21mysql> select * from users order by id limit 0,2;
22+----+----------+------------+
23| id | username | password |
24+----+----------+------------+
25| 1 | Dumb | Dumb |
26| 2 | Angelina | I-kill-you |
27+----+----------+------------+
28
29# 从第2条数据查询 查询6个数据
30mysql> select * from users order by id limit 1,6;
31+----+----------+------------+
32| id | username | password |
33+----+----------+------------+
34| 2 | Angelina | I-kill-you |
35| 3 | Dummy | p@ssword |
36| 4 | secure | crappy |
37| 5 | stupid | stupidity |
38| 6 | superman | genious |
39| 7 | batman | mob!le |
40+----+----------+------------+
regexp
在前面已经了解到 MySQL 可以通过 LIKE ...% 来进行模糊匹配。
MySQL 同样也支持正则表达式的匹配, MySQL 中使用 REGEXP 操作符来进行正则表达式匹配。
1# 查询所有 username 以 a 开头的数据
2select * from users where username REGEXP '^a';
3
4# 查询所有 username 以 a 结尾的数据
5select * from users where username REGEXP 'a$';
6
7# 查询所有 username 包含 a 的数据
8select * from users where username REGEXP 'a';
9
10# 查询所有 username 0-9 结尾的数据
11mysql> select * from users where username regexp '[0-9]$';
12+----+----------+----------+
13| id | username | password |
14+----+----------+----------+
15| 9 | admin1 | admin1 |
16| 10 | admin2 | admin2 |
17| 11 | admin3 | admin3 |
18| 14 | admin4 | admin4 |
19+----+----------+----------+
204 rows in set (0.00 sec)
as
起别名
1mysql> select version();
2+-----------+
3| version() |
4+-----------+
5| 5.5.53 |
6+-----------+
7
8mysql> select version() as '版本';
9+--------+
10| 版本 |
11+--------+
12| 5.5.53 |
13+--------+
MySQL常用函数
MySQL 有很多内置的函数,灵活运行可以提高手工注入的效率。
参考文档:https://dev.mysql.com/doc/refman/5.7/en/
系统信息函数
| 函数 |
说明 |
| SELECT version(); |
返回当前 MySQL 数据库的版本信息 |
| SELECT database(); |
返回当前正在使用的数据库名称 |
| SELECT schema(); |
返回当前正在使用的数据库名称(与 database () 功能相同) |
| SELECT user(); |
返回当前登录的用户信息 |
| SELECT current_user(); |
返回当前登录的用户信息 |
| SELECT session_user(); |
返回当前登录的用户信息 |
| SELECT system_user(); |
返回当前登录的用户信息 |
| SHOW processlist; |
查看当前用户的连接信息,包括进程 ID、用户、主机、数据库、命令等 |
| SELECT @@datadir; |
返回 MySQL 数据库的数据存储路径 |
| SELECT @@basedir; |
返回 MySQL 数据库的安装路径 |
| SELECT @@version_compile_os; |
返回编译 MySQL 时所使用的操作系统信息 |
| SELECT md5(233); |
返回对字符串 "233" 进行 MD5 加密后的结果 |
1# 返回数据库版本
2mysql> select version();
3+-----------+
4| version() |
5+-----------+
6| 5.5.53 |
7+-----------+
8
9# 返回当前数据库名
10mysql> select database();
11+------------+
12| database() |
13+------------+
14| security |
15+------------+
16
17# 返回当前使用的数据库
18mysql> select schema();
19+----------+
20| schema() |
21+----------+
22| security |
23+----------+
24
25# 返回当前用户
26mysql> select user();
27+----------------+
28| user() |
29+----------------+
30| root@localhost |
31+----------------+
32
33# 返回当前用户
34mysql> select current_user();
35+----------------+
36| current_user() |
37+----------------+
38| root@localhost |
39+----------------+
40
41# 返回当前用户
42mysql> select session_user();
43+----------------+
44| session_user() |
45+----------------+
46| root@localhost |
47+----------------+
48
49# 返回当前用户
50mysql> select system_user();
51+----------------+
52| system_user() |
53+----------------+
54| root@localhost |
55+----------------+
56
57# 查看当前用户连接信息
58mysql> show processlist;
59+----+------+-------------------+----------+---------+------+-------+------------------+
60| Id | User | Host | db | Command | Time | State | Info |
61+----+------+-------------------+----------+---------+------+-------+------------------+
62| 1 | root | 10.211.55.2:51246 | security | Query | 0 | NULL | show processlist |
63| 2 | root | localhost:49948 | NULL | Sleep | 7 | | NULL |
64+----+------+-------------------+----------+---------+------+-------+------------------+
65
66# 数据库存放的路径
67mysql> select @@datadir;
68+--------------------------------------+
69| @@datadir |
70+--------------------------------------+
71| C:\myphp_www\PHPTutorial\MySQL\data\ |
72+--------------------------------------+
73
74# MySQL安装路径
75mysql> select @@basedir;
76+---------------------------------+
77| @@basedir |
78+---------------------------------+
79| C:/myphp_www/PHPTutorial/MySQL/ |
80+---------------------------------+
81
82# 操作系统
83mysql> select @@version_compile_os;
84+----------------------+
85| @@version_compile_os |
86+----------------------+
87| Win32 |
88+----------------------+
89
90# 返回md5加密后的字符串
91mysql> select md5(233);
92+----------------------------------+
93| md5(233) |
94+----------------------------------+
95| e165421110ba03099a1c0393373c5b43 |
96+----------------------------------+
数学函数
| 函数 |
说明 |
| FLOOR(X) |
返回不大于X的最大整数。 |
| RAND() |
返回0~1的随机数 |
| ROUND(X) |
返回离X最近的整数,截断时要进行四舍五入。 |
1mysql> SELECT FLOOR(3.5);
2+------------+
3| FLOOR(3.5) |
4+------------+
5| 3 |
6+------------+
7
8mysql> select round(1.4);
9+------------+
10| round(1.4) |
11+------------+
12| 1 |
13+------------+
141 row in set (0.00 sec)
15
16mysql> select round(1.5);
17+------------+
18| round(1.5) |
19+------------+
20| 2 |
21+------------+
221 row in set (0.00 sec)
聚合函数
| 函数 |
说明 |
| COUNT(expr) |
返回查询结果的行数 |
| CONCAT(s1,s2...sn) |
将字符串 s1,s2 等多个字符串合并为一个字符串 |
| CONCAT_WS(x, s1,s2...sn) |
同 CONCAT(s1,s2,...) 函数,但是每个字符串直接要加上 x,x 可以是分隔符 |
| GROUP_CONCAT(exp1,exp2) |
将多行数据合并为单个字符串(使用英文逗号分隔,结果有长度限制,默认约 1024 字节) |
| MAX(c) |
返回指定列c中的最大值 |
| MIN(c) |
返回指定列c中的最小值 |
| SUM(c) |
返回指定列值c的总和 |
| AVG(c) |
返回指定列c数据的平均值 |
1mysql> select count(*) from users;
2+----------+
3| count(*) |
4+----------+
5| 13 |
6+----------+
7
8mysql> select concat(user(),version(),database());
9+------------------------------------------+
10| concat(user(),version(),database()) |
11+------------------------------------------+
12| root@localhost5.7.26sys |
13+------------------------------------------+
14
15mysql> select concat(user(),' ',version(),' ',database()) as xxx;
16+------------------------------------------+
17| xxx |
18+------------------------------------------+
19| root@localhost 5.7.26 sys |
20+------------------------------------------+
21
22mysql> select CONCAT_WS('~',user(),version(),database()) as xxx;
23+------------------------------------------+
24| xxx |
25+------------------------------------------+
26| root@localhost~5.7.26~sys |
27+------------------------------------------+
28
29mysql> select group_concat(name) as all_names from students;
30+----------------+
31| all_names |
32+----------------+
33| 张三,李四,王五 |
34+----------------+
35
36mysql> SELECT GROUP_CONCAT(username, ':', password SEPARATOR ', ') as info FROM users;
37+----------------------------------+
38| info |
39+----------------------------------+
40| test:test, demo:demo123, 123:123 |
41+----------------------------------+
日期时间函数
| 函数 |
说明 |
| CURDATE()、CURRENT_DATE() |
返回当前日期,格式:yyyy-MM-dd |
| CURTIME()、CURRENT_TIME() |
返回当前时间,格式:HH:mm:ss |
| NOW() |
返回当前日期和时间,格式:yyyy-MM-dd HH:mm:ss |
编码转换函数
| 函数 |
说明 |
| ASCII(s) |
返回字符串 s 的第一个字符的 ASCII 码 |
| BIN(X) |
返回X的二进制信息 |
| CONV(N,from_base,to_base) |
将N从from_base转换成to_base格式 |
| HEX(X) |
返回X的十六进制信息 |
| MD5(X) |
返回X的MD5信息 |
| UNHEX(X) |
对X进行十六进制解码 |
1mysql> select ascii(version());
2+------------------+
3| ascii(version()) |
4+------------------+
5| 53 |
6+------------------+
7
8mysql> select hex('MySQL');
9+--------------+
10| hex('MySQL') |
11+--------------+
12| 4D7953514C |
13+--------------+
141 row in set (0.00 sec)
15
16mysql> select unhex('4D7953514C');
17+---------------------+
18| unhex('4D7953514C') |
19+---------------------+
20| MySQL |
21+---------------------+
221 row in set (0.01 sec)
23
24
25mysql> select x'4D7953514C';
26+---------------+
27| x'4D7953514C' |
28+---------------+
29| MySQL |
30+---------------+
311 row in set (0.00 sec)
32
33mysql> select 0x4D7953514C;
34+--------------+
35| 0x4D7953514C |
36+--------------+
37| MySQL |
38+--------------+
391 row in set (0.00 sec)
40
41
42mysql> select hex(233);
43+----------+
44| hex(233) |
45+----------+
46| E9 |
47+----------+
48
49mysql> select conv('E9',16,10);
50+------------------+
51| conv('E9',16,10) |
52+------------------+
53| 233 |
54+------------------+
55
56mysql> select conv('E9',16,2);
57+-----------------+
58| conv('E9',16,2) |
59+-----------------+
60| 11101001 |
61+-----------------+
62
63mysql> select conv('E9',16,8);
64+-----------------+
65| conv('E9',16,8) |
66+-----------------+
67| 351 |
68+-----------------+
字符串函数
| 函数 |
说明 |
| LENGTH(s) |
返回字符串 s 的字节长度 |
| CHAR_LENGTH(s) |
返回字符串 s 的字符长度 |
| INSERT(s1,x,len,s2) |
返回字符串 s1,子字符串起始于 x 位置,并且用 len 个字符长的字符串代替 s2 |
| LOWER(s) |
将字符串 s 中的字母字符全部转换成小写 |
| UPPER(s) |
将字符串 s 中的字母字符全部转换成大写 |
| MID(s,n,len) |
从字符串 s 的 start 位置截取长度为 length 的子字符串 |
| LEFT(s,n) |
返回字符串 s 的前 n 个字符 |
| RIGHT(s,n) |
返回字符串 s 的后 n 个字符 |
| RTRIM(s) |
返回字符串 s 的后 n 个字符 |
| STRCMP(s1,s2) |
比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 |
| SUBSTR(s, start, length) |
从字符串 s 的 start 位置截取长度为 length 的子字符串 |
| TRIM(s) |
去掉字符串 s 开始和结尾处的空格 |
| RTRIM(s) |
去掉字符串 s 结尾处的空格 |
| REPLACE(s,s1,s2) |
使用字符串 s2 替换字符串 s 中所有的字符串 s1 |
| REVERSE(s) |
将字符串 s 反转,返回的字符串的顺序和 s 字符串的顺序相反 |
流程函数
| 函数名称 |
作用 |
| IF(expr,v1,v2) |
判断,如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2 |
| IFNULL(v1,v2) |
判断是否为空,如果 v1 不为 NULL,则 IFNULL 函数返回 v1; 否则返回 v2 的结果。 |
| CASE |
搜索语句 |
1mysql> SELECT if(LEFT(user(),4)='root','root','not root') as is_root;
2+---------+
3| is_root |
4+---------+
5| root |
6+---------+
MySQL运算符
MySQL 支持 4 种运算符,分别是:
- 算术运算符
执行算术运算,例如:加、减、乘、除等。
- 比较运算符
包括大于、小于、等于或不等于、等等。主要用于数值的比较、字符串的匹配等方面。
- 逻辑运算符
包括与、或、非和异或、等逻辑运算符。其返回值为布尔型,真值(1 或 true)和假值(0 或 false)。
- 位运算符
包括按位与、按位或、按位取反、按位异或、按位左移和按位右移等位运算符。位运算必须先将数据转换为补码,然后在根据数据的补码进行操作。运算完成后,将得到的值转换为原来的类型(十进制数),返回给用户。
算术运算符
| 运算符 |
作用 |
使用方法 |
| + |
加法运算 |
用于获得一个或多个值的和 |
| - |
减法运算 |
用于从一个值中减去另一个值 |
| * |
乘法运算 |
使数字相乘,得到两个或多个值的乘积 |
| / 或 DIV |
除法运算,返回商 |
用一个值除以另一个值得到商 |
| % 或 MOD |
求余运算,返回余数 |
用一个值除以另一个值得到余数 |
除法运算和模运算中,如果除数为0,将是非法除数,返回结果为NULL。
1mysql> select 1+2;
2+-----+
3| 1+2 |
4+-----+
5| 3 |
6+-----+
7
8mysql> select 1-2;
9+-----+
10| 1-2 |
11+-----+
12| -1 |
13+-----+
14
15mysql> select 2*3;
16+-----+
17| 2*3 |
18+-----+
19| 6 |
20+-----+
21
22mysql> select 2/3;
23+--------+
24| 2/3 |
25+--------+
26| 0.6667 |
27+--------+
28
29mysql> select 10 DIV 4;
30+----------+
31| 10 DIV 4 |
32+----------+
33| 2 |
34+----------+
35
36mysql> select 10 MOD 4;
37+----------+
38| 10 MOD 4 |
39+----------+
40| 2 |
41+----------+
比较运算符
SELECT 语句中的条件语句经常要使用比较运算符。通过这些比较运算符,可以判断表中的哪些记录是符合条件的。比较结果为真,则返回 1,为假则返回 0,比较结果不确定则返回 NULL。
| 符号 |
描述 |
备注 |
| = |
等于 |
无 |
| <>, != |
不等于 |
无 |
| > |
大于 |
无 |
| < |
小于 |
无 |
| <= |
小于等于 |
无 |
| >= |
大于等于 |
无 |
| BETWEEN |
在两值之间 |
>=min&&<=max |
| NOT BETWEEN |
不在两值之间 |
无 |
| IN |
在集合中 |
无 |
| NOT IN |
不在集合中 |
无 |
| <=> |
严格比较两个NULL值是否相等 |
两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 |
| LIKE |
模糊匹配 |
无 |
| REGEXP 或 RLIKE |
正则式匹配 |
无 |
| IS NULL |
为空 |
无 |
| IS NOT NULL |
不为空 |
无 |
1# 等于
2mysql> select 2=3;
3+-----+
4| 2=3 |
5+-----+
6| 0 |
7+-----+
8
9mysql> select NULL = NULL;
10+-------------+
11| NULL = NULL |
12+-------------+
13| NULL |
14+-------------+
15
16# 不等于
17mysql> select 2<>3;
18+------+
19| 2<>3 |
20+------+
21| 1 |
22+------+
23
24mysql> select 2!=3;
25+------+
26| 2!=3 |
27+------+
28| 1 |
29+------+
逻辑运算符
逻辑运算符用来判断表达式的真假。如果表达式是真,结果返回 1。如果表达式是假,结果返回 0。
| 运算符 |
作用 |
| NOT 或者 ! |
逻辑非 |
| AND 或者 && |
逻辑与 |
| OR 和 || |
逻辑或 |
| XOR |
逻辑异或 |
1# 与
2mysql> select 2 and 0;
3+---------+
4| 2 and 0 |
5+---------+
6| 0 |
7+---------+
8
9mysql> select 2 and 1;
10+---------+
11| 2 and 1 |
12+---------+
13| 1 |
14+---------+
15
16mysql> select 2 && 0;
17+--------+
18| 2 && 0 |
19+--------+
20| 0 |
21+--------+
22
23
24# 或
25mysql> select 2 or 0;
26+--------+
27| 2 or 0 |
28+--------+
29| 1 |
30+--------+
31
32mysql> select 2 or 1;
33+--------+
34| 2 or 1 |
35+--------+
36| 1 |
37+--------+
38
39mysql> select 0 or 0;
40+--------+
41| 0 or 0 |
42+--------+
43| 0 |
44+--------+
45
46mysql> select 1 || 0;
47+--------+
48| 1 || 0 |
49+--------+
50| 1 |
51+--------+
52
53# 非
54mysql> select not 1;
55+-------+
56| not 1 |
57+-------+
58| 0 |
59+-------+
60
61mysql> select !0;
62+----+
63| !0 |
64+----+
65| 1 |
66+----+
67
68# 异或
69# 如果a、b两个值不相同,则异或结果为1。 如果a、b两个值相同,异或结果为0。
70mysql> select 1 xor 1;
71+---------+
72| 1 xor 1 |
73+---------+
74| 0 |
75+---------+
76
77mysql> select 0 xor 0;
78+---------+
79| 0 xor 0 |
80+---------+
81| 0 |
82+---------+
83
84mysql> select 1 xor 0;
85+---------+
86| 1 xor 0 |
87+---------+
88| 1 |
89+---------+
90
91mysql> select 1 ^ 0;
92+-------+
93| 1 ^ 0 |
94+-------+
95| 1 |
96+-------+
97
98mysql> select 1 ^ null;
99+----------+
100| 1 ^ null |
101+----------+
102| NULL |
103+----------+
位运算符
所谓位运算,就是按照内存中的比特位(Bit)进行操作,这是计算机能够支持的最小单位的运算。
程序中所有的数据在内存中都是以二进制形式存储的,位运算就是对这些二进制数据进行操作。
位运算会先将操作数变成二进制数,进行位运算。然后再将计算结果从二进制数变回十进制数。
| 运算符 |
说明 |
使用形式 |
举例 |
| | |
位或 |
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 位 |
位运算中的 &、|、~ 和逻辑运算中的 &&、||、! 非常相似。
1# 按位与 两个二进位都为1时,结果位才为1
2mysql> select 1 & 2;
3+-------+
4| 1 & 2 |
5+-------+
6| 0 |
7+-------+
8
9mysql> select 1 & 3;
10+-------+
11| 1 & 3 |
12+-------+
13| 1 |
14+-------+
&&是逻辑与 即判断&&两侧的表达式是否都为真,都为真则此&&表达式值为真;
& 是按位与 即将&两侧的数用二进制展开,每一位都求与运算(二进制与运算,跟逻辑与差不多),最后得到的二进制数即为结果;逻辑与结果只讲真和假,而按位与得出的却是实实在在的一个数
11 -> 01
22 -> 10
3 00
4
51 -> 01
63 -> 11
7 01