程序在运行时,数据都是在内存中的。当程序终止时,通常需要将数据保存在磁盘上。前面我们有学过将数据写入文件就是保存到磁盘的一种方式。
但是当面对大批量的数据时,为了方便我们保存和查找数据或者该条见查找特定数据时,就需要用到数据库了。在实际项目开发中。我们也是天天和数据库打交道。此教程我们需要使用的数据库是Mysql。今天我们先来看看如何安装Mysql。
1. 下载:
点击以下链接进入Mysql官网,选择最新版本下载。
https://dev.mysql.com/downloads/mysql/8.0.html
直接选择'No thanks, just start my download.'
2. 安装
首先是确定 MySQL 8 的安装目录,可以自行决定,我是将其安装在 E:\Mysql目录下,解压安装包至安装目录下即可。
3.配置文件
在安装目录下新建配置文件 my.ini ,配置文件中写入:
[mysqld] port=3306 basedir =E:\Dade\mysql-8.0.25-winx64 max_allowed_packet = 20M
保存即可,其中 datadir 为数据存储目录,我的存放路径是E:\Dade目录下,你可以对应地进行修改。
4. 初始化 MySQL 8
打开命令行,进入 MySQL 的 bin 目录下,之后进行初始化,命令为:
mysqld --initialize --consol
初始化成功后,命令行会打印出 root 用户的初始密码(记得保存),如下图:
5.启动 MySQL 服务。
在启动服务前,首先要将 MySQL 8 安装为 Windows 的系统服务,在 MySQL 的 bin 目录执行命令如下:
mysqld --install mysql8
其中 mysql8 为服务名称,你可以自行修改成想要的名字。
注意,如果显示'Install/Remove of the Service Denied!',选择使用管理员身份打开即可!
服务注册成功后,就可以启动 MySQL 服务了,执行命令:
net start mysql8
重点:此处若是显示错误'服务没有相应控制功能',尝试解决方法:访问如下网站:
https://cn.dll-files.com/vcruntime140_1.dll.html
下载VCRUNTIME140_1.DLL最新的版本。下载后将此文件直接放入MySQL的bin子目录下即可。
6. 登录 MySQL
服务启动成功后,则可以登录 MySQL 服务器了,在 bin 目录下执行
mysql -uroot -p
输入刚刚保存的密码即可。显示‘Welcome to the MySQL monitor’即可代表登录成功。
接下来需要修改Mysql的 root 用户密码,不然是无法进行操作的。需要执行的修改 root 用户密码命令如下:
ALTER USER 'root'@'localhost' IDENTIFI WITH mysql_native_password BY '你的六位数字密码'; FLUSH PRIVILEGES;
7.测试连接
然后使用Sqlyog测试连接,如下证明Mysql已成功安装:
由于Mysql服务器以独立的进程运行,并通过网络对外服务。所以我们需要支持Python的Mysql驱动来连接Mysql服务器。在Python中支持Mysql的数据库模块有很多,我们选择使用PyMySql。
PyMsql的安装
PyMysql的安装很简单,安装命令如下:
pip install pymysql
如下代表正常成功。
连接数据库
使用数据库的第一步就是连接数据库,接下来我们看看如何使用PyMysql连接数据库。
1:连接数据库
2:创建游标对象
3:对数据库进行增删改查
4:关闭游标
5:关闭连接
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306) print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # 使用 execute() 方法执行 SQL 查询 cursor.execute("SELECT VERSION()") # 使用 fetchone() 方法获取单条数据. data = cursor.fetchone() print("Database version : %s " % data) # 关闭数据库连接 db.close() ''' 连接成功! Database version : 8.0.25 '''
操作运行结果:
连接成功!
Database version : 8.0.25
创建数据库表
如果数据库连接存在我们可以使用execute()方法来为数据库创建表,如下所示创建表EMPLOYEE:
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306, db='Mysql8') print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # 使用 execute() 方法执行 SQL,如果表存在则删除 cursor.execute("DROP TABLE IF EXISTS EMPLOYEE") # 使用预处理语句创建表 sql = """CREATE TABLE EMPLOYEE ( FIRST_NAME CHAR(20) NOT NULL, LAST_NAME CHAR(20), AGE INT, SEX CHAR(1), INCOME FLOAT )""" cursor.execute(sql) print('建表成功!') # 关闭数据库连接 db.close() ''' 连接成功! 建表成功! '''
操作运行结果:
连接成功!
建表成功!
我们可以打开Sqlyog发现在我们名称为Mysql8的数据库下多了一个EMPLOYEE 的Table。如下图:
插入数据
我们来看看如何使用INSERT语句向表 EMPLOYEE 插入数据。
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306, db='Mysql8') print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # SQL 插入语句 sql = """INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" try: # 执行sql语句 cursor.execute(sql) # 提交到数据库执行 db.commit() print('数据插入成功!') except: # 如果发生错误则回滚 db.rollback() print('数据插入错误!') # 关闭数据库连接 db.close() ''' 连接成功! 数据插入成功! '''
连接成功!
数据插入成功!
数据库查询操作
ython查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。
fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
fetchall(): 接收全部的返回结果行.
rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。
查询EMPLOYEE表中salary(工资)字段大于1000的所有数据:
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306, db='Mysql8') print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # SQL 查询语句 sql = "SELECT * FROM EMPLOYEE \ WHERE INCOME > %s" % (1000) try: # 执行SQL语句 cursor.execute(sql) # 获取所有记录列表 results = cursor.fetchall() for row in results: fname = row[0] lname = row[1] age = row[2] sex = row[3] income = row[4] # 打印结果 print('数据查询成功!') print("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \ (fname, lname, age, sex, income)) except: print("Error: unable to fetch data") # 关闭数据库连接 db.close() ''' 连接成功! 数据查询成功! fname=Mac,lname=Mohan,age=20,sex=M,income=2000.0 '''
操作运行结果:
连接成功!
数据查询成功!
fname=Mac,lname=Mohan,age=20,sex=M,income=2000.0
数据库更新操作
更新操作用于更新数据表的的数据,以下实例将 TESTDB 表中 SEX 为 'M' 的 AGE 字段递增 1:
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306, db='Mysql8') print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # SQL 更新语句 sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M') try: # 执行SQL语句 cursor.execute(sql) # 提交到数据库执行 db.commit() print('数据更新成功!') except: # 发生错误时回滚 db.rollback() # 关闭数据库连接 db.close() ''' 连接成功! 数据更新成功! '''
操作运行结果:
连接成功!
数据更新成功!
删除操作
删除操作用于删除数据表中的数据,以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据:
import pymysql # 打开数据库连接 try: db = pymysql.connect(host='localhost', user='root', passwd='666666', port=3306, db='Mysql8') print('连接成功!') except: print('something wrong!') # 使用 cursor() 方法创建一个游标对象 cursor cursor = db.cursor() # SQL 删除语句 sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20) try: # 执行SQL语句 cursor.execute(sql) # 提交修改 db.commit() print('数据删除成功') except: # 发生错误时回滚 db.rollback() # 关闭连接 db.close() ''' 连接成功! 数据删除成功 '''
操作运行结果:
连接成功!
数据删除成功
执行事务
什么是事务?
转账是生活中常见的操作,比如从A账户转账100元到B账号。站在用户角度而言,这是一个逻辑上的单一操作,然而在数据库系统中,至少会分成两个步骤来完成:
1.将A账户的金额减少100元
2.将B账户的金额增加100元。
在这个过程中可能会出现以下问题:
1.转账操作的第一步执行成功,A账户上的钱减少了100元,但是第二步执行失败或者未执行便发生系统崩溃,导致B账户并没有相应增加100元。
2.转账操作刚完成就发生系统崩溃,系统重启恢复时丢失了崩溃前的转账记录。
3.同时又另一个用户转账给B账户,由于同时对B账户进行操作,导致B账户金额出现异常。
为了便于解决这些问题,需要引入数据库事务的概念。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功,要么全部失败。
一致性(Consistency):事务的执行结果必须使数据库从一个一致性状态到另一个一致性状态。一致性状态是指:1.系统的状态满足数据的完整性约束(主码,参照完整性,check约束等) 2.系统的状态反应数据库本应描述的现实世界的真实状态,比如转账前后两个账户的金额总和应该保持不变。
隔离性(Isolation):并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时一样。比如多个用户同时往一个账户转账,最后账户的结果应该和他们按先后次序转账的结果一样。
持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障都不会导致数据丢失。
在事务的ACID特性中,C即一致性是事务的根本追求,而对数据一致性的破坏主要来自两个方面
# SQL删除记录语句 sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20) try: # 执行SQL语句 cursor.execute(sql) # 向数据库提交 db.commit() except: # 发生错误时回滚 db.rollback()
对于支持事务的数据库, 在Python数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。
commit()方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。