MySql数据库简单了解

连接数据库

首先尝试连接数据库,这里使用PyMySQL连接MySQL,并创建一个新数据库。

#导入pymysql
import pymysql
#使用connect连接
db = pymysql.connect(host='localhost', user='root', password='123456', port=3306)
#调用光标(操作游标)
cursor = db.cursor()
#使用操作游标执行操作,选择版本号
cursor.excute('SELECT VERSION()')
#得到第一条数据,获得版本号
data = cursor.fetchone()
print('Database version:', data)
#创建新数据库,名为spiders
cursion.excute('CREATE DATABASE spiders DEFAULT CHARATER SET utf8')
#关闭
db.close()

'utf8’目前是字符集UTF8MB3的别名,但在将来的版本中将是UTF8MB4的别名。

使用connect()方法声明一个MySQL连接对象时,需要传入host(即IP),本地运行时传入localhost,远程运行时则需要传入其公网IP地址。后续传入用户名,密码,端口(默认3306)。

创建表

#导入pymysql
import pymysql
#使用connec连接
db = pymysql.connect(host='localhost', user='root', password='aaasss111', port=3306, db='spiders')
#调用光标(操作游标)
cursor = db.cursor()
#编辑创建语言
sql = 'CREATE TABLE IF NOT EXISTS students (id VARCHAR(255) NOT NULL, 
		name VARCHAR(255) NOT NULL, age INT NOT NULL, PRIMARY KEY (id))'
#执行创建表
cursor.execute(sql)
#关闭
db.close()

使用not null代表可以允许无值,如果该项没有填入数据,则为空;若设置为null,该项没有填入时,会自动写为null。null可以理解为unknown或者信息缺失的意思。

插入数据

#导入pymysql
import pymysql
id = '201202020518'
user = 'bob'
age = 25
#使用connec连接
db = pymysql.connect(host='localhost', user='root', password='aaasss111', port=3306, db='spiders')
#调用光标(操作游标)
cursor = db.cursor()
#编辑创建语言
sql = 'INSERT INTO students(id,name, age) values(%s, %s, %s)'
#执行创建表
try:
    cursor.execute(sql, (id,user, age))
    db.commit()
except:
    db.rollback()
#关闭
db.close()

调用commit()方法后,数据的更新,插入,删除才会生效,是使用db调用commit()方法,而不是cursor,cursor仅为光标。
db.rollback()数据回滚,失败的话相当于什么都没有发生,适用于异常处理。

事务的ACID特性:

  • 原子性:事务是不可分割的单位,事务中包含的操作全做或者全不做,不会做一半。
  • 一致性:事务需要使数据库从一个一致性状态转变到另一个。
  • 隔离性:一个事务执行不能被其他事务干扰,一个事务的内部操作和使用数据对并发 的其他事务隔离,并发执行的事务互不干扰。
  • 持久性:也成为永久性,一个事物一旦提交,对数据库的改变应该是永久的,接下来的其他操作或者故障对其不能有影响。

插入,更新,删除都是对数据库的更改操作,更改操作必须作为一个事务,标准写法:

try:
	#执行(使用*光标*操作)
	cursor.execute(sql)
	#写入(使用*数据库数据库连接对象*操作)
	db.commit()
except:
	#否则回滚(使用*数据库连接对象*操作)
	db.rollback()

动态通用的插入方法
传入一个字典,SQL语句会根据字典动态构造,元组也动态构造,实现通用的插入方法。

#传入一个字典
data = {
    'id':'201202020519',
    'name': 'sam',
    'age': 26
}
#设置各种值
table = 'students'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
#设置一个SQL语句
sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format(table=table, keys=keys,values=values)
#异常处理
try:
	#执行SQL语句
    if cursor.execute(sql, tuple(data.values())):
        print('successful')
        #写入
        db.commit()
except:
    print('failed')
    #否则回滚
    db.rollback()
#关闭
db.close()

values = ‘, ‘.join([’%s’] * len(data))
使用 len(data)将%s扩展成[%s, %s, %s],如果不加中括号([ ]),结果是%, s, %, s, %,s
最终SQL语句为:INSERT INTO students(id,name,age) VALUES (%s, %s,%s)

更新数据

更新数据也是执行SQL语句,传入元组形式的参数。

#将name%s的age设置为%s
 sql = 'UPDATE students SET age = %s WHERE name = %s'
try:
	#执行SQL语句
    cursor.execute(sql, (22, 'bob'))
    #写入
    db.commit()
except:
	#否则回滚
    db.rollback()
#关闭
db.close()

构造一种新方法,如果数据存在就更新数据,如果不存在就插入数据,可以用来去重。

data = {
    'id':'201202020519',
    'name': 'sam',
    'age': 26
}
#设置一些值
table = 'students'
keys = ', '.join(data.keys())
values = ', '.join(['%s' * len(data)])
#ON DUPLICATE KEY UPDATE表示当主键存在时,执行更新操作
sql = 'INSERT INTO {table}({keys}) VALUES({values}) ON DUPLICATE KEY UPDATE'.format(table=table,
                                                                         keys=keys,values=values)
#更新
updata = ', '.join(["{key} = %s".format(key=key) for key in data])
#连接起来实现更新数据
sql += updata
try:
    if cursor.execute(sql, tuple(data.values()) * 2):
        print("successful")
        db.commit()
except:
    print('failed')
    db.rollback()
db.close()

sql += updata构造出来为:
INSERT INTO students(id, name, age) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE id = %s, name = %s, age = %s
当主键(primary key)已经存在时,更新数据而不是插入新数据。
一共有6个%s,所以cursor.execute(sql, tuple(data.values()) * 2)第二个参数需要乘2

删除数据

直接使用DELETE语句即可,需要指定删除的目标标名称和删除条目,同样需要执行commit()才能生效。

#选择要删除的表
table = 'students'
#设定删除条件
condition = 'age > 20'
#写需要执行的SQL语句
sql = 'DELETE FROM {table} WHERE {condition}'.format(table=table, condition=condition)
#异常处理
try:
    #执行SQL语句
    cursor.execute(sql)
    #写入
    db.commit()
except:
    #否则回滚
    db.rollback()
#关闭
db.close()

删除条件多种多样,运算符有大于,小于,等于,LIKE等,条件连接符有AND, OR等

查询数据

查询数据需要使用SELECT语句,不需要使用commit()

#设置SQL语句
sql = 'SELECT * FROM students WHERE age >= 20'
#异常处理
try:
    #执行SQL语句
    cursor.execute(sql)
    #获取查询结果的条数
    print('Count:', cursor.rowcount)
    #fetchone()方法可以获得结果的第一条数据
    one = cursor.fetchone()
    #可将结果打印
    print('One:', one)
    #获取所有查询结果
    results = cursor.fetchall()
    #将所有的查询结果打印
    print('Result:', results)
    #遍历结果,逐条打印
    for row in results:
        print(row)
except:
    print('error')

最初调用了一次fetchone(),光标会偏移一条,再次读取会读取到下一条数据,所以后面是用fetchall()时,结果会少一条。

可以使用while循环加上fetchone()来获取所有数据。因为使用fetchall()会将结果以元组的形式全部返回,数据量较大的时候,占用资源很多,所以可以改为:

#设置SQL语句
sql = 'SELECT * FROM students WHERE age >= 20'
#异常处理
try:
    #执行SQL语句
    cursor.execute(sql)
    #获取查询结果的条数
    print('Count:', cursor.rowcount)
    #获取光标当前
    row = cursor.fetchone()
    #如果光标当前有数据就打印结果并获取下一个数据
    while row:
        print('Row:', row)
        #每次都会移动光标
        row = cursor.fetchone()
except:
    print('error')

每次循环,光标指针都会偏移一条。

你可能感兴趣的:(简单了解)