mysql
2022-04-18 14:22:23 26 举报
AI智能生成
mysql基础操作
作者其他创作
大纲/内容
默认配置
[mysql]<br># 设置mysql客户端默认字符集<br>default-character-set=utf8<br>[mysqld]<br>#设置3306端口<br>port = 3306<br># 设置mysql的安装目录<br>basedir=D:\mysql\mysql-5.6.44-winx64<br># 设置mysql数据库的数据的存放目录<br>datadir=D:\mysql\mysql-5.6.44-winx64\data<br># 允许最大连接数<br>max_connections=200<br># 服务端使用的字符集默认为8比特编码的latin1字符集<br>character-set-server=utf8<br># 创建新表时将使用的默认存储引擎<br>default-storage-engine=INNODB
账户相关
create user 'gcs'@'%' identified by '123456';<br># 创建账户并设置密码,%表示所有机器都可以连接
mysql> grant all on *.* to 'gcs'@'%';<br># 全部权限<br>grant 权限类型 on dbname.* for 'user'@'ip'<br>grant all on *.* to 'eva'@'%';<br>grant select<br>grant select, insert<br>flush privileges; # 刷新使授权立即生效
flush privileges;<br># 权限立即生效
show grants for 'gcs'@'%';<br># 查看用户数据库权限<br>+---------------------------------+<br>| Grants for gcs@% |<br>+---------------------------------+<br>| GRANT USAGE ON *.* TO `gcs`@`%` |<br>+---------------------------------+<br><br><br>
mysql> update user set Grant_priv = 'Y', Super_priv = 'Y' where user = 'root';<br>Query OK, 1 row affected (0.00 sec)<br>Rows matched: 2 Changed: 1 Warnings: 0<br><br>mysql> flush privileges;<br>Query OK, 0 rows affected (0.00 sec)
# 处理mysql8.0 远程访问无库权限<br>mysql> use mysql;<br>Database changed<br>mysql> select host, user from user;<br>+--------------+------------------+<br>| host | user |<br>+--------------+------------------+<br>| % | admin |<br>| % | gcs |<br>| % | root |<br>| 172.16.238.4 | guest |<br>| localhost | debian-sys-maint |<br>| localhost | mysql.infoschema |<br>| localhost | mysql.session |<br>| localhost | mysql.sys |<br>| localhost | root |<br>+--------------+------------------+<br>9 rows in set (0.00 sec)<br><br>mysql> grant all on *.* to 'root'@'%';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> grant all on *.* to 'root'@'localhost';<br>Query OK, 0 rows affected (0.00 sec)<br><br>mysql> show grants for 'root'@'%';<br><br>mysql> flush privileges;<br>Query OK, 0 rows affected (0.01 sec)<br>
https://dev.mysql.com/doc/refman/8.0/en/grant.html
https://blog.csdn.net/weixin_43180441/article/details/99685405?ops_request_misc=&request_id=&biz_id=102&utm_term=mysql%3E%20create%20database%20day40;%20&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-99685405.142^v9^pc_search_result_control_group,157^v4^control&spm=1018.2226.3001.4187
存储引擎<br># mysql5.6默认存储引擎Innodb
# Innodb存储引擎(mysql5.6之后的默认存储引擎)<br># 数据和索引存储在一起 2个文件<br> # 数据索引/表结构<br> # 数据持久化<br> # 支持事物:为了保证数据的完整性,将多个操作变成原子性操作(原子性:不可拆分的)<br> # 行级锁:修改的行少的时候使用 -> 修改数据频繁的操作<br> # 表级锁:批量修改多行的时候使用 -> 对于大量数据的同时修改<br> # 支持外键:约束两张表中的关联字段不能随意的添加、删除 -> 能够降低数据增删改的出错率
# 面试题<br> # 你了解mysql的存储引擎么?<br> # 你的项目用了什么存储引擎,为什么?<br> # Innodb<br> # 多个用户操作的过程中对同一张表的数据同时做修改<br> # Innodb支持行级锁,所以我们使用了这个引擎<br> # 为了适应程序未来的扩展性,扩展新功能的时候可能会用到...,涉及到要维护数据的完整性<br> # 项目中有一两张xx表,之间的外间关系是什么,一张表的修改或者删除比较频繁,怕出错所以做了外键约束<br>
补充:<br> # select database() 查看当前库<br> # show engines; # 查看当前版本支持的存储引擎<br> # show variables like '%engine%'<br> # creat table tbname(fdname type) engine = Innodb; 创建表,并指定存储引擎
sql慢查询优化
# 慢查询优化:<br> # 首先从sql的角度优化<br> # 把每一句话单独执行,找到效率低的表,优化这句sql<br> # 了解业务场景,适当的创建索引,帮助查询<br> # 尽量用连表代替子查询<br> # 确认命中索引的情况<br> # 考虑修改表结构<br> # 拆表<br> # 把固定的字段往前调整<br> # 使用执行计划,观察sql的type通过以上调整是否提高<br># mysql的慢日志<br> # 在mysql的配置中开启并设置一下<br> # 在超过设定时间之后,这条sql总是会被记录下来<br> # 这个时候我们可以对这些被记录的sql进行定期优化
如何正确使用mysql数据库
# 正确的使用mysql数据库<br> # 从库的角度<br> # 搭建集群<br> # 读写分离<br> # 分库<br> # 从表的角度<br> # 合理安排哦表于表之间的关系:该拆的拆,该合的合<br> # 把固定长度的字段放在前面<br> # 计量使用char而不是varchar<br> # 从操作数据角度<br> # 尽量在where字段就约束数值到一个比较小的范围: 分页<br> # where a between value1 and value2 (必须建立索引才能快,否则还是全表查)<br> # 尽量使用连表查询代替子查询<br> # 删除数据和修改数据的时候尽量使用主键<br> # 合理的创建和使用索引:<br> # 创建索引<br> # 1.选择区分度比较大的列<br> # 2.尽量选择短的字段创建索引<br> # 3.不要创建没必要的索引,及时删除不用的索引(索引多了b+树的索引位置会多次重新计算,拖慢写入的数据)<br> # 使用索引<br> # 1.查询的字段不是索引字段<br> # 2.在条件中使用范围,结果的范围越大速度越慢,范围越小就快<br> # 3.like 'a%' 命中索引, like'%a' 不命中索引<br> # 4.条件列不能参与计算、不能使用函数<br> # 5.and/or<br> # and条件相连,有一列有索引都会命中<br> # or条件相连,所有列都有索引才能命中<br> # 6.联合索引(重要)<br> # create index mix_ind on 表(id,name,email)<br> # 遵循最左前缀原则,且从出现范围开始索引失效<br> # select * form tbname wehre id = '123'; 命中索引<br> # select * form tbname wehre id > '123'; 不命中索引,出现范围就不会命中<br> # select * from tbname where id = '123' and name = 'alex'; 命中索引<br> # select * from tbname where id > '123' and name = 'alex'; 不命中索引,出现范围就不会命中<br> # select * from tbname where id = '123' and name = 'alex' and email = 'alex@oldboy'; 命中索引<br> # select * from tbname where email = 'alex@oldboy'; 不命中索引,因为条件中没有id<br> # select * from tbname where name = 'alex' and email = 'alex@oldboy'; 不命中索引,因为条件中没有id<br><br> # 7.条件中的数据类型和实际字段的类型必须一致<br> # 8.select字段中应该包含order by的字段<br> # select age from tbname order by age; 快<br> # select name from tbname order by age; 慢,因为select 是在order by 之前查询到的,索引查的快<br><br># 覆盖索引:查询过程中不需要回表<br># select id from tbname where id > 10000;<br># select max(id) from tbname where id > 10000; # 使用函数<br>#<br># 索引合并:分别创建的两个索引某次查询中临时合并成一条索引: a = 1 or b = 2,将a,b都设置成索引列,在使用or的时候就是索引合并<br># 执行计划: explain select 语句,能够查看sql语句有没有按照预期执行,可以查看索引的使用情况,type等级
mysql数据库的备份与恢复
备份和恢复表
# 表和数据的备份<br> # 备份数据在终端命令行直接执行<br> # mysqldump -uroot -p123456 -h172.16.238.4 homework > /home/zew/tem.sql<br><br> # 恢复数据,在mysql中执行命令<br> # 切换到一个要备份的数据库中<br> # sourse /home/zew/tem.sql
备份和恢复库
# 备份库<br> # 备份<br> # mysqldump -uroot -p123456 --databases homework > /home/zew/tem2.sql<br> # 恢复<br> # source /home/zew/tem2.sql<br>
聚集索引与非聚集索引解析<br># 查询时尽量使用主键作为条件
事物
## 多线程或并发情况下,添加锁<br># begin; # 开启事务<br># select * from emp where id = 1 for update; # 查询id值,for update添加行锁;<br># update emp set salary=10000 where id = 1; # 完成更新<br># commit; # 提交事务
字符集
mysql> show variables like '%character%';
查看默认配置<br>
select @@basedir as basePath from dual;<br># 查看mysql的安装目录<br># /usr/
select @@datadir as basePath from dual;<br># 查看mysql的数据目录<br># /var/lib/mysql/
select@@port as port from dual;<br># 查看端口
mysql服务
service mysql status<br># 查看服务状态 <br># Active: active (running)<br># Active: inactive (dead)
service mysql start<br># 启动服务
service mysql stop<br># 停止服务
# service mysql restart<br># 重启服务
建库建表相关
库
mysql> show databases;<br># 查看所有库信息
mysql> use dbname<br># 切换库
mysql> create database dbname;<br># 创建库
mysql> show tables;<br># 查看库下的所有表
mysql> drop database day39;<br># 删除库
表
mysql> desc t1; <br># 部分属性<br>mysql> show create table t1; <br># 查看建表时的全部属性<br>
修改表结构
# 修改表名<br>alter table tbname rename 新名字;
# 添加字段<br>alter table tbname add 字段名 类型(长度) 约束 after 某字段
# 删除某个字段<br>alter table tbname drop 字段名;
# 修改某个字段的类型、约束<br>alter table tbname modify 字段名 类型(长度) 约束
# 修改某个字段的名字、类型、约束<br>alter table tbname change 旧字段名 新名字 类型(长度) 约束
单表的增删改查
# 增<br>insert into tbname (field1, field2, ...) values(field1, field2,...);<br>insert into tbname values(field1, field2...);<br>insert into tbname select * from tbname2 where 条件;
# 删<br>delete from tbname where 条件;<br># 清空表<br>delete from tbname; # 不会清空主键的自增值<br>truncate table tbname; # 会清空表和自增字段的偏移量<br>
# 改<br>update tbname set field = value where 条件;<br>update tbname set field1 = value1, field2 = value2 where 条件; # 修改多个值
# 查<br># as 别名<br># distinct 去重<br># concat(field1, field2) as n # 返回拼接后的字符串 field1+field2<br># concat_ws(分隔符, field1, field2) # 返回指定分隔符后的字段:1|alex|3714|85<br># select 支持四则运算,例如根据月薪求年薪<br># 判断逻辑 case when ... then ... end 相当于if判断语句<br># 聚合函数 min max avg count sum <br># 比较运算符 > < >= <= != <><br># 模糊匹配 like %通配符 _ 占位符<br># 逻辑运算 优先级: not > and > or<br># group by 分组<br># having 分组后的过滤,having中可以使用聚合函数,where中不可以<br># ourder by 排序, asc 升序, desc 降序,默认asc<br># limit 取前几项,limit m, n # 从m+1项开始取,取n项; limit m # 从0开始,取m项
多表查询
定义:通过关联关系创建一张大表,保存两张表的笛卡尔积,再根据条件筛选数据
# 内连接<br>inner join tbname on 关联条件
# 外连接<br># 左外连接<br>left join tbname on 关联条件; # 左外连接以左表为主,右表没有的赋值null<br># 右外连接<br>right join tbname on 关联条件; # 右外连接以右表为主,左表没有的赋值null<br># 全外连接 <br> # oracle: full outer join tbname on 关联条件<br> # mysql 不支持这种方式, 利用union合并左外和右外<br># select * from department d left join employee e on d.id = e.dep_id<br># union<br># select * from department d right join employee e on d.id = e.dep_id;<br><br>
子查询
其中一个查询结果作为另一个select查询的条件,<br>或者其中一个查询结果作为另一个select查询关联的外表
exisits关键字<br># 返回bool值True/False,<br># 返回True时,外层语句执行,返回False时,外层语句不执行
mysql> select * from class where exists (select cid where caption = '一年二班');<br> +-----+--------------+<br> | cid | caption |<br> +-----+--------------+<br> | 3 | 一年二班 |<br> +-----+--------------+<br> 1 row in set (0.00 sec)<br><br> mysql> select * from class where exists (select cid where caption = '一年一班');<br> Empty set (0.00 sec)
sql的执行顺序
# from 找表<br># where 条件, 筛选符合条件的行<br># group by 分组<br># having 分组之后的过滤<br># select 字段 <br># order by 排序<br># limit m, n 取从m+1开始的前n条记录
数据类型(常用)
整型
int 不约束长度,最多表示10位
tinyint unsigned<br># 0~255, 表示年龄使用,现在不常用,直接int即可
unsigned 无符号约束,例如年龄不能为负数
浮点型
float(5,3)<br># 表示,总共5位,小数位3位四舍五入,整数位2位
double(5,3)<br># 表示,总共5位,小数位3位四舍五入,整数位2位<br># 精度比float高,一般情况下float足够了
时间类型
date<br># 年月日
time<br># 时分秒,常用,比如计时类软件
datetime<br># 年月日时分秒,常用
year<br># 年,不常用
timestamp<br># 时间戳,截止到2038年,已经不用了
# mysql> create table t5(<br># -> id int,<br># -> dt datetime NOT NULL # 不能为空<br># DEFAULT CURRENT_TIMESTAMP # 默认是当前时间<br># ON UPDATE CURRENT_TIMESTAMP); # 在更新的时候使用当前时间更新字段<br># 给字段设置默认时间
字符串转换成时间类型<br>str_to_date()<br># select str_to_date(sysdate(), '%Y-%m-%d %H:%i:%S') as time from dual;
+---------------------+<br>| time |<br>+---------------------+<br>| 2022-04-28 16:08:53 |<br>+---------------------+<br>1 row in set (0.00 sec)
将时间类型字段按照format格式 格式化<br>date_format(date, format)<br># select date_format(sysdate(), '%Y-%m-%d') as date from dual;
+------------+<br>| date |<br>+------------+<br>| 2022-04-28 |<br>+------------+<br>1 row in set (0.00 sec)
返回两个日期之间相隔多少天<br>DATEDIFF(datepart,startdate,enddate)<br># select datediff(sysdate(), '1990-11-08')/365 as time from dual;
+---------+<br>| time |<br>+---------+<br>| 31.4904 |<br>+---------+<br>1 row in set (0.00 sec)
字符型
char(n)<br># 最多只能表示255个字符<br># 定长存储,节省时间,浪费空间<br># 不足的长度,右侧补空白<br># 需要频繁更改的固定长度字段,建议使用char
# 适合使用char<br> # 身份证号<br> # 手机号<br> # qq号<br> # username 12 - 18<br> # password 32<br> # 银行卡号
varchar(n)<br># 最多表示65535个字符<br># 变长存储,节省空间,存取速度慢<br># 对于不经常查看或更改的字段,使用varchar
# 适合使用varchar<br> # 评论<br> # 朋友圈<br> # 微博
单选enum和多选set
field enum(opt1,opt2)<br># 增改field值时,只能选择固定选项
field set(opt1,opt2,opt3...)<br># 插入值时,选项之间不能有空格<br># insert into t9 values(1, 'tbjx', '抽烟,喝酒,汤头');
约束 constraints
int unsigned<br># 整型无符号约束
not null<br># 非空约束
unique<br># 唯一约束
unique(field1,field2)<br># 联合唯一约束
default<br># 默认值约束
male enum('0','1') not null default '1'
auto_increment<br># 自增约束<br># 至少是unique约束的列才能加自增约束,<br># 主要用于主键自增<br># 在自增约束的列,插入值时,可传null值,入库时会自增值
primary key<br># 主键约束,非空+唯一<br># 一般搭配 自增约束<br># 一张表只能有一个主键,默认第一个非空+唯一约束的字段为主键<br># 联合主键约束<br># 在建表语句最后 primary key(field1, field2..),一般不用
foreign key(本表字段) references 外表(外表的字段)<br># 外键约束<br>
on update cascade<br># 外键级联更新,即:外表更新时,关联表同步更新
on delete cascade<br># 外键级联删除,即,外表删除是,关联表同步删除(不安全,不用)
foreign key(class_id) references class(id) on update cascade on delete cascade
表与表之间的关系
一对多/多对一<br># foreign key
多对多 (建两个外键)<br># 找出关联关系,建立第三张表,<br># 第三张存储那两张表的外键<br># 那两张表分别关联第三张表存储的列
create table author2book(<br>id int not null unique auto_increment,<br>author_id int not null,<br>book_id int not null,<br>constraint fk_author foreign key(author_id) references author(id)<br>on delete cascade<br>on update cascade,<br>constraint fk_book foreign key(book_id) references book(id)<br>on delete cascade<br>on update cascade,<br>primary key(author_id,book_id)<br>);
一对一<br># 一张表唯一约束,另一张表建立 唯一约束加外键约束<br> # 客户 学生<br> # unique foreign key + unique<br>
如何确认表关系
分析步骤:<br>#1、先站在左表的角度去找<br>是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)<br><br>#2、再站在右表的角度去找<br>是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)<br><br>#3、总结:<br>#多对一:<br>如果只有步骤1成立,则是左表多对一右表<br>如果只有步骤2成立,则是右表多对一左表<br><br>#多对多<br>如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系<br><br>#一对一:<br>如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可
索引
B+树
# b+树<br> # b是balance 平衡<br> # 为了保证每一个数据查找经历的IO次数都相同<br> # 只在叶子节点存储数据<br> # 为了降低树的高度<br> # 叶子节点之间加入双向连接<br> # 为了查找范围的时候比较快
聚簇索引和非聚簇索引
# 聚集索引(聚簇索引)<br> # 全表的数据都存储到叶子节点上 -- Innodb存储引擎中的主键<br># 非聚集索引(非聚簇索引)/辅助索引<br> # 叶子节点不存放具体的整行数据,而是存储主键的值
创建和删除索引
# 索引的创建和删除<br> # create index ind_name on 表名(字段名);<br> # create index ind_name on 表名(字段名1, 字段名2); # 联合索引<br> # drop index 索引名 on 表名; # 删除索引
合理的创建和使用索引
# 数据库使用的时候有什么注意事项<br> # 从搭建数据库的角度上来描述问题<br> # 建表的角度上<br> # 1.合理安排表关系<br> # 2.尽量把固定长度的字段放在前面<br> # 3.尽量使用char代替varchar<br> # 4.分表: 水平分,垂直分<br> # 使用sql语句的时候<br> # 1.尽量用where来约束数据范围到一个比较小的程度,比如说分页的时候<br> # 2.尽量使用连表查询而不是子查询<br> # 3.删除数据或者修改数据的时候尽量要用主键作为条件<br> # 4.合理的创建和使用索引<br> # 1.查询的条件字段不是索引字段<br> # 对哪一个字段创建了索引,就用这个字段做条件查询<br> # 2.在创建索引的时候应该对区分度比较大的列进行创建<br> # 1/10以下的重复率比较适合创建索引<br> # 3.范围<br> # 范围越大越慢<br> # 范围越小越快<br> # like 'a%' 快<br> # like '%a' 慢<br> # 4.条件列参与计算/使用函数<br> # 5.and和or<br> # id name<br> # select * from s1 where id = 1800000 and name = 'eva';<br> # select count(*) from s1 where id = 1800000 or name = 'eva';<br> # 多个条件的组合,如果使用and连接<br> # 其中一列含有索引,都可以加快查找速度<br> # 如果使用or连接<br> # 必须所有的列都含有索引,才能加快查找速度<br> # 6.联合索引 : 最左前缀原则(必须带着最左边的列做条件,从出现范围开始整条索引失效)<br> # (id,name,email)<br> # select * from s1 where id = 1800000 and name = 'eva' and email = 'eva1800000@oldboy';<br> # select * from s1 where id = 1800000 and name = 'eva';<br> # select * from s1 where id = 1800000 and email = 'eva1800000@oldboy';<br> # select * from s1 where id = 1800000;<br> # select * from s1 where name = 'eva' and email = 'eva1800000@oldboy';<br> # (email,id,name)<br> # select * from s1 where id >10000 and email = 'eva1800000@oldboy';<br> # 7.条件中写出来的数据类型必须和定义的数据类型一致<br> # select * from biao where name = 666 # 不一致<br> # 8.select的字段应该包含order by的字段<br> # select name,age from 表 order by age; # 比较好<br> # select name from 表 order by age; # 比较差
pymysql模块
创建连接
conn = pymysql.connect(user='root', # mysql 用户名<br> password='123456', # mysql 密码<br> host='172.16.238.4', # mysql 所在的服务器ip<br> database='homework',) # mysql使用的库<br>cur = conn.cursor() # 获取游标,默认返回元组数据, 参数cursor=pymysql.cursors.DictCursor,返回字典<br>
执行sql语句
cur.execute(sql语句) # 执行sql<br>
查询
ret = cur.fetchone() # 获取一条结果<br>ret = cur.fetchmany(10) # 获取n条结果<br>ret = cur.fetchall() # 获取全部结果<br># 查询时,通过 try 捕获异常
# cur = conn.cursor(cursor=pymysql.cursors.DictCursor) # 查询返回字典<br># cur = conn.cursor() # course 游标 # 默认返回元组<br># try:<br># cur.execute('select * from students;')<br>#<br># ret = cur.fetchone() # 获取一条结果<br># print(ret)<br># ret2 = cur.fetchmany(10) # 获取多条结果<br># print(ret2)<br># ret3 = cur.fetchall() # 获取全部结果<br># print(ret3)<br># except pymysql.err.ProgrammingError as e: # 做异常处理时,控制台打印e,或者打到log里<br># print(e)<br>#<br># conn.close() # 关闭连接<br># cur.close() # 关闭游标
增删改
cur.execute(insert语句)<br>cur.execute(update语句)<br>cur.execute(delete语句)<br>cur.commit() # 提交事物
# 执行增删改操作,需提交事物,<br># 如果出现异常,需要在异常处理中回滚事物<br>cur.commit() 提交事物<br>cur.roolback() # 回滚事物
## 增加,删除,修改<br># conn = pymysql.connect(user='root', # The first four arguments is based on DB-API 2.0 recommendation.<br># password='123456',<br># host='172.16.238.4',<br># database='homework',)<br>#<br># cur = conn.cursor()<br># try:<br># # cur.execute("insert into student values(null, '男', 3, '大壮')") # 增<br># # cur.execute("update student set gender = '女' where sid = 18") # 删<br># # cur.execute("delete from student where sid in(20, 21)") # 改<br># conn.commit() # 提交<br># except Exception as e: # 异常处理要打印日志或者写log<br># print(e)<br># conn.rollback() # 如果出问题,回滚事物<br>#<br># cur.close()<br># conn.close()
cur.rowcount # 获取查询结果的行数<br>cur.rownumber # 获取当前结果的行号
利用rowcount 搭配fetchone循环遍历查询结果,<br>获取使用 yeld/yeld from 得到一个生成器函数
# conn = pymysql.connect(user='root', # The first four arguments is based on DB-API 2.0 recommendation.<br># password='123456',<br># host='172.16.238.4',<br># database='homework',)<br>#<br>#<br># cur = conn.cursor() # course 游标 # 默认返回元组<br># try:<br># cur.execute('select * from student;')<br># print(cur.rowcount) # 获取查出使用多少行,便于使用fetchone取所有结果<br># for i in range(cur.rowcount):<br># ret = cur.fetchone()<br># print(cur.rownumber, ret)<br># except pymysql.err.ProgrammingError as e: # 做异常处理时,控制台打印e,或者打到log里<br># print(e)<br>#<br># conn.close() # 关闭连接<br># cur.close() # 关闭游标
利用execute()传元组参数,<br>避免sql拼接引起的sql注入
sql = "select * from userinfo where user = %s and password = %s"<br>cur.execute(sql, (user, pwd)) # 参数必须是字符串类型
user = input('username:')<br>pwd = input('password:')<br>conn = pymysql.connect(user='root', <br> password='123456',<br> host='172.16.238.4',<br> database='day42',)<br><br>cur = conn.cursor()<br>sql = "select * from userinfo where user = %s and password = %s"<br>cur.execute(sql, (user, pwd)) # sql用execute参数拼接,避免sql注入<br>print(cur.fetchone())<br><br>cur.close()<br>conn.close()
0 条评论
下一页