Day15:python数据库
数据库:按照数据结构来,组织、管理、存储数据的仓库,可以和编程语言结合
1.MySQL安装
mysql属于关系型数据库
1.选择custom:
2.只需要选择这一个进行安装就可以了
3.对上一步中选择好的,点开按图中选择就可以了
SQL语句的基本语法
DDL:data definition language,数据定义语言:建库建表如create,修改库表alter,删除库表drop等,给数据仓库定义
DML:data manipulation language,数据库操作语言对数据的查询,插入,删除,更新操作,对数据内容进行操作
DCL: data control language,数据库控制语言,对用户 的管理
1.数据定义语言DDL
1.数据库操作
- 创建数据库:create database if not exists 数据库名
- 删除数据库:drop database 数据库名
- 查看数据库:show databases;
- 定义数据库字符集: create database if not exists 数据库名 default charset=utf8
2.数据表操作
- 创建表:
create table if not exists table(字段 字段类型(字段长度) [字段属性 [字段约束]);
- 查看表:show tables;
- 查看表结构:desc table;
- 查看表创建语句:show create table;
- 删除表:drop table if not exists table_
- 修改表名:alter table table_old rename as table_new
- 修改字段名:alter table table_ change old_字段 new_字段 字段类型及属性
- 修改字段类型:alter table table_ modify 字段名 字段类型及属性
- 添加字段:alter table table_ add 字段名 字段类型及属性
- 删除字段: alter table table_ drop 字段名
- 约束:主键 ,唯一,自增长,外键:
- create table if not exists table_(xxx primary key ,…)
- create table if not exists table_(xxx primary key ,…, constraint 外键名称 foreign key(从表某字段) references 主表(主表某字段,这个字段需要有唯一性约束))
- alter table 从表名 add constraint 外键名称 foreign key(从表某字段) references 主表(主表某字段,这个字段需要有唯一性约束)
- 1.两个表必须是InnoDB表;2.使用在外键关系的域(字段)必须为索引型(Index)。所以要为设置外键的字段建立index;3.使用在外键关系的两个域(字段)数据类型要相同。
- mySQL引擎:innodb,myisam : create table MM(xxxxx)engine=InnoDB
功能对照表:
对比项 | MyISAM表 | InnoDB表 |
---|---|---|
事务处理 | 不支持 | 支持 |
数据行锁定 | 不支持,只有表锁定 | 支持 |
外键约束 | 不支持 | 支持 |
表空间大小 | 相对小 | 相对大,最大是2倍 |
全文索引 | 支持 | 不支持 |
COUNT问题 | 无 | 执行COUNT(*)查询时,速度慢 |
2.数据操作语言DML
数据库操作语言:insert,update,delete
添加数据:
- 指定字段名添加:insert into table_(field1,fied2,field3…) values(value1,value2,value3…)
- 不指定字段名,匹配所有列添加:insert into table_ values(value1,value2,vaule3…) #要与table列顺序全匹配
- 添加多列数据:insert into table_ values (value1,value2,vaule3…),(value1,value2,vaule3…),…();
- select 添加:INSERT INTO table2 SELECT * FROM table1;
删除数据:
- 条件删除:delete from 表名 where condition;
- 删除所有:delete from 表名;truncate 表名;truncate删除会重置索引
更新数据:
- 条件更新:update 表名 set 字段1 = value1 ,字段2 = value2 where condition
- 更新所有:update 表名 set 字段1 = value1 ,字段2 = value2
查询数据:
- 查所有:select * from table_name;
- 查指定列:select field1 ,field2 from table_name
查指定条件数据:
between…and :查询在两个之间的记录
is null:查询为空的记录
is not null :查询不为空的记录
like:模糊查询
%,_,*
模糊匹配
模式 描述 ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 . 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。 […] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 [^…] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 p1 p2 * 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 + 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 {n} n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 in : 查询在某个集合内的
and:条件1 and 条件二 :查询同时满足条件1 和条件2的所有记录
or : 条件1 or 条件二 :查询满足条件1 或条件2的所有记录
- not :条件1 not 条件二 :查询满足条件1 且不满足条件2的所有记录
xor
异或:条件1xor
条件二 :查询不同时满足条件1 和条件2的所有记录- 算术运算符:
大于:>, 小于:< ,等于 =, 大于等于:>= ,小于等于<= ,不等于<>
分组查询:
group by
分组查询属于聚合函数,可以和count,average,sum等一起使用- select * from table_name group by 字段
分页查询:
- 每页显示记录数page_number:select * from commodity limit (page-1)*page_number,page_number
排序:
order by + asc(升序)/desc(降序)
子查询:内层查询的结果作为另外一个查询的条件;select * from xxx where id = (select cc from aa)
连接查询:内连接(inner join…on),外连接(左外连接:left join …on ,右外连接 right join …on),全连接(full join…on)
小知识:Where子句中使用的连接语句,在数据库语言中,被称为隐性连接。Inner join……on子句产生的连接称为显性连接。(其他Join参数也是显性连接)Where 和Inner join产生的连接关系,没有本质区别,结果也一样。但是!隐性连接随着数据库语言的规范和发展,已经逐渐被淘汰,比较新的数据库语言基本上已经抛弃了隐性连接,全部采用显性连接了。在 SQL-92 标准中,内联接可在 FROM 或 WHERE 子句中指定。这是 WHERE 子句中唯一一种 SQL-92 支持的联接类型。WHERE 子句中指定的内联接称为旧式内联接。
- 聚合函数:sum(),avg(),count(),max(),min()
注意:如果统计的列中只有NULL值,那么MAX和MIN就返回NULL
注意:sum和avg函数—求和与求平均!!表中列值为null的行不参与计算,要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。
python 连接msyql
- 连接mysql的基本步骤:
#1、导入pymysql模块
import pymysql
#2、 建立连接
conn=pymysql.Connect(host='localhost',user='root',password='123456',db='school',charset='utf8')
#3、 获取游标,,通过游标的位置获取相应的数据(重要)
cur=conn.cursor()
#4、 组装sql语句
sql="insert into job values('%s','%s','%s','%s')"
#在使用格式化输出的时候,%s为字符串输出类型,需要加引号
#5、 execute()执行sql语句
cur.execute(sql % data)
#data为元组
#6-1、 如果是增、删、改操作,需要commit()操作
conn.commit()
#6-2、 如果是查询操作,则执行抓取操作,fetchone()、fetchmany()、fetchall()
data_one=cur.fetchone()
#获取一条数据,游标下移,后面获取将从游标位置继续
data_many=cur.fetch_many()
#以元组类型存储
data_all=cur.fetchall()
#7、 关闭连接
conn.close()
- 操作mysql并将处理结果写入excel
import pymysql
import xlwt
class Connect(object): #定义Connect类,用于实例化连接对象
def __init__(self,host,user,password,db,charset):
self.host=host
self.user=user
self.password=password
self.db=db
self.charset=charset
def getConnect(self): #定义获得连接方法
conn=pymysql.connect(host=self.host,user=self.user,password=self.password,db=self.db,charset=self.charset)
return conn #必须要有return才能成功建立连接
conn=Connect('localhost','root','123456','movies','utf8').getConnect()
cur=conn.cursor()
'''
----------------- 通过pymysql模块插入两条数据 -----------------------
'''
def insertData(data):
sql_1="insert into movieRank values('%s','%f','%f','%d','%f')"
cur.execute(sq_l1 % data)
conn1.commit()
print("插入了{}条数据!".format(cur.rowcount))
data1=('犬之岛',617.35,0.0908,2,1309.09)
data2=('湮灭',145.34,0.0199,9,5556.77)
# insertData(data1)
# insertData(data2)
'''
------------- 执行SQL语句查询数据,并通过xlwt模块操作excel写入文件 --------------
'''python
sql_2="select * from movierank" #SQL查询语句
cur.execute(sql_2) #执行SQL语句
table_frame=cur.description #description就是sql语句中的desc,描述的是表结构,上一句的execute相当于定位到表movierank,描述的表结构,为横向排列
list1=[] #定义空列表,用于存放表头
for row in table_frame:
list1.append(row[0]) #将表结构中每行第一个元素加入到list1中
wb=xlwt.Workbook()
new_sheet=wb.add_sheet('Movies data')
for i in range(len(list1)):
new_sheet.write(0,i,list1[i]) #在第一行写入表头
alldata=cur.fetchall() #通过fetchall()获取所有数据
for j in range(len(alldata)):
for k in range(len(alldata[i])):
new_sheet.write(j + 1,k, alldata[j][k]) #for循环遍历通过write()方法将数据写入excel
wb.save("./movieRank.xls")
- 通过Python操作pymysql进行分页查询
import pymysql #导入模块
conn=pymysql.Connect(host='localhost',user='root',password='123456',db='jobinfo',charset='utf8') #建立连接
cur=conn.cursor() #建立游标
currentPage=1 #当前页码
pageNum=10 #每页数据数量
for page in range(1,21): #for循环从第1页打印到20页:
sql = "select * from job limit %d,%d" #组装sql语句
start_index = (currentPage - 1) * pageNum
cur.execute(sql % (start_index, pageNum))
print("************:获取第{}页**************".format(page))
for row in cur.fetchall():
print(row)
经常使用select * from students,score WHERE students.sno = score.sno;
这样的语句,今天使用左外连接时候写的SQL语句:
select * from students left join score where students.sno = score.sno;
执行报错:
syntax to use near 'where students.sno = score.sno' at line 1
查了一下在外连接的时候使用on进行条件连接;
2.在内连接不加条件的时候就是全连接,因为连接指向就是先进行全连接然后再进行on条件筛选,如果是外连接则必须有on;
在CNDN看到了一篇讲解SQL语句的执行顺序的,如下:
执行顺序:
- FROM:对FROM子句中的前两个表执行笛卡尔积,生成虚拟表VT1。
- ON:对VT1应用ON筛选器。只有那些使为真的行才被插入VT2。
- OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行将作为外部行添加到VT2,生成VT3。 如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到 处理完所有的表为止。
- 对VT3应用WHERE筛选器。只有使为TRUE的行才被插入VT4。
- GROUP BY:按GROUP BY 子句中的列列表对VT4中的行分组,生成VT5。
- CUBE|ROLLUP:把超组插入VT5,生成VT6。
- HAVING:对VT6应用HAVING筛选器。只有使为TRUE的组才会被插入VT7。
- SELECT:处理SELECT列表,产生VT8。
- DISTINCT:将重复的行从VT8中移除,产生VT9。
- ORDER BY:将VT9中的行按ORDER BY子句中的列列表排序,生成一个有表(VC10)。
- TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回给调用者。
MySQL最常用分组聚合函数 —- “讲解很好包括用法和注意事项”