PYTHON1.day21


Flush PRIVILEGES;   -- 刷新权限并生效
6)查看授权
   - 查看当前用户: show grants;
   -查看其他用户:  show grants for '用户名'@'客户端';
7)吊销权限(取消用户的某个权限)
   - 语法: revoke 权限列表 on 库名.表名 from '用户名'@'客户端地址'
   - 示例: 吊销Daniel用户所有库,所有列表的插入数据权限
           revoke insert on *.* from 'bank_user'@'%';
           revoke insert on bank.* from 'bank_user'@'%';

4. 数据库事务(重点)
   - 事务(Transacyion):
   - 数据库执行一系列操作时,全都执行,全都不执行
     保证数据的一致性、正确性
   - 例如在一笔转账中,执行需要三个操作,
         从转出账户减去相应金额
         在转入账户增加相应金额
         登记一笔转账明细
         以上三个操作,要么全部成功,要么全部失败
   3)使用事务的情况
     - 涉及到多表的增删改操作
     - 执行这些操作时需要保证一致性,正确性
   4)启用事务条件要求:必须是Innodb存储引擎
   5)事务的额特征(ACID):
      - 原子性(Atomicity):事务是一个整体,要么全部执行,要么全部不执行
      - 一致性(Consis.
      tency):事务执行完成后,从一个一致状态变成另一个一致状态
      - 隔离性(Isolation):不同的事务不会相互影响,干扰
      - 持久性(Durability):一旦事务提交,对数据库的修改就必须永久保留下来

   6)如何进行事务操作
    - 开启: start transaction
     - 提交: commit
     - 回滚:rollback

     - 示例:在两个账户间进行转账
             第一步:减去转出账户余额
             第二步:在转入账号上加上相等的余额
             提交事务
             start transaction;
             update acct_new set balance = balance - 100
                    where acct_no = '6223450001';
             update acct_new set balance = balance + 100
                    where acct_no ='622456000020';
             commit;---或rollback
             ----在提交事务前,重新登录一个客户端
             ----查看数据是否变更

    
     7)SQL语句分类
      - 数据查询语言(DQL):查询数据,不改变数据
      - 数据定义语言(DDL):定义数据结构,如建表/库,删除库/表,创建/删除索引,修改表结构
      - 数据操作语言(DML):对数据进行增删改
      - 数据控制语言(DCL):权限管理,事务操作,数据库监视...

   
-------------------------------------------------day25.new---------------------------------------------------
1.锁
   1)锁:对数据库的控制权
   2)目的:解决多个工作单元并发操作数据的正确性
   3)分类:
     a)锁类型
       - 读锁(共享锁):加锁后,可以读取,但不能修改
       - 写锁(排它锁):加锁后,不能进行读写

    b)锁粒度
       - 行级锁(细粒度):锁定一行,并发效率高
         控制较为复杂,消耗资源多
       - 表级锁(粗粒度):锁定整张表,并发效率低
         控制简单,消耗资源较少


2.存储引擎
   1)什么是存储引擎:表的存储方式,包括存储机制,索引机制,锁定方式等
   2)基本操作:
     - 查看:show engines;
     - 查看某个表的存储引擎方式:show create table 表名
PYTHON1.day21
     -建表时指定存储引擎
      create table t1(id int primary key)engine=InnoDB default charset=utf8;
                                         engine 指定存储
     - 修改存储引擎方式
       alter table t1 engine = MyISAM;

   3)常见存储引擎
     a)InooDB
      特点:支持事务,行级锁,外键
      共享表空间
     *.frm    表结构和索引
      *.ibd    表记录
      show global variables like '%datadir'命令查看数据存储位置    
      sudo -i切换到root用户,进入目录查看

     - 使用场合
       更新操作密集的表
       有数据库事务支持的要求
       自动灾备,恢复
       有外键约束要求
       支持自增长字段(auto_increment)

PYTHON1.day21
     b)MyISAM
       - 支持表级锁定、不支持事务、不支持外键
         不支持行锁定,访问速度较快
       - 独享表空间
           表名.frm: 表结构
           表名.myd: 表数据
           表名.myi: 表索引

       - 适用场合
           查询操作较多
           数据一致性要求较低(不支持事务)
           没有外键约束

    c)Memory(内存表):
         - 表结构存储在磁盘上(硬盘),数据存储在内存
           访问速度很快
         - 文件:表名.frm   存储表结构
         - 服务(或机器)重启后,表中的数据丢失
         - 适用场合:
               数据量小、访问速度要求极快、访问频率高、
               数据丢失后不会造成影响 
         - 示例:
               1:创建memory引擎的表
                 create table t2(id int)engine=memory;
               2:插入数据并查询
               3:重启服务,再查询,数据消失
                 sudo /etc/init.d/mysql restart

PYTHON1.day21

PYTHON1.day21

PYTHON1.day21
     3. E-R模型:实体关系模型
           a)实体(Entry): 现实中可以区分的事物称之为实体
           b)关系(Relationship): 实体之间的联系
             - 一对一
             - 一对多
             - 多对多
           c)属性:实体所具有的数据特征
           d)E-R图:用图形化方式,表达实体间的关系
             矩形:表示实体
             椭圆:实体的属性
             菱形:实体间的关系
               一对一:菱形左右各写一个1
               一对多:菱形左右分别用1,N来表示
               多对多:菱形左右分别用M, N来表示
           e)练习:画出账户,交易明细,客户实体之间的E-R图(见ER图.pptx)
     4. 使用Python访问MySQL
       1)pymysql库:Python语言访问MySQL接口
         - 安装:
           在线:sudo pip3 install pymysql
           离线:
             第一步:下载安装包,下载地址:
                 https://pypi.org/project/PyMySQL/
             PyMySQL-0.9.3.tar.gz
         第二步:解压包,并执行安装
                 tar -zxvf PyMySQL-0.9.3.tar.gz
             cd PyMySQL-0.9.3
         第三步:进入目录,安装
             python3 setup.py install
         - 验证:进入Python交互模式,执行导入包操作
                 import pymysql
             如果不报错,则说明安装成功

        # 第一步:导入pymysql模块
import pymysql
host = 'localhost'#服务器地址
user = 'root'#用户名
passwd = '123456'#密码
dbname = 'bank'#库名称

PYTHON1.day21

#第二步:建立到数据库服务器的连接,创建连接对象
conn = pymysql.connect(host,user,passwd,dbname)
#第三步:获取游标对象(cursor),通过调用数据库连接 对象获得游标        
cursor = conn.cursor()
#第四步:利用cursor对象提供的方法,执行SQL语句
cursor.execute("select * from acct_new")
result = cursor.fetchall()#取查询到的数据
for r in result:
     tmp = "帐号:%s,户名:%s,金额:%s"%(r[1],r[1],r[6])
     print(tmp)
#第五步:提交事务(如果需要)
#第六步:关闭游标对象

cursor.close()
#第七步:关闭数据库连接对象
conn.close()
       2)PyMySQL访问MySQL的流程
         第一步:导入pymysql模块
         第二步:建立到数据库服务器的连接,创建连接对象
         第三步:创建游标对象(cursor),通过调用数据库连接
                 对象获得游标
         第四步:利用cursor对象提供的方法,执行SQL语句
         第五步:提交事务(如果需要)
         第六步:关闭游标对象
         第七步:关闭数据库连接对象
      
       3)PyMySQL模块的主要方法
         - connect:  连接数据库
             参数:host    服务器地址
               port    服务器端口(省略连默认端)
               user    用户名
               passwd    密码
               db    数据库名称
               charset    指定编码格式

        - connection连接对象支持的方法
            cursor()        获取游标
            commit()        提交事务
            rollback()    回滚事务
            close()        关闭游标

        - cursor游标对象支持的方法
            execute(sql)    执行SQL语句
            fetchall()    取得查询结果集中的所有数据
            fetchone()    取查询结果集中一笔数据
            fetchmany(size)    取得指定笔数数据
            close()        关闭游标对象

           只读属性:
            rowcount        返回修改影响的笔数

       4)示例:
      示例1:查询
         # pymysql查询示例
         import pymysql
         from db_conf import * #导入配置

        #建立到数据库服务器的连接,创建连接对象
         conn = pymysql.connect(host, user, \
                    password, dbname)              

        #创建游标对象(cursor),通过调用数据库连接
         #对象获得游标
         cursor = conn.cursor()

        #利用cursor对象,执行SQL语句
         sql = "select * from acct"
         cursor.execute(sql)  #执行SQL语句

        #取出查询结果,并打印
         result = cursor.fetchall() #result是元组
         for r in result: #遍历result
             acct_no = r[0] #账号
             acct_name = r[1] #户名
             if r[6]: #判断是否为空值
             balance = float(r[6]) #余额
             else:
             balance = 0.00 #余额为空设置为0
             print("账号:%s, 户名:%s, 余额:%.2f" % \
              (acct_no, acct_name, balance))
         #关闭游标对象
         cursor.close()
         #关闭数据库连接对象
         conn.close()
       
         示例2:插入
         # pymysql的插入示例
         import pymysql
         from db_conf import * #导入配置

        try:       
             conn = pymysql.connect(host, user, \
                    password, dbname)  #连接数据库
             cursor = conn.cursor()  #获取游标
             #执行SQL语句
             sql = '''insert into
               acct(acct_no, acct_name, cust_no,
                acct_type, reg_date, status, balance)
               values('622345000010','Robert', 'C0010',
                1, date(now()), 1, 33.00)'''   
             print(sql)
             cursor.execute(sql) #执行
             conn.commit() #提交事务
             print("Insert OK")
         except Exception as e:
             print("数据库插入异常")
             print(e)
         finally:
             cursor.close() #关闭游标
             conn.close() #关闭连接

           
        示例3:修改
         import pymysql
         from db_conf import * #导入配置

        try:       
             conn = pymysql.connect(host, user, \
                    password, dbname)  #连接数据库
             cursor = conn.cursor()  #获取游标
             #执行SQL语句
             sql = '''update acct
                  set balance = balance + 1000
                 where acct_no='622345000010'
             '''   
             cursor.execute(sql) #执行
             conn.commit() #提交事务
             print("修改笔数:%d" % cursor.rowcount)
         except Exception as e:
             print("数据库修改异常")
             print(e)
         finally:
             cursor.close() #关闭游标
             conn.close() #关闭连接

        示例4:删除
        # pymysql删除示例
         import pymysql
         from db_conf import * #导入配置

        try:       
             conn = pymysql.connect(host, user, \
                    password, dbname)  #连接数据库
             cursor = conn.cursor()  #获取游标
             #执行SQL语句
             sql = '''delete from acct
             where acct_no='622345000010'
             '''   
             cursor.execute(sql) #执行
             conn.commit() #提交事务
             print("删除笔数:%d" % cursor.rowcount)
         except Exception as e:
             print("数据库删除异常")
             print(e)
         finally:
             cursor.close() #关闭游标
             conn.close() #关闭连接

    课堂作业:账户管理修改、删除功能添加上
             
     5. SQL语句优化
       1)在经常查询、排序的字段上建立索引
       2)尽量少使用不等于条件判断,不等于会放弃使用索引
       3)少使用null值判断,null值判断会放弃使用索引
       4)条件判断少使用or连接,in,not in
       5)模糊查询避免%前置
       6)查询时如果select *,直接写成字段名会提高效率
       7)尽量少在where子句中,使用字段进行运算。例如:
          select * from acct where balance / 2 > 5000
       8)数值类型的字段,进行条件比较时,一般比
          字符串比较效率更高

     作业:完善账户管理系统的修改、删除功能
            账户管理系统启动时,增加登录功能
            (原理:打印菜单前,先输入用户名、密码
              并到数据库自建的用户表中查询
          如果用户名、密码匹配,则登录成功)

PYTHON1.day21
  1 #账户类
  2 class Acct:
  3     def __init__(self,acct_no,acct_name,acct_type,balance):
  4         self.acct_no=acct_no
  5         self.acct_name=acct_name
  6         self.acct_type = acct_type
  7         self.balance = balance
  8     def __str__(self):
  9         ret = "账号:%s,户名:%s,类型:%d,余额:%.2f"%(self.acct_no,self.acct_name,self.acct_type,self.balance)
 10         return ret
acct.pyPYTHON1.day21
  1 #账户管理类(业务逻辑层)
  2 #实现账户新增,修改,删除等逻辑处理
  3 #账户类,仅用于数据传输
  4 from db_oper import *
  5 from acct import *
  6 class AccMange:#账户管理类
  7     def __init__(self,db_oper):
  8         self.db_oper = db_oper#数据访问对象
  9     #查询所有庄户信息
 10     def query_all_acct(self):
 11         accts =[]#返回的Acct对象列表,可能有多个对象
 12         #拼装所需要的SQL
 13         sql = "select * from acct_new"
 14         #执行查询
 15         result = self.db_oper.do_query(sql)
 16         if not result:
 17             print("查询结果为空")
 18             return None
 19         #返回结果:实例化一个Acct对象列表返回
 20         for r in result:#便利数据集
 21             acct_no = r[0]#账户
 22             acct_name = r[1]#姓名
 23             acct_type =int(r[3])#类型
 24             balance = r[6]#金额
 25             accts.append(Acct(acct_no,acct_name,acct_type,balance))
 26         return accts#返回对象列表
 27     #根据账户查询,最多返回一个Acct对象
 28 
 29     def query_by_id(self,acct_no):
 30         sql = "select * from acct_new where acct_no = %s" % acct_no
 31         result = self.db_oper.do_query(sql)#执行查询
 32         if not result:
 33             print("查询返回空对象")
 34             return None
 35         #提取查询结果,实例化一个Acct对象返回
 36         r = result[0]#取得第一行数据
 37         acct_no = r[0]#账号
 38         acct_name = r[1]#户名
 39         acct_type = int(r[3])#类型
 40         balance = r[6]#余额
 41         return Acct(acct_no,acct_name,acct_type,balance)
 42 
 43     def insert_acct(self,acct_new):#插入
 44         sql = '''insert into acct_new(acct_no,acct_name,acct_type,balance)values('%s','%s',%d,%.2f)'''%(acct_new.acct_no,acct_new.acct_name,acct_new.acct_type,acct_new.balance)
 45         print("\nsql:%s\n"%sql)
 46         result =self.db_oper.do_update(sql)
 47         print("执行结构,影响行数:%d"%result)
 48         return
 49 
 50     def update_acct(self,acct_new):#更新
 51         sql="update acct set acct_type =%d,balance = %.2f where acct_no='%s'"%(acct_new.acct_type,acct_new.balance,acct_new.acct_no)
 52         print("\nsql:%s\n"%sql)
 53         result = self.db_oper.do_update(sql)
 54         print("执行结束,影响行数:%d"%result)
 55         return
 56 
 57     def query_by_name(self,acct_name):#模糊?
 58         if not acct_name:
 59             print("户名对象非法")
 60             return None
 61         if acct_name =="":
 62             print("用户名不能为空")
 63             return None
 64 
 65         accts =[]
 66         sql = "select * from acct_new where acct_name ='%s'" % acct_name
 67 
 68         result = self.db_oper.do_query(sql)
 69         if not result:
 70             print("查询返回空对象")
 71             return None
 72 
 73         for acct_info in result:
 74             acct_no = acct_info[0]
 75             acct_name = acct_info[1]
 76             acct_type = int(acct_info[3])
 77             balance = acct_info[6]
 78             accts.append(Acct(acct_no,acct_name,acct_type,balance))
 79         return accts
 80 
 81 if  __name__=="__main__":
 82     db_oper = DBOper()#实例化访问对象
 83     db_oper.open_conn()#打开数据库连接
 84 
 85     am = AccMange(db_oper)#实例化AcctMange对象
 86     db_oper.close_conn()
 87 
acct_manger.pyPYTHON1.day21
  1 #ui
  2 from db_oper import *
  3 from acct_manager import *
  4 from acct import *
  5 
  6 #全局变量
  7 db_oper = None#打印主菜单
  8 am =None
  9 def print_menu():#打印主菜单
 10     #根据用户输入,进行不同操作
 11     menu = '''----------请选取要执行的操作---------
 12                      1-查询所有              4-新增账户
 13                      2-根据用户查询           5-修改账户
 14                      3-根据用户名查询         6-删除账户
 15     '''
 16     print(menu)
 17 def query_all():#查询所有账户
 18     accts = am.query_all_acct()
 19     for a in accts:
 20         print(a)
 21 
 22 def query_by_id():
 23     acct_no = input("请输入要查询的账号:")
 24     if not acct_no:
 25         print("输入账号不合法")
 26         return
 27 
 28     acct= am.query_by_id(acct_no)
 29     print("\n查询结果:")
 30     print(acct)#打印账户信息
 31     print("\n")
 32 
 33 def query_by_name():#根据用户名查询
 34     acct_name = input("请输入要查询的户名:")
 35     if not acct_name:
 36         print("输入账号不合法")
 37         return
 38 
 39     accts =am.query_by_name(acct_name)
 40     print("\n查询结果:")
 41     for acct in accts:
 42         print(acct)#打印账户信息
 43     print("\n")
 44 
 45 def add_acct():
 46     try:
 47         acct_no = input("请输入账号:")
 48         acct_name = input("请输入户名:")
 49         acct_type = int(input("请输入账户类型(1-借记卡 2-理财卡  3-代缴代扣卡):"))
 50         balance = float(input("请输入开户金额:"))
 51         assert acct_type in [1, 2, 3]
 52         assert balance >= 0.000001
 53 
 54         new_acct =Acct(acct_no,acct_name,acct_type,balance)
 55         am.insert_acct(new_acct)
 56     except Exception as e:
 57         print("操作错误")
 58         print(e)
 59     return
 60 
 61 def update_acct():
 62     try:
 63         acct_no = input("请输入账号:")
 64         acct_name = input("请输入户名:")
 65         acct_type = int(input("请输入账户类型(1-借记卡 2-理财卡  3-代缴代扣卡):"))
 66         balance = float(input("请输入开户金额:"))
 67 
 68         assert acct_type in [1, 2, 3]
 69         assert balance >= 0.000001
 70 
 71         new_acct = Acct(acct_no,acct_name,acct_type,balance)
 72         am.update_acct(new_acct)
 73     except Exception as e:
 74         print("操作错误")
 75         print(e)
 76     return
 77 #主函数
 78 def main():
 79     global db_oper
 80     global am
 81     db_oper = DBOper()#实例化数据访问对象
 82     db_oper.open_conn()#打开数据库连接
 83     am = AccMange(db_oper)#实例化AccMange对象
 84 
 85     while True:
 86         print_menu()
 87         oper = input("请选则要执行的操作:")
 88         if oper == "1":  #查询所有账户
 89             query_all()
 90         elif oper == "2":  #根据账号查询
 91             query_by_id()
 92         elif oper == "3":  #根据户名查询
 93             query_by_name()
 94         elif oper == "4":  #新增账户
 95             add_acct()
 96         elif oper == "5":  #修改账户
 97             update_acct()
 98         elif oper == "6":  #删除账户
 99             pass
100         else:
101             break
102     db_oper.close_conn()
103 
104 if __name__ == "__main__":
105     main()
acct_manger_ui.pyPYTHON1.day21
  1 #数据库配置
  2 host = 'localhost'#服务器地址
  3 user = 'root'#用户名
  4 passwd = '123456'#密码
  5 dbname = 'bank'#库名称
db_conf.pyPYTHON1.day21
  1 #数据库访问类
  2 import pymysql
  3 import db_conf
  4 class DBOper:
  5     #构造方法
  6     def __init__(self):
  7         self.host =db_conf.host
  8         self.user =db_conf.user
  9         self.passwd =db_conf.passwd
 10         self.dbname =db_conf.dbname
 11         self.db_conn = None#数据库的连接对象
 12 
 13     #连接数据库
 14     def open_conn(self):
 15         try:
 16             self.db_conn = pymysql.connect(self.host,self.user,self.passwd,self.dbname)
 17         except Exception as e:
 18             print("连接数据库失败")
 19             print(e)
 20         else:
 21             print("连接数据库成功")
 22     #关闭连接
 23     def close_conn(self):
 24         try:
 25             self.db_conn.close()
 26         except Exception as e:
 27             print("连接数据库失败")
 28             print(e)
 29         else:
 30             print("关闭数据库成功")
 31 
 32     #执行查询返回结果集
 33     def do_query(self,sql):
 34         if not sql:#参数合法性判断
 35             print("sql语句不合法")
 36             return None
 37         if sql == "":#参数合法性判断
 38             print("sql语句不合法")
 39             return None
 40 
 41         try:
 42             cursor = self.db_conn.cursor()#获取游标
 43             cursor.execute(sql)#执行sql语句
 44             result = cursor.fetchall()#获取数据
 45             cursor.close()#关闭游标
 46             return result#返回查询数据集
 47         except Exception as e:
 48             print("查询出错")
 49             print(e)
 50             return None
 51 
 52 
 53     #执行增删改等变更操作
 54     def do_update(self,sql):
 55         if not sql:#参数合法性判断
 56             print("sql语句不合法")
 57             return None
 58         if sql == "":#参数合法性判断
 59             print("sql语句不合法")
 60             return None
 61 
 62         try:
 63             cursor = self.db_conn.cursor()#获取游标
 64             result = cursor.execute(sql)#执行SQL语句
 65             self.db_conn.commit()#提交事物
 66             cursor.close()
 67             return result#返回受影响的笔数
 68         except Exception as e:
 69             print("执行sql语句出错")
 70             print(e)
 71             return None
 72 
 73 #测试
 74 if __name__=="__main__":
 75     dboper = DBOper()
 76     dboper.open_conn()
 77     ret = dboper.do_query("select * from acct_new")
 78     for x in ret:
 79         print(x)
 80 
 81     ret = dboper.do_update("update acct_new set balance = balance + 100 where acct_no = '6223456000 '")
 82 
 83     print(ret)
 84     #查询
 85     # result = dboper.do_query("select * from acct_new")
 86     # for x in result:
 87     #     print(x)
 88 
 89     # dboper.close_conn()#关闭数据库连接
 90 
 91     #修改数据测试
 92     # sql = '''update acct_new set balance = balance +1000 where acct_no ="6223456000"'''
 93     # ret = dboper.do_update(sql)
 94     # if not ret:#返回空对象,出错
 95     #     print("执行修改错误")
 96     # #非空对象,执行成功
 97     # else:
 98     #     print("影响笔数:%d"% ret)
 99     # dboper.close_conn()#关闭数据库连接
100 
101 
102 
103 
db_oper.py

上一篇:借助JavaScript中的Dom属性改变Html中Table边框的颜色


下一篇:day26