07_MySQL笔记-GRANT-REVOKE-INSERT-UPDATE-DELETE-TRUNCATE-事务

Posted mycpen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了07_MySQL笔记-GRANT-REVOKE-INSERT-UPDATE-DELETE-TRUNCATE-事务相关的知识,希望对你有一定的参考价值。

文章目录


个人博客
https://blog.csdn.net/cPen_web


Python里连接mysql的库
	mysql-connector
	records
	pymysql
Python3 MySQL 数据库连接 - PyMySQL
详细步骤	https://www.runoob.com/python3/python3-mysql.html
步骤:安装PyMySQL
[root@cPen ~]# pip3 install pymysql

步骤:实例链接 Mysql 的 jd 数据库
[root@cPen ~]# python3
>>> import pymysql						# 打开数据库连接 ↓ 
>>> db = pymysql.connect(host="192.168.1.11",user="jd",password="Sanchuang123#",database="jd")
>>> cursor = db.cursor()				#注:创建一个游标
	#注:游标:是mysql里的缓存空间 --> 类似 大使馆
>>> cursor.execute("select version()")	# 使用 execute() 方法执行 SQL 查询 
1
>>> data = cursor.fetchone()			# 使用 fetchone() 方法获取单条数据. 
>>> print(data)
('5.7.32',)
>>> db.close()							# 关闭数据库连接 

root@(none) mysql>create user 'stone'@'127.0.0.1' identified by '123456';
root@(none) mysql>create user 'stone'@'192.168.1.11' identified by '123456';
以上创建的2个用户,使用下面的方式登录不了

[root@cPen lianxi]# mysql -ustone -p'123456';
ERROR 1045 (28000): Access denied for user 'stone'@'localhost' (using password: YES)
#注:其实是使用文件socket的方式连接到mysqld进程,进行数据交互
stone@localhost
root@(none) mysql>select host,user from mysql.user;
+--------------+---------------+
| host         | user          |
+--------------+---------------+
| 127.0.0.1    | stone         |
| 192.168.1.11 | stone         |
| localhost    | root          |
+--------------+---------------+
root@(none) mysql>create user 'stone'@'localhost' identified by '123456';
root@(none) mysql>^DBye

[root@cPen lianxi]# mysql -ustone -p'123456'
stone@(none) mysql>				#注:登录成功

mysql和mariadb的差异

1 .
	mysql登录进去  mysql>
	mariadb登录进去  MariaDB [(none)]>  还可以看到在哪个数据库
2 .
	mysql和mariadb 用户表里的字段 mysql.user
	mariadb存放密码的字段就叫 Password
	mysql存放密码的字段叫 authentication_string

GRANT

with grant option子句

root@localhost
	这个用户可以使用grant语句给其他的用户授权

with grant option子句
	通过在grant语句的最后使用该子句,就允许被授权的用户把得到的权限继续授给其它用户
root@(none) mysql>create user 'heyachen'@'%' identified by '123456';
root@(none) mysql>grant all on *.* to 'heyachen'@'%';
#注:用户有create的权利,但没有grant权利

root@(none) mysql>create user 'huangtao'@'%' identified by '123456';
root@(none) mysql>grant all on *.* to 'huangtao'@'%' with grant option;
root@(none) mysql>select * from mysql.user where user='huangtao' \\G;
            ……
            Grant_priv: Y
#注:用户有grant的权利,可以给别人授权

如何查看授予给某个用户的权限?

SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

root@(none) mysql>show grants;				#注:默认查看当前用户
root@(none) mysql>show grants for 'huangtao';
+-----------------------------------------------------------------+
| Grants for huangtao@%                                           |
+-----------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'huangtao'@'%' WITH GRANT OPTION |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)
	--> 背后查看的是 information_schema.USER_PRIVILEGES 表
root@(none) mysql>show engines;
--> 本质上 查看information_schema.ENGINES 表

示例:知道当前是哪个用户 select user();

root@(none) mysql>select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

或者看前面的提示符

示例:查看mysql版本 select version();

root@(none) mysql>select version();

REVOKE

废除权限 revoke

root@(none) mysql>revoke all on *.* from 'heyachen'@'%';		#注:回收权限
root@(none) mysql>show grants for 'heyachen';
+--------------------------------------+
| Grants for heyachen@%                |
+--------------------------------------+
| GRANT USAGE ON *.* TO 'heyachen'@'%' |
+--------------------------------------+
1 row in set (0.00 sec)
create user 'yangsiting'@'192.168.0.%' identified by '123456'; 
	--> 允许整个192.168.0.0/24网段可以访问
主机名使用localhost还是127.0.0.1?
	使用localhost,是通过socket来连接(文件socket);使用127.0.0.1,是通过tcp/ip来连接(网络socket)
用户具有usage权限意味着“没有权限”,它只表示该用户可以连接到数据库。无法废除该权限

DML

数据操纵语言
select insert delete
DATA MANIPULATION LANGUAGE(数据操纵语言),由INSERT、UPDATE、DELETE等语句构成,用来修改表中的数据

INSERT

# 关键字  for print --> 预用的 --> 预先保留的变量名 keyword
>>> import sys					#注:操纵Python本身
>>> import os					#注:操纵Linux操作系统

>>> import keyword				#注:导入关键字模块
>>> print(keyword.kwlist)		#注:查询所有关键字
>>> print(len(keyword.kwlist))	#注:查询关键字一共多少个
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
insert into TEAMS(TEAMNO,playerno,division) values(3,10,"third")
#注:表名区分大小写,字段名不区分大小写

INSERT TEAMS VALUES(4,8,"fourth")
insert TEAMS values(5,"fifth",9)		#注:会出错

#注:SQLyog  右击 改变表 --> 查看表结构
-----------------------------------------------------------------
2、在表名后面省略所有的列名
这种写法要求VALUES子句中的值必须按照列在表结构中的顺序来一一赋值
INSERT INTO teams
  VALUES(4,104,'third');

-----------------------------------------------------------------
3、在表名后面只列出部分的列名
所有没有明确赋值的列,将通过隐式赋值自动得到null值
例2: 添加一个新球员
INSERT INTO players(playerno,NAME,initials,sex,joined,street,town)
  VALUES(611,'Jones','GG','M',1997,'Green Way','Stratford');
#注:没指定的列 它的值都为null
	SQL语句之间接;分号,单独执行1条可以不接

-----------------------------------------------------------------

count(*) --> count() 是一个统计函数,统计某列有多少行数据
*  代表 列名 --> 字段名

root@TENNIS mysql>select name,town,joined,playerno from PLAYERS;
root@TENNIS mysql>select name,town,joined,playerno from PLAYERS where joined=1980;
#示例:统计行数 (所有显示的字段有多少行) --> 输出出来行的数量
root@TENNIS mysql>select name,town,joined,playerno,count(*) from PLAYERS where joined=1980;
+-----------+-----------+--------+----------+----------+
| name      | town      | joined | playerno | count(*) |
+-----------+-----------+--------+----------+----------+
| Newcastle | Inglewood |   1980 |        8 |        3 |
+-----------+-----------+--------+----------+----------+
1 row in set (0.00 sec)
sum() --> 求和函数
sum(amount) --> 里面放的列名,将所有的值相加
root@TENNIS mysql>select sum(amount) from PENALTIES;
+-------------+
| sum(amount) |
+-------------+
|      480.00 |
+-------------+
1 row in set (0.00 sec)
#注:SQL语句操纵的是列
root@TENNIS mysql>select sum(amount) from PENALTIES where amount >50;
VALUES子句中除了字面量(#注:即固定的值),还可以使用函数、计算、标量子查询等
INSERT INTO totals(numberplayers,sumpenalties)
  VALUES((SELECT count(*) FROM players),
                 (SELECT sum(amount) FROM penalties));
注意:子查询必须放在单独的小括号中
	#注:子查询 --> 先执行子查询,再执行外层的
#示例:统计有多少用户 (小圆括号 相当于子查询)
[root@cPen ~]# usernum=$(cat /etc/passwd |wc -l)
[root@cPen ~]# echo $usernum 
21
[root@cPen ~]# echo $(cat /etc/passwd |wc -l)
21
[root@cPen ~]# echo `cat /etc/passwd |wc -l`
21
#注:反引号不能嵌套,$()更好
一条INSERT语句可以插入多个行,用,逗号隔开
INSERT INTO teams(teamno,playerno,division)
  VALUES (6,7,'third'),
            (7,27,'fourth'),
            (8,39,'fourth'),
            (9,112,'sixth'); 	
带子查询的INSERT语句
将联盟会员号为空的球员插入到recr_players表中
INSERT INTO recr_players
  (SELECT  playerno, NAME, town, phoneno
   FROM  players
  WHERE  leagueno IS NULL);4 行受到影响
#注:将select查询的结果插入到表里去。先子查询select,然后再把值传给insert语句
把那些罚款额大于平均罚款额的所有罚款添加到penalties表中
INSERT INTO penalties
  SELECT paymentno + 100,playerno,payment_date,amount
       FROM penalties
      WHERE amount > (SELECT avg(amount)
                        FROM penalties);4 行受到影响
#示例:查询联盟编号是null值的
select * from PLAYERS where LEAGUENO IS NULL;
select * from PLAYERS where LEAGUENO IS not NULL;
8:把那些罚款额大于平均罚款额的所有罚款添加到penalties表中
INSERT INTO PENALTIES
  SELECT paymentno + 100,playerno,payment_date,amount
       FROM PENALTIES
      WHERE amount > (SELECT avg(amount)
                        FROM PENALTIES);

#注:avg() 通过计算的,必须要用select语句得到
paymentno + 100	是为了避免主键值一样 (主键约束)

需求分析:
	1 .确定 表 --> 罚款表
	2 .确定 字段 --> 球员号和罚款额
	3 .确定 条件 --> 罚款额大于平均罚款额
					avg(amount)

UPDATE

#示例:插入2行数据
root@TENNIS mysql>insert into totals values(20,1000),(30,2000);

#示例:不接where条件语句,会修改所有行
root@TENNIS mysql>update totals set sumpenalties=10000;

#注:工作中误操作怎么恢复:用以前的备份恢复,通过备份回滚,二进制日志 通过日志回滚

#示例:接where条件语句
root@TENNIS mysql>update totals set sumpenalties=480 where numberplayers=15;
1: 把95号球员的联盟会员号码改为2000
	表:球员
	字段:联盟会员号码
	条件:95号球员
	UPDATE PLAYERS SET LEAGUENO='2000' WHERE PLAYERNO=95;
2: 把所有的罚款增加5%
	表:罚款表
	字段:AMOUNT
	条件:所有的行
	UPDATE PENALTIES SET AMOUNT=AMOUNT*1.05;
3: 把住在Stratford的球员的获胜局数设为0 --> 牵扯到 主键、外键、子查询
	表:MATCHES  PLAYERS
	字段:获胜局数
	条件:住在Stratford的球员
		子查询:SELECT PLAYERNO,TOWN FROM PLAYERS WHERE TOWN="Stratford";
	update MATCHES SET won=0 where MATCHES.PLAYERNO IN (SELECT PLAYERNO FROM PLAYERS WHERE TOWN="Stratford");

某个字段的值为NULL 和 空值 有什么区别? 当某个字段类型为字符串的时候

1 .占用空间区别
空值('')的长度是0,是不占用空间的;而的NULL长度是NULL,其实它是占用空间的

2 .插入/查询方式区别
mysql> INSERT tb_test VALUES (NULL,NULL);
mysql> INSERT tb_test VALUES ('','');
如果要单纯查NULL值列,则使用 is NULL去查,单纯去查空值('')列,则使用 =''

3 .COUNT 和 IFNULL函数
总结:使用 COUNT(字段) 统计会过滤掉 NULL 值,但是不会过滤掉空值
说明:IFNULL有两个参数。 如果第一个参数字段不是NULL,则返回第一个字段的值。 否则,IFNULL函数返回第二个参数的值(默认值)

4 .索引字段说明
MySql中如果某一列中含有NULL,那么包含该列的索引就无效了
	1 .存储空间上说明
	NULL值 其实数据库需要在另外地方记录下,这个字段的值为NULL --> NULL值也是值 --> 空气
	空值 是不消耗存储空间的 --> 真空状态
	2 .在count函数统计的时候,NULL值所在的列不计入

root@TENNIS mysql>select name,char_length(name),length(name) from t1;
+------+-------------------+--------------+
| name | char_length(name) | length(name) |
+------+-------------------+--------------+
|      |                 0 |            0 |
| NULL |              NULL |         NULL |
+------+-------------------+--------------+

ORDER BY 排序

	排序是根据字段的内容来排序
升序:从小到大 --> 默认 ASC
降序:从大到小 --> DESC
#示例:根据amount字段来排序,默认升序
root@TENNIS mysql>select * from PENALTIES order by amount;			#注:升序
#示例:排序 --> 降序
root@TENNIS mysql>select * from PENALTIES order by amount DESC;		#注:降序
	UPDATE语句中可以使用ORDER BY子句,要求以排序的顺序来依次更新行。这在某些场景可能有用。例如,如果想要把所有罚款的罚款编号都加1,如果从罚款编号为1的行开始更新,要么就会发生主键值重复异常。如果从罚款编号最大的行开始更新,就没有问题(#注:即降序)。6:把所有罚款的编号增加1
UPDATE  penalties
   SET  paymentno = paymentno + 1
  ORDER BY  paymentno DESC;

LIMIT --> 限量

罚款表 --> 罚款额最高的前3名的球员编号和总罚款金额
	表:罚款表
	字段:sum(amount)
	条件:前3名
分组:group by 接列名
	limit
select playerno,sum(amount) from PENALTIES group by playerno;
select playerno,sum(amount) from PENALTIES group by playerno order by sum(amount) DESC;
select playerno,sum(amount) from PENALTIES group by playerno order by sum(amount) DESC limit 3;
聚合函数:sum()  count()  avg() --> 聚集合成一个值
取第4行、第5limit 3,2
ORDER BY  amount DESC, playerno ASC			#注:罚款金额一样,再根据第2个字段排序
#示例:显示第3行 --> 偏移量offset 2,前面2条不要
root@TENNIS mysql>select * from PENALTIES ORDER BY amount DESC limit 2,1;

root@TENNIS mysql>help select
	[LIMIT [offset,] row_count | row_count OFFSET offset]
	offset		偏移量
	row_count	行数

更新多个表中的值
	#注:可以改多个表,但是一定要有关联条件(主外键),进行连接查询。多表连接,只有外键能确定唯一性
MySQL允许我们使用1条UPDATE语句就更新两个或多个表中的行
8:把一个first分级球队的所有比赛的获胜局数设为0,并把first分级球队的队长编号改为112
UPDATE MATCHES m,TEAMS t
   SET m.won = 0,
       t.playerno = 112
 WHERE t.teamno = m.teamno
   AND t.division = 'first';6 行受到影响 

MySQL首先执行一个二表连接查询,从两个表中找到满足连接条件 t.teamno = m.teamno 的所有行,然后对这些行分别进行更新 
使用一条语句更新多个表的优点是:要么两个表都更新,要么两个表都不更新
8:把一个first分级球队的所有比赛的获胜局数设为0,并把first分级球队的队长编号改为112
UPDATE
	表:TEAMS  MATCHES
	字段:获胜局数 --> MATCHES   队长编号 --> TEAMS
	条件:TEAMNO  first分级球队

update TEAMS t,MATCHES m set m.won=0,t.playerno=112 where t.division="first" and t.teamno=m.teamno;

REPLACE语句

	替代已有的行
	REPLACE语句是INSERT语句的一个变种。当添加新行时,如果主键值重复,那么就覆盖表中已有的行。如果没有主键值重复,则插入该行
#注:replace和insert的区别:如果主键值重复,那么就覆盖表中已有的行
root@TENNIS mysql>insert into t2(id,name) values(1,'cali');
root@TENNIS mysql>insert into t2(id,name) values(1,'cali');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'		#注:Duplicate entry 重复的条目
	entry条目  record记录
	一行记录就是一个条目
#示例:REPLACE
root@TENNIS mysql>replace into t2(id,name) values(1,'califeng');
Query OK, 2 rows affected (0.00 sec)
root@TENNIS mysql>update t2 set name="fengdeyong" where id=1;
Query OK, 1 row affected (0.00 sec)

DELETE

从表中删除满足WHERE条件的所有行。没有WHERE条件,则删除表中的所有行 
#示例:DELETE语句
root@TENNIS mysql>delete from t2;

以上是关于07_MySQL笔记-GRANT-REVOKE-INSERT-UPDATE-DELETE-TRUNCATE-事务的主要内容,如果未能解决你的问题,请参考以下文章

(转)Mysql存储引擎__笔记

MySQL-07-笔记

Oracle学习笔记_07_模糊查询

MySQL学习笔记_10_MySQL高级操作(下)

MySQL InnoDB读书笔记07 MySQL中各种类型文件详解

Hadoop学习笔记-008-CentOS_6.5_64_yum安装mysql