mysql的理论知识补充

MySQL理论知识补充

  • pymysql其他操作
  • SQL注入
  • 用户管理
  • 事务
  • 视图
  • 触发器
  • 存储过程
  • 函数
  • 索引

pymysql其他操作

import pymysql

# 创建连结对象
con= pymysql.connect(
# 回环地址,默认本机地址
host='127.0.0.1',
# 端口号
port=3306,
user='root',
password='111',
database='df',
# 字符编码
charset='utf8'
# 针对执行增删改操作,自动确认,无需第二次确认
autocommit=True 
)
# 生成游标对象等待输入命令
cursor = con.cursor(cursor=pymysql.cursors.DictCursor)
# 默认可以执行查询操作,查询teacher表
sql='select * from teacher'
# 插入操作,必须经过一次确认才可以执行,第一次或第二次确认在之后,否则会报错
sql2='insert into teacher(name) values("袁老师")' #

查找操作

# 自定义sql语句
sql='select * from teacher where tid=1' 
# 执行sql语句
cursor.execute(sql)
# 获取执行结果
res=cursor.fetchall()
print(res)

 

 增加操作

# 插入操作,必须经过二次确认才可以执行,第一次第二次确认在之后,否则会报错
sql='insert into teacher(tname) values("袁老师")'
# 执行sql语句
cursor.execute(sql)
conn.commit() # 确认 提交

删除操纵

# 删除操作,必须经过二次确认才可以执行,第二次确认在之后,否则会报错
sql='delete from teacher where tid=6'
# 执行sql语句
cursor.execute(sql)
conn.commit()  # 确认 提交

 

修改操作

# 修改操作,必须经过二次确认才可以执行,第二次确认在之后,否则会报错
sql='update teacher set tname="计划吧老师" where tid=5'
# 执行sql语句
cursor.execute(sql)
conn.commit()  # 确认 提交

 影响行数

sql='update teacher set tname="计划老师" where tid=5'
# 执行sql语句
affect_rows=cursor.execute(sql)
print(affect_rows) 
conn.commit()  # 确认 提交
'''
输出为一
内部操作只改变了一行
'''

数据显示

显示所有数据

# 自定义sql语句
sql='select * from teacher'
# 执行sql语句
cursor.execute(sql)
# 显示一条数据
print(cursor.fetchall())
# 但在此显示时为空,类似于文件独学而里的光标操作
print(cursor.fetchall())

显示一条数据

# 自定义sql语句
sql='select * from teacher'
# 执行sql语句
cursor.execute(sql)
# 显示一条数据
print(cursor.fetchone())

显示几条数据

# 语法
变量名.fetchmany(x) 显示x个值

sql='select * from teacher'
# 执行sql语句
cursor.execute(sql)
# 显示两条数据
print(cursor.fetchmany(2))

 读取移动(类似于文件光标移动)

# 执行sql语句
cursor.execute(sql)
# 当前位置左右移动 正数往右 负数往左
cursor.scroll(2,'absolute')
print(cursor.fetchone())
# 起始位置左右移动 正数往右 负数往左 
cursor.scroll(1,'relative')
print(cursor.fetchone())

 

 

 

 代替;

delimiter $$

 

SQL注入

前期准备

构造一个登录界面

import pymysql

# 1.先获取用户名和密码
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 2.链接MySQL
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123',  # 支持简写passwd
    database='df',  # 支持简写db
    charset='utf8',
    autocommit=True  # 自动确认
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 3.拼接查询sql语句
sql = "select * from userinfo where name='%s' and password='%s'" %(username,password)
cursor.execute(sql)# 判断输入是否成功
if res: print(res, '登录成功') else: print('用户名或密码错误')

 

数据库内数据

现象1

只输入用户名jason' -- adsdsfewfvwq

 

 

 

 现象2

只输入用户名xxx' or 1=1 -- kjancjqdncjqcjk

 

 

 

 注入理论

通过特殊字符和特俗语法的组合来实现登陆成功
# 如何解决上述现象
    在sql注册过程中涉及到关键数据时不要手动输入
    交由固定方法拼接

 

解决方法

# 将原先代码跟改成这样
sql = "select * from userinfo where name=%s and password=%s" 
# execute可以自动识别
cursor.execute(sql,(username,password))

 

补充多表插入

# 已登录为例,插入多个数据
cursor.executemany(sql, [('jason', 123), ('jason1', 123), ('jason2', 321), ('jason3', 222)])

 

用户管理

创建用户

creater user 用户名 identified by '密码'# 修改密码
set password for 用户名 =password('新密码');
set password = password('新密码');  # 针对当前用户 

 

重命名

rename user 新用户名 to 旧的名;

 

删除用户

drop user 用户名;

 

查看用户访问权限

show grants for 用户名;
# 新创建的用户没有任何权限

 

授予和撤销权限

# 授予用户对某数据库下所有表使用select权限
grant select on 库名.* to 用户名;
# 整个服务器
grant all/revoke all on ...
# 整个数据库
on 库名.* 
# 特定表
on 库名.t1
# 撤销权限 revoke select on db1.* from 用户名;

 

事务

四大特性:ACID
    A:原子性
        每一个事物都是整体,不可分割的,事物中的多条代码同时执行同时失败
    C:一致性
        事物会将内部数据从一种一致的状态转换到另一种一致的状态
    I:独立性
        事物之间互相独立,互不干涉
    D:永久性
        事物内的数据改变、确定之后,将会是永久不变的

eg:
    create table user(
    id int primary key auto_increment,
    name char(32),
    balance int
);

insert into user(name,balance)
values
('jason',1000),
('kevin',1000),
('tony',1000);

 

数据修改

# 修改数据之前先开启事务操作
start transaction;

# 修改操作
update user set balance=800 where name='jason';
update user set balance=1100 where name='kevin';
update user set balance=1100 where name='tony';# 回退到上一个状态
rollback;
# 确认事物没有问题
commit;  # 确认之后无法回退 
select * from user;

 

修改数据前

修改数据后

 

视图

什么是视图

通过查询得到的表,进行保存,可以重复使用该表

 

为什么要使用视图 

如果要频繁使用一张虚拟表,可以不用重复查询

如何使用试图

# 视图虽然好不推荐使用    
eg:
# 将联表结果作为teabcher2course视图
create view teacher2course as select
* from teacher inner join course on teacher.tid = course.teacher_id;

 

触发器

在满足对某张表数据的增、删、改的情况下,自动触发的功能称之为触发器

# 为何要用触发器
    触发器专门针对我们对某一张表数据增insert(前后)、删delete(前后)、改update(前后)的行为
这类行为一旦执行就会触发触发器的执行,即自动运行另外一段sql代码

 

语法:

create trigger 触发器的名字 before/after insert/update/delete on 表名 for each row
begin
    sql语句
end
针对触发器的名字有一个小习惯
    tri_before_insert_t1
        触发器简写_之前或之后_操作_表名
# 删除触发器
drop 触发器的名字

 

 

存储过程

类似于python中的自定义函数

语法:

# 用‘$$’代替;
delimiter $$
# 创建
create procedure p1()
begin
    select * from cmd;
end $$
delimiter ;

# 调用
call p1()

 

 

函数

相对于pythpn中的内置方法
"ps:可以通过help 函数名    查看帮助信息!"

移除指定字符

Trim、LTrim、RTrim

 

trim语法:

mysql> SELECT TRIM('  bar   ');
        -> 'bar'
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'

 

ltrim语法:

mysql> SELECT LTRIM('  barbar');
        -> 'barbar'

 

rtrim语法:

mysql> SELECT RTRIM('barbar   ');
        -> 'barbar'

大小写转换

Lower、Upper

获取左右起始指定个数字符

Left、Right

返回读音相似值(对英文效果)

eg:客户表中有一个顾客登记的用户名为J.Lee
        但如果这是输入错误真名其实叫J.Lie,可以使用soundex匹配发音类似的
        where Soundex(name)=Soundex('J.Lee')

日期格式:date_format

'''
在MySQL中表示时间格式尽量采用2022-11-11形式
mysl中年月日识别与python中相同
''' CREATE TABLE blog ( id INT PRIMARY KEY auto_increment, NAME CHAR (32), sub_time datetime ); INSERT INTO blog (NAME, sub_time) VALUES ('第1篇','2015-03-01 11:31:21'), ('第2篇','2015-03-11 16:31:21'), ('第3篇','2016-07-01 10:21:31'), ('第4篇','2016-07-22 09:23:21'), ('第5篇','2016-07-23 10:11:11'), ('第6篇','2016-07-25 11:21:31'), ('第7篇','2017-03-01 15:33:21'), ('第8篇','2017-03-01 17:32:21'), ('第9篇','2017-03-01 18:31:21'); # 以年月分租,输出年与月 select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');

 

select date_format(sub_time,'%Y-%m-%d'),count(id) from blog where date(sub_time) = '2015-03-01';

select date_format(sub_time,'%Y-%m'),count(id) from blog where Year(sub_time)=2016 AND Month(sub_time)=07;

 

其他操作

# 更多日期处理相关函数 
    adddate    增加一个日期 
    addtime    增加一个时间
    datediff    计算两个日期差值
    ...

流程控制

if语句

# i等于1时执行
    if i = 1 THEN
        SELECT 1;
# i等于2时执行
    ELSEIF i = 2 THEN
        SELECT 2;
# 其他结果时    
    ELSE
        SELECT 7;
# 结束if程序
    END IF;

 

 while循环语句

# 临界值num
set num =0;
# 当num小于10时循环
while num < 10 DO
# 执行命令
    select
        num ;
# num值加一
    set num = num + 1 ;
# 结束循环
end while ;

 

索引

什么是索引

索引就是一种数据结构,类似于书的目录。
    意味着以后在查数据应该先找目录再找数据,而不是用翻页的方式查询数据

索引表中的存在形式

索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构(b树,b*树,b+树,红黑树)

  主键 primary key
        除了可以加快查询之外还有其他的功能
    唯一键 unique
        除了可以加快查询之外还有其他的功能
    索引键 index key
        除了可以加快查询之外没有其他的功能
    外键     foreign key
        跟索引半毛钱关系都没有 也不存在提升查询速度一说

 

索引带来的消极影响

    在表中有大量数据的前提下,创建索引速度会很慢
    在索引创建完毕后,对表的查询性能会大幅度提升,但是写的性能会降低

 

索引分类

聚集索引(primary key)
    叶子结点放的一条条完整的记录
辅助索引(unique,index)
    叶子结点存放的是辅助索引字段对应的那条记录的主键的值
    
# 覆盖索引
    只在辅助索引的叶子节点中就已经找到了所有我们想要的数据
     select name from user where name='jason';
# 非覆盖索引
    虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找
     select age from user where name='jason';

 

posted @ 2021-09-11 22:39  微纯册  阅读(32)  评论(0编辑  收藏  举报