7 Python高级 MySQL

数据库 就是特殊的文件:

  • 持久化存储
  • 读写速度极高
  • 保证数据的有效性
  • 对程序支持行非常好 容易扩展

 当前主要是用两种类型的数据库:关系型和非关系性数据库。

关系型数据库RDBMS,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来池里数据库中的数据。

关系型数据库:

  • oracle:大型项目中使用,银行 电信等项目
  • mysql:web时代使用最广泛的关系性数据库
  • ms sql server:微软的项目中使用
  • sqlite:轻量级数据库 主要应用在移动平台

SQL

结构化查询语言 是一种用来操作RDBMS的数据库语言 当前关系型数据库丢支持SQL语言操作 。

SQL语句主要分:

DQL:数据查询语言 select

DML:数据操作语言 对数据增删改

DDL:数据定义语言 进行数据库表的管理 create drop

......

数据完整性

  • 一个数据库就是一个完整的数据单元 可以包含多张表 数据被存储在表中。
  • 在表中为了更加准确的存储数据 保证数据的正确有效 可以在创建表的时候 为表添加一些强制性的验证 包括数据字段的类型 约束。

数据类型

使用数据类型原则:够用就行 尽量使用取值范围小的 而不是用大的 这样可以更多的节省存储空间。

常用数据类型:

  • 整数:int bit
  • 小数:decimal
  • 字符串:varchar char
  • 日期时间:data time datatime
  • 枚举类型:enum (就是东西给你列好 只能从这些之中选择)

对于图片 视频等 不存储在数据库中 而是上传到某个服务器上 然后在表中存储这个文件的报讯路径。

约束:

  • 主键primary key:物理上存储的数据
  • 非空not null:字段不允许填空格
  • 惟一unique:此字段的值不允许重复
  • 默认defalut:不填写此值会使用默认值 
  • 外键foreign key(存储的别的表的主键):对关系字段进行约束 当为关系字段填写值时 会到关联的表中查询此值是否存在 如果存在则填写成功 不存在则填写失败并抛出异常。

 数据库三范式

第一范式1NF:强调是列的原子性 即列不能再分成其他列。

第二范式:首先是1NF 另外包含两部分内容 一是表必须有一个主键 二是没有包含在主键中的列必须完全依赖于主键 而不能只依赖于主键的一部分。

第三范式:首先是2NF 另外非主键必须直接依赖于主键 不能存在传递连接 即不能存在:非主键列A依赖于非主键列B 非主键列B依赖于主键的情况。

 E-R模型:

E表示实体 设计实体就像定义一个类一样 指定从哪些方面描述对象 一个实体转换为数据库中的一个表

R表示关系 关系描述两个实体之间的对应规则 关系的类型包括一对一 一对多 多对多

关系也是一种数据 需要通过一个字段存储在表中

实体A对实体B为一对一 则在表A或者表B中创建一个字段 存储另一个表的主键值。

实体A对实体B为多对多 就建一张新表 这个表只有两个字段 一个用于存储A的主键值 一个存储B的主键值。

数据库练习

创建数据库:

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);

sql语句:

查询每种类型中最贵的电脑信息:

select * 
from(select cate_name as c,max(price) as m from goods group by cate_name) as ca
join goods g
on ca.c=g.cate_name and ca.m=g.price;

将上面的表拆分成多表:

创建商品分类表:

create table if not exists goods_cates(\
    -> id int unsigned primary key auto_increment,\
    -> name varchar(40) not null);

将goods表中的商品种类写入goods_cates(不用写values):

insert into goods_cates(name) select cate_name from goods group by cate_name;

同步两表的数据(将两个表关联起来):

update goods as g\
    -> join goods_cates as go\
    -> on g.cate_name = go.name\
    -> set g.cate_name = go.id;

修改cate_name类型和goods_cates中的一样:

alter table goods change cate_name cate_id int unsigned not null;

设置外键  让两个表关联起来:

alter table goods add foreign key(cate_id) references goods_cates(id);

取消外键约束:

先获取外键约束名称:show crete table goods;

删除:alter table goods drop foreign key 外键名称;

实际开发中 很少用到外键约束 会降低更新的效率。

Python操作mysql数据库:

查询数据过程:

from pymysql import *
def main():
    #创建connection连接
    conn = connect(host='localhost',port=3306,user='root',password='25257758Mn',database='jing_dong',charset='utf8')
    #获得cursor游标对象
    cls = conn.cursor()
    #执行select语句 并返回受影响的行数 查询一条数据
    count = cls.execute('select id,name from goods where id>4')
    #打印受影响的行数
    print('查询到%d条数'% count)

    for i in range(count):
        #获得查询结果
        result= cls.fetchone()#逐条取
        #fetchmany和fetchall取多条
        print(result)
    #关闭cursor对象
    cls.close()
    conn.close()

if __name__=='__main__':
    main()

根据要求查询数据:

from pymysql import *

class JD(object):
    def __init__(self):
        # 创建connection连接
        self.conn = connect(host='localhost', port=3306, user='root', password='25257758Mn', database='jing_dong',
                       charset='utf8')
        # 获得cursor游标对象
        self.cls = self.conn.cursor()

    def __del__(self):#最后肯定会被调用
        # 关闭cursor对象
        self.cls.close()
        self.conn.close()
    def execute_sql(self,sql):
        self.cls.execute(sql)
        for temp in self.cls.fetchall():
            print(temp)
    def show_all_item(self):
         sql = 'select * from goods;'
         self.execute_sql(sql)
    def show_cates(self):
        sql = 'select name from goods_cates;'
        self.execute_sql(sql)
    def show_brand_name(self):
        sql = 'select brand_name from goods group by brand_name;'
        self.execute_sql(sql)
    def add_good(self):
        item_name = input("输入新商品分类:")
        sql = 'insert into goods_cates(name) values("%s");' % item_name
        self.cls.execute(sql)
        self.conn.commit()
    def find_good(self):
        find_name = input('输入查询商品的名字:')
        #sql = """select * from goods where name = '%s'""" % find_name
        #sql注入 如果输入' or 1=1 or '1 所有数据就会都查询出来
        #print("----->%s<------" % sql)
        #self.execute_sql(sql)

        sql = 'select * from goods where name=%s'
        params = [find_name]
        self.cls.execute(sql,params)#execute自己填充%s
        print(self.cls.fetchall())

    @staticmethod#静态方法
    def print_menu():
        print('---京东---')
        print('1 所有商品')
        print('2 所有商品分类')
        print('3 所有商品品牌分类')
        print('4 添加商品分类')
        print('5 根据名字查询商品')
        return input('输入对应功能序号:')
    def run(self):
        while True:
            num = self.print_menu()
            if num == '1':
                #查询所有商品
                self.show_all_item()
            elif num == '2':
                #查询分类
                self.show_cates()
            elif num =='3':
                #查询品牌分类
                self.show_brand_name()
            elif num == '4':
                self.add_good()
            elif num == '5':
                self.find_good()
            else:
                print('输入有错误 重新输入')

def main():
    #创建一个京东商城对象
    jd = JD()
    #调用run方法让其运行
    jd.run()

if __name__ == '__main__':
    main()

python操作sql:增删改

from pymysql import *
def main():
    #创建connection连接
    conn = connect(host='localhost',port=3306,user='root',password='25257758Mn',database='jing_dong',charset='utf8')
    #获得cursor游标对象
    cls = conn.cursor()
    #执行insert语句 并返回受影响的行数 查询一条数据
    count = cls.execute('insert into goods_cates(name) values ("光盘");')
    #打印受影响的行数
    print(count)
    #提交之前的操作 如果之前已经执行多次的execute 那么就都进行提交
    conn.commit()
    #关闭cursor对象
    cls.close()
    conn.close()

if __name__=='__main__':
    main()

防止sql注入:(之前例子包含有sql注入的问题)

SQL注入,也称SQL注入SQL注码,是发生于应用程序与数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了字符检查,那么这些注入进去的恶意指令就会被数据库服务器误认为是正常的SQL指令而执行,因此遭到破坏或是入侵。

视图:就是虚拟的表 主要用来查询数据的时候来用的

show tables可以查看表以及视图

create view 视图名称 as select语句-----创建视图

 drop view 视图名称---- 删除视图

事务:一个或者一组sql语句组成一个执行单元 这个执行单元要么全部执行 要么都不执行。

事务acid属性:原子性 一致性 隔离性 持久性

set autocommit = 0;

start transaction;开启事务

begin;也是开启事务

commit;提交事务

rollback;回滚

索引

是一种特殊的文件 他们包含着对数据表里所有记录的引用指针。通俗的说数据库索引好比一本书前面的目录 能加快数据库的查询速度

索引的使用:

查看索引:show index from 表名

创建索引:

  • 如果指定字段是字符串 需要指定长度 建议长度与定义字段时的长度一样
  • 字段类型如果不是字符串 可以不填长度部分

create index 索引名称 on 表名(字段名称(长度))

删除索引:

drop index 索引名称 on 表名;

但是建立太多索引将会影响更新和插入的速度 因为需要同样更新每个索引文件;建立索引会占用磁盘空间。

mysql主从服务器:

主从同步使得数据可以从一个数据库服务器复制到其他服务器上 在复制数据时 一个服务器充当主服务器 其余服务器充当从服务器  因为复制时异步进行的 所以从服务器不需要一直连接着主服务器。

主从同步的好处:

  • 通过增加从服务器来提高数据库的性能 在主服务器上执行写入和更新 从服务器向外提供读功能 可以动态调整从服务器的数量 从而调整整个数据库的性能
  • 提高数据安全 数据已复制到从服务器 可以在从服务器上备份而不影响主服务器的相应数据
  • 在主服务器上生成实时数据 而在从服务器上分析这些数据 从而提高从服务器的性能。

(备份 恢复数据):

  • 备份: mysqldump -uroot -p 数据库名 > 保存的文件名(如python.sql)
  • 恢复:如果不小心删除了原始数据
  • 连接mysql 创建新的数据库
  • mysql -uroot -p 新数据库名 < python.sql
  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值