zoukankan      html  css  js  c++  java
  • day49 Pyhton 数据库Mysql 06

    多表查询

    连表查询

      要进行连接,那一定涉及两个表,两个表中要有关联条件才能进行连接

      内连接 只有表一和表二中的连接条件都满足的时候才能显示出来

        inner join on /where 条件

        select * from t1 inner join t2 on t1.id  =t2.t2_id;

        select * from t1,t2 where t1.id = t2.t2_id

      左外连接 一定显示左表中所有内容,如果右表中的内容没有符合连接条件就不显示

        left join

        select * from t1 left join t2 on t1.id = t2.t2_id;

      右外连接

        right join

        select * from t1 right join t2 on t1.id = t2.t2_id

      全外连接

        select * from t1 left join t2  on t1.id = t2.t2_id

        union

        select * from t1 right join t2 on t1.id = t2.t2_id

      所谓的连表,实际上就是把多张表通过条件的连接,变成一张大表,然后所有的查询条件都和原来一张表是一样的

      但是我们要注意两张表中如果字段的名字不同,可以直接使用

      但是我们要注意两张表中如果字段的名字相同,需要使用 表名.字段名来表示具体的字段 

      当表的名字过长的时候,可以对表进行一个临时重命名,重命名之后在本条sql中就可以使用新名字来代替原来的表名了

    # table1 : id name sex
    # table2 : id salary t1_id
    # select table1.id,table2.id,name,salary from table1 inner join table2 on table1.id = table2.t1_id;
    # select t1.id,t2.id from table1 t1 inner join table2 t2 on t1.id = t2.t1_id;

      子查询

        是先查一个表,得到一个结果,这个结果要么是n条,要么是1条,通常是一个字段

        用这个结果作为条件去查另外一张表

        子查询:结果在哪个表,最后你查的一定是那张表

        如果结果是n条:在外层查询中你可能会用到in条件

        如果结果是1条:在外层查询中你可以用 = != > < is

      索引

        加速查询速度

        mysql的存储引擎的索引基于 b+树hash做的

          innodb b+树  聚集索引/聚簇索引  非聚簇索引

          myisam b+树 非聚簇索引

          memory hash

        b+树做了那些事儿?为什么基于b+树的索引会快?

          一颗平衡树

          在非叶子节点不存储数据相关的信息,只存放指针  :  让树的高度降低了,所有的数据的寻找的时间是固定的

          在叶子节点会直接存储数据或者数据的指针       :  能够直接找到对应的数据
         
    叶子节点的各个数据块之间使用双向链表来连接 : 能够更好的进行范围排序相关的操作
         
    要想缩短树的高度,我们能做的事情
          1.就是让每一列的宽度尽量的小
         聚簇索引和非聚簇索引
          聚簇索引
            一张表只能有一个
            只在innodb存储引擎中存在
            b+树 : 在叶子节点会直接存储数据
            所有的数据存储的物理地址是根据索引顺序: 排序快
          非聚簇索引
            每张表可以有多个
            在myisam,innodb中都存在
            b+树 : 在叶子节点会存储数据的指针
            所有的数据存储的物理地址和索引顺序无关
            如果创建多个非聚簇索引,那么insert delete数据都会非常慢,并且占用更多的硬盘和内存
    今日内容
      在创建表的时候创建索引
      CREATE TABLE ind1(
                id int primary key,
                name char(12),
                index ind_name(name)
                );
      在建表之后添加索引
      CREATE TABLE ind2(
                id int primary key,
                email char(12)
                );
      CREATE INDEX ind_email on ind2(email);
      alter table ind2 add index ind_email(email);
    删除索引
    DROP INDEX ind_email ON ind2;
    索引的基础用法 
    你设置了哪个字段为索引,那么查找条件就使用这个字段,就能够加速查询  
    如果我们给id字段创建了索引,但是查找的确实email条件,那么就未命中索引,并不会加速查询  
    一次sql查询只能用上一个索引id = 1000 and email='eva1000@oldboy'

    索引的正确使用
    1.
    如果查询的结果是很多条数据的话我们仍然不能命中索引

      > < >= <= != like between and
    2. 当我们选定某一列作为索引的时候,这一列必须是区分度比较高的列
      如果这一列的内容都是重复的,那么创建了索引也不会有任何的加速效果
    3.索引列不能在条件中参与计算
    4.对于sql中的or来说,即便找到一个为假的条件
    也还是要去判断另外的条件是否成立,所以mysql并没有进行优化

      所有的查询都是从左向右一次进行的,所以使用了or的条件语句很难命中索引

      对于sql中的and,由于只要找到一个为假的条件就可以放弃判断整个语句,所以mysql进行了优化

      在所有的and条件中会找到第一个区分度最高的列来使用它的索引,来达到加快查询速度的效果

    5.联合索引:最左前缀匹配原则

      create  index  union_ind  on s1(id,email,name)

      联合索引,第一个索引项是这个索引的姓,每一次查询条件必须带着第一个索引项字段(例id),才能命中联合索引

      如果条件中丢失了第一个索引项来创建条件,那么不能命中联合索引

      create index union_ind on s1(id,email,name,sex)

      id

      email,id

      id,email,name

      id,email,name,sex

      id,name # id,sex

      id,name,sex

    聚集索引 1.纪录的索引顺序与无力顺序相同 因此更适合between and和order by操作 2.叶子结点直接对应数据 从中间级的索引页的索引行直接对应数据页 3.每张表只能创建一个聚集索引 非聚集索引 1.索引顺序和物理顺序无关 2.叶子结点不直接指向数据页 3.每张表可以有多个非聚集索引,需要更多磁盘和内容 多个索引会影响insert和update的速度

    使用python操作数据库

    import pymysql
    conn = pymysql.connect(
        host = 'localhost',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'homework',
        charset='utf8'
    )
    cur = conn.cursor(pymysql.cursors.DictCursor)   # 设置返回的数据类型是字典
    cur = conn.cursor()   # 默认返回的数据类型是元组
    # cur 数据库操作符
    # sql = 'drop table ind1;'
    # sql = """CREATE TABLE EMPLOYEE (
    #          FIRST_NAME  CHAR(20) NOT NULL,
    #          LAST_NAME  CHAR(20),
    #          AGE INT,
    #          SEX CHAR(1),
    #          INCOME FLOAT )"""
    try:
        sql = 'select * from class'
        ret = cur.execute(sql)
        conn.commit()
    except:
        conn.rollback()
    
    print(ret)
    res = cur.fetchone()
    print(res)
    ret = cur.fetchmany(2)
    # res = cur.fetchall()
    print(ret)
    cur.close()
    conn.close()
  • 相关阅读:
    111.浮动初识 Walker
    105.灰度和对比度 Walker
    102.表格属性 Walker
    POJ 1321 棋盘问题
    HDU 1106 排序 题解
    HDU 1240 Asteroids! 解题报告
    HDU 1372 Knight Moves
    HDU 1253 胜利大逃亡
    HDU 1231:最大连续子序列 解题报告
    POJ 2251 Dungeon Master
  • 原文地址:https://www.cnblogs.com/pythonz/p/10158952.html
Copyright © 2011-2022 走看看