您的位置:首页 > 博客中心 > 数据库 >

49 mysql 索引 元类

时间:2022-03-16 11:34

一 昨日回顾

  视图

  触发器

  事务

    什么是事务

    逻辑上的一组操作 要么都成功 要么都失败

    如何使用

    start transaction 开启事务 mysql 默认一条sql就是一个事务 pymysql默认开启事务

    rollback 当其中一条失败 就整体回滚

    commit 提交事务

    特性

    原子性 一致性(完整性一致 约束都是正确的) 隔离性 持久性

 

  并发带来的问题

  幻读 脏读 不可重复读

  隔离级别:

  read uncommintted  读未提交

  read committed     读已提交  脏读   不能防止幻读  和不可重复读

  repeatable read   可重复读  

  串行化        安全  效率低

存储过程

  什么是存储过程 一系列sql语句  类似于python的函数

  可以包含 热河支持语句

  有什么用?应用程序可以直接调用存储过程   降低网络传输 简化sql语句的编写

      缺点:语法恶心,扩展性差  维护性差

常用函数

备份与恢复

#单库备份
mysqldump -uroot -p123 db1 > db1.sql
mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql
?
#多库备份
mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql
?
#备份所有库
mysqldump -uroot -p123 --all-databases > all.sql


#恢复
use db1;
source /root/db1.sql

流程控制

二.mysql索引

  什么是索引

  在关系数据库中,索引是一种单独的.物理的对数据库表中一类或多列的值进行排序的一种存储结构

也称为 key

  索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容.

  为什么需要索引

  索引的就是用帮我们加快查询速度的 

  小白的误区

  既然索引如此神奇,那以后只要熟读满了就加索引,

  不对!

  索引不是越多越好,有了索引后还要考虑索引是否命中

  加上索引后写入数据速度回降低

  索引的实现原理

  就像新华字典,将字按拼音音节顺序排序,提高人的查字速度,索引也是一样

  

数据库中的索引,实现思路与字典是一致的,需要一个独立的存储结构,专门存储索引数据

本质上索引是通过不断的缩小查询范围来提高查询效率

 

索引数据结构剖析

在字典的例子中我们知道了,索引是独立于真实数据的一个存储结构,这个结构到底是什么样的?

技术分享图片

索引最终的目的是要尽可能降低io次数,减少查找的次数,以最少的io找到需要的数据,此时B+树闪亮登场

光有数据结构还不行,还需要有对应的算法做支持,就是二分查找法

有了B+数据结构后查找数据的方式就不再是逐个的对比了,而是通过二分查找法来查找(流程演示)

另外,其实大多数文件系统都是使用B+是来完成的!

 

应该选择数据量小的字段作为索引

最左匹配原则,

当b+树的数据项是符合的数据结构,比如(name,age,sex)的时候,从左边开始匹配

聚集索引

叶子节点保存的就是完整的一行记录,如果设置了主键,主键就作为聚集索引,

如果没有主键,则找第一个NOT NULL且QUNIQUE的列作为聚集索引,

如果也没有这样的列,innoDB会在内心自动产生一个聚集索引,它是自增的

辅助索引

除了聚集索引之外的索引都是辅助索引或第二索引,包括 foreign key 与 unique

辅助索引的特点:

其叶子节点保存的是索引数据与所在行的主键值,innoDB用这个 主键值来从聚集索引中

搜查找数据

三.元类

一切源自于一句话:python中一切皆为对象。既然如此类是不是也是对象呢?

所有的对象都是实例化类得到的,类也是对象,

那么类是怎么得到的呢?类是由于元类实例化得到的.

创建类的流程分析

class关键字在帮我们创建类时,必然帮我们调用了元类Teacher=type(...),那调用type时传入的参数是什么呢?必然是类的关键组成部分,一个类有三大组成部分,分别是

1、类名class_name=‘Teacher‘

2、基类们class_bases=(object,)

3、类的名称空间class_dic,类的名称空间是执行类体代码而得到的

调用type时会依次传入以上三个参数

自己来实例化一个类

           
class_name = "Teacher"
class_body = """
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def say(self):
        print(‘%s says welcome to the Beijing‘ %self.name)
"""
class_dict = exce(class_body)
bases = (object,)
Teacher = type(class_name,class_body,bases)
 

 

综上,class关键字帮我们创建一个类应该细分为以下四个过程

1.获取类名

2.获取基类

3.获取名称空间

4.实例化元类得到类

补充__call__函数得执行时机

该方法会在调用对象是自动触发执行 (对象加括号)

           
class Foo:
?
    def __call__(self, *args, **kwargs):
?
        print("run")
?
f = Foo()
f()
 

自定义元类控制类的创建

一个类没有声明自己的元类,默认他的元类就是type,除了使用内置元类type,我们也可以通过继承type来自定义元类,然后使用metaclass关键字参数为一个类指定元类

           
class Mymeta(type): #只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类
    pass
class Teacher(object,metaclass=Mymeta): # Teacher=Mymeta(‘Teacher‘,(object),{...})
    school=‘tsinghua‘
    def __init__(self,name,age):
        self.name=name
        self.age=age
?
    def say(self):
        print(‘%s says welcome to the Beijing‘ %self.name)
 

 

需求 

1.规范类名必须大写

2.类中必须包含文档注释

           
class MyMate(type):
    def __init__(self,name,bases,dic):
        print("run")
        if not dic.get("__doc__"):
            raise TypeError("类必须有文档注释!")
        if not name.istitle():
            raise TypeError("类名必须大写开头!")
        super().__init__(name,bases,dic)
class Foo(object,metaclass=MyMate):
    pass
 

 

自定义元类控制类的调用

控制类的调用过程 关键在于call函数, 类也是对象,调用类必然也会执行call函数

           
class MyMate(type):
    def __init__(self,name,bases,dic):
        print("run")
        if not dic.get("__doc__"):
            raise TypeError("类必须有文档注释!")
        if not name.istitle():
            raise TypeError("类名必须大写开头!")
        super().__init__(name,bases,dic)
?
    def __call__(self, *args, **kwargs):
        # 创建空对象
        # 调用init
        # 返回初始化后的对象
        obj = object.__new__(self)
        self.__init__(obj,*args,**kwargs)
?
        return obj
class Foo(object,metaclass=MyMate):
    """
?
    """
    def __init__(self):
        print("初始化对象")
    pass
?
f = Foo()
?
print(f)
 

 

元类实现单例

什么是单例,

单例是指的是单个实例,指一个类智能有一个实例对象

为什么要用单例

当一个类的实例中的数据不会变化时使用单例,数据是不变的

例如开发一个音乐播放器程序,音乐播放器可以封装为一个对象,那你考虑一下,当你切歌的时候,是重新创建一个播放器,还是使用已有的播放器?

因为播放器中的数据和业务逻辑都是相同的没有必要创建新的,所以最好使用单例模式,以节省资源,

 

           
#使用classmethod 实现单例
class Player():
    def __init__(self):
        print("创建播放器了")
    __play = None
    @classmethod
    def get_player(cls):
        if not cls.__play:
            cls.__play = Player()
        return cls.__play
?
?
p1 = Player.get_player();
p1 = Player.get_player();
p1 = Player.get_player();
p1 = Player.get_player();
 

该方法无法避免使用者直接调用类来实例化,这样就不是单例了

使用元类实现单例模式

           
#在类定义时 自动执行init 在init中创建实例 call中直接返回已有实例
class MyMeta(type):
    __instance = None
?
    def __init__(self,name,bases,dic):
        if not self.__instance:
            self.__instance = object.__new__(self)
            self.__init__(self.__instance)
?
        super().__init__(name, bases, dic)
?
?
    def __call__(cls):
        return cls.__instance
?
class Player(metaclass=MyMeta):
    def __init__(self):
        print("创建播放器了")
        
Player()
Player()
# 仅执行一次创建播放器
?
 

 

本类排行

今日推荐

热门手游