SQL是结构化查询语言,是一种用来操作RDBMS的数据库的语言,可以通过SQL操作oracle,sql server,mysql,sqlite等关系型数据库
SQL的作用是实现数据库客户端和数据库服务端之间的通信,SQL就是通信的桥梁
MyQL是一个关系型数据库管理系统,在Web应用方面,MySQL是最好的RDBMS(关系型数据库管理系统)应用软件,是由MySQL AB公司开发,目前是Oracle旗下的产品,MySQL是最流行的关系型数据库管理系统中的一个
安装 sudo apt-get install mysql-server
查看是否安装 apt list | grep mysql-server
sudo service mysql status
sudo service mysql stop
sudo service mysql start
sudo service mysql restart
查看当前进程 ps
表示所有用户 -a
表示显示用户名 -u
表示显示所有的执行程序 -x
配置文件路径:/etc/mysql/mysql.confi.d/mysqld.cnf
port 表示端口号,默认为 3306
bind-address 表示服务器绑定的ip,默认为127.0.0.1
datadir表示数据库保存路径,默认为/var/lib/mysql
log_error 表示错误日志,默认为 /var/log/mysql/error.log
图形化界面客户端 Navicat
使用: tar zxvf navicat112_mysql_cs_x64.tar.gz
启动:./start_navicat
cd ~
rm -r .navicat64
命令行客户端mysql(目前使用的Ubuntu中已经安装了MYSQL命令行客户端软件)
sudo apt-get install mysql-client
数据类型是指在创建表的时候为表中字段指定数据类型,只有数据符合要求才能存储起来,使用数据类型的原则是:够用就行,尽量使用取值范围小的,而不用大的,这样也可以更多的节省存储空间。
常用数据类型:
数据类型说明:
数据约束:
navicat是一套快速,可靠并价格适应的数据库管理工具,适用于三种平台:Windows,mac,OS,及linux.可以对本机或远程的MYSQL。SQL Server,SOLite,Oracle等数据库进行管理及开发。专门为简化数据库的操作而设计,它的设计符合数据库管理员,开发人员及中小企业的需求,Navicat是一个数据库图形化客户端软件,让你可以以安全并简单的方式对数据库进行操作。
登录 mysql -uroot -p -u后面是登录用户名 -p后面是登录密码,若不填写,回车后会提示输入密码
显示当前时间 select now();
登出数据库 exit / quit / ctrl+d
查看所有数据库 show databases;
创建数据库 create database 数据库名 charset=utf-8; 例:create database python charset=utf-8;
使用数据库 use 数据库名;
查看当前使用的数据库 select database();
5.> 删除数据库-慎重 drop database 数据库名; 例:drop database python;
查看当前数据库中的所有表 show tables;
创建表 create table st(id int unsigned primary key auto_increment not null,name varchar(20) not null,age tinyint unsigned default 0;height decimal(5,2);gender enum('男’,‘女’));说明:create table 表名( 字段命名 数据类型 可选约束条件,。。);
修改表-添加字段 alter table 表名 modify 列名 类型 约束; alter table st modify birth data not null; 说明:modify:只能修改字段类型或者约束,不能修改字段名
修改表-修改字段名和字段类型 alter talbe 表名 change 原名 新名 类型及约束;例:alter table st change bith datetime not null;
查询语句 select * from 表名;
查询指定列 select 列,列。。from 表名; 例:select id,namefrom st;
全列插入 insert into 表名 values(…) 例: insert into st values(0,‘xx’,default,'男‘);
部分列插入,值的顺序与输出的列顺序对应 insert into 表名 (列名,…),values(值,…);
修改数据 update 表名 set 列1=值1,列2=值2,,, where 条件
删除数据(物理删除) delete from 表名 where 条件
select id as 序号 ,name as 名字,gender as 性别 from st;
select s.id,s.name from st as s;
查询大于平均年龄的学生 select * from st where age>(select avg(age) from st);
查询学生在班的所有班级名字 select name from class where id in (select c_id from st where c_id is not null);
查找年龄最大,身高最高的学生 select * from st where (age,height)=(select max(age),max(height) from st);
--创建学校表
create table sc(
id int not null primary key auto_increment,
name varchar(10)
);
--创建老师表
create table teacher(
id int not null primary key auto_increment,
name varchar(10),
s_id int not null,
foreign key(s_id) references sc(id)
);
--删除外键约束
--需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table teacher;
--获取名称之后就可以根据名称删除外键约束
alter table teacher drop foreign key 外建名;
5.分组和聚合函数的使用
--创建jd数据库
create database jing_dong charset=utf8;
--创建商品表goods decimal 浮点数
create table goods(
id int unsigned primary key auto_increment not null,
name varchar(150) not null,
cate_name varchar(40) not null,
brand_name varchar(40) not null,
price decimal(10,3) not null default 0,
is_show bit not null default 1,
is_saleoff bit not null default 0
);
--表结构
--id 主键 自增
--name 商品名称 cate_name 分类名称 brand_name 品牌名称 price 价格 is_show 是否显示 is_saleoff 是否售完
--1.商品分类
select distinct cate_name from goods;
select cate_name from goods group by cate_name;
--2求所有电脑产品的平均价格,并保留两位小数
select round(avg(privr),2) from goods;
--3显示每种商品的平均价格
select cate_name,round(avg(price),2) from goods group by cate_name;
--4查询每种类型的商品种最贵的,最便宜的,平均价,数量
select cate_name,max(price),min(price),avg(price),count(*) from goods group by cate_name;
--5查询所有价格大于平均价格的商品,并且按价格降序排序
select * from goods where price>(select avg(price) from goods) order by price desc;
--想要添加一个商品分类信息,还需创建一个商品分类表,将goods中的商品分类信息添加到该表中,
--将goods表中的分类名称更改为商品分类表中对应的分类id
--闯将商品分类表
create table good_cates(
id int not null primary key auto_increment,
name varchar(50) not null;
);
--将goods表中的商品分类添加到商品分类表
insert into good_cates(name) select cate_name from goods group by cate_name;
--添加移动设备分类信息
insert into good_cates(name) values("移动设备");
--将goods表中的分类名称改为商品分类表中对应的分类id
--查看goods表中尚品分类名称对应的商品分类id
select * from inner join good_cates on goods.cate_name=good_cates.name;
--把该语句中from后的语句理解为一张表
update goods g inner join good_cate gc on g.cate_name=gc.name set g.cate_name=gc.id;
--查询品牌信息
select brand_name from goods group by brand_name;
--创建品牌表
--create table ..select 创建数据表并同时插入数据 插入字段名称要与表中字段一致
create table good_brands(
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by band_name;
);
--将goods表中的品牌更改为品牌表中对应的品牌id,连接更新表中的某个字段
update goods g inner join goods_brands gs on g.brand_name=gs.name set g.brand_name=gd.id;
--查看表结构
desc goods;
--通过alter table 语句修改为表结构
alter table goods change cate_name cate_id int not null ,change brand_name brand_id int not null;
conn=connect(参数列表)
host:连接mysql主机,本机是:localhost
port:连接mysql主机的端口,默认是3306
user:连接的用户名
password:连接的密码
database:数据库名称
charset:通信采用的编码格式,推荐使用utf8
3. 获取游标对象
获取游标对象的目标就是要执行sql语句,完成对数据的增删改查操作,
调用连接对象的**cursor()**方法获取游标对象
cur=conn.cursor()
游标操作说明:
使用游标执行SQL语句:execute(operation[parameters])执行SQL语句,返回受影响的行数,主要用于执行insert,update,delete,select等语句
获取查询结果集中的一条数据:cur.fetchone() 返回一个元祖,如(1,’张三‘)
获取查询结果集中的所有数据,cur,fetchall()返回一个元祖,如(1,’张三‘),(2,'李四’)
关闭游标:cur.close(),表示和数据库操作完成
4. pymysql完成数据的操作,关闭连接
#1.导包
import pymysql
if __name__ == '__main__':
#2.创建连接对象
#connect =Connection=Connect 本质上是一个函数,使用其一都可以创建一个连接对象
conn=pymysql.connect(
host='localhost',
port =3306,
user='root',
password='123456',
database='pythontest',
charset='utf8'
)
#3,获取游标,目的执行sql语句 游标好比一辆运输数据的车
cur=conn.cursor()
#准备sql,语法与mysql中一样
sql='select * from user;'
#4.执行sql语句
cur.execute(sql)
#5.获取执行结果
row=cur.fetchone()# 返回数据类型是一个元组
print(row)
#6.关闭游标
cur.close()
#7.关闭连接
conn.close()
3. pymysql对数据库的增删查改
def delete():
#2.创建连接
conn=pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='pythontest',
charset='utf8'
)
#获取游标
cur=conn.cursor()
#编写sql语句
sql='delete from user where id=2;'
try:
#执行sql语句
cur.execute(sql)
#提交数据
conn.commit()
except Exception as e:
#回滚数据
conn.rollback()
finally:
#挂壁游标
cur.close()
#关闭连接
conn.close()
什么是sql注入?
用户提交带有恶意的数据与SQL语句进行字符串方式的拼接,从而影响了SQL语句的语义,最终产生数据泄露的现象
如何防止?
SQL语句参数化
SQL语言中的参数使用%来占位,此处不是python中的字符串格式化操作
将SQL语句中%占位所需要的参数存在一个列表中,把参数列表传递给execute方法中的第二个参数
1.单个参数
#是select语句的条件语句为真,可查询所有语句 如:select * from user where name='%';"% 'ww' or 1=1 or ''";
#防注入 的sql语句 % 是sql语句的参数和字符串里面的%s不一样,不用加上引号
sql="select * from user where name=%s;"
cur.execute(sql,("'ww' or 1=1 or ' '",))#查出的是一条数据
#sql防注入多个参数使用
insert into user(id,name,age) values(%s,%s,%s);
cur.execute(sql,[1,'dfd',54])
def main():
#创建连接对象
conn=pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123456',
database='pythontest',
charset='utf8'
)
#获取游标
cur=conn.cursor()
try:
# 插入10万条语句
for i in range(100000):
cur.execute("insert into test_index values('h-%d')"%i)
#提交数据
conn.commit()
except Exception as e:
conn.rollback()
finally:
#关闭游标
cur.close()
#关闭连接
conn.close()
3. 验证索引性能
开始运行时间监测 set profiling=1;
查找第1万条数据 select * from test_index where title='h-9999';
查看执行时间 show profiles
给title字段创建索引 alter table test_index add index(title);
再次执行查询语句
再次查看执行时间
mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> use pythontest;
Database changed
mysql> select * from test_index where title='h-9999';
+--------+
| title |
+--------+
| h-9999 |
+--------+
1 row in set (0.11 sec)
mysql> show profiles;
+----------+------------+-----------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------+
| 1 | 0.00028250 | SELECT DATABASE() |
| 2 | 0.11412100 | select * from test_index where title='h-9999' |
+----------+------------+-----------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
mysql> alter table test_index add index(title);
Query OK, 0 rows affected (0.83 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from test_index where title='h-9999';
+--------+
| title |
+--------+
| h-9999 |
+--------+
1 row in set (0.00 sec)
mysql> show profiles;
+----------+------------+-----------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------+
| 1 | 0.00028250 | SELECT DATABASE() |
| 2 | 0.11412100 | select * from test_index where title='h-9999' |
| 3 | 0.82791925 | alter table test_index add index(title) |
| 4 | 0.00059325 | select * from test_index where title='h-9999' |
+----------+------------+-----------------------------------------------+
4 rows in set, 1 warning (0.00 sec)