面试题(数据库)

 
复制代码
- 引擎
    - innodb
        - 事务
        - 行锁/表锁
            - 表锁:
                select * from tb for update;
            - 行锁:
                select id,name from tb where id=2 for update ;
    - myisam
        - 全文索引
        - 快
        - 表锁
            - select * from tb for update;
- 设计表(*)
    - FK
    - M2M
    PS: 
        - 数据库部分:课程、老师、学生、分数
        - 博客
        - 权限表

- 查询表中的数据(*)
    PS:41题

- 概念:
    - 触发器
    - 函数
        - 聚合:max/sum/min/avg
        - 时间格式化 date_format
        - 字符串拼接 concat
    - 存储过程
    以上内容都是保存在数据库中。
    
- 索引: B+/哈希索引   =》 查找速度快;更新速度慢
    单列:
        - 普通索引:加速查找
        - 唯一索引: 加速查找 + 约束:不能重复
        -     主键: 加速查找 + 约束:不能重复 + 不能为空
    多列:
        - 联合索引
        - 联合唯一索引
        PS:遵循最左前缀的规则
    其他词语:
        - 索引合并,利用多个单例索引查询;
        - 覆盖索引,在索引表中就能将想要的数据查询到;
        
- 创建了索引,应该如何命中索引?  那种情况下,创建了无法命中索引?
    - like '%xx'
        select * from tb1 where name like '%cn';
    - 使用函数
        select * from tb1 where reverse(name) = 'wupeiqi';
    - or
        select * from tb1 where nid = 1 or email = 'seven@live.com';
        特别的:当or条件中有未建立索引的列才失效,以下会走索引
                select * from tb1 where nid = 1 or name = 'seven';
                select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
    - 类型不一致
        如果列是字符串类型,传入条件是必须用引号引起来,不然...
        select * from tb1 where name = 999;
    - !=
        select * from tb1 where name != 'alex'
        特别的:如果是主键,则还是会走索引
            select * from tb1 where nid != 123
    - >
        select * from tb1 where name > 'alex'
        特别的:如果是主键或索引是整数类型,则还是会走索引
            select * from tb1 where nid > 123
            select * from tb1 where num > 123
    - order by
        select email from tb1 order by name desc;
        当根据索引排序时候,选择的映射如果不是索引,则不走索引
        特别的:如果对主键排序,则还是走索引:
            select * from tb1 order by nid desc;
     
    - 组合索引最左前缀
        如果组合索引为:(name,email)
        name and email       -- 使用索引
        name                 -- 使用索引
        email                -- 不使用索引
    
- 看-看:
    - 如何开启慢日志查询?
        slow_query_log = ON                            是否开启慢日志记录
        long_query_time = 2                              时间限制,超过此时间,则记录
        slow_query_log_file = /usr/slow.log        日志文件
        log_queries_not_using_indexes = ON     为使用索引的搜索是否记录
        
    - 执行计划
        explain select * from tb;
        
        
    - 导入和导出
        
        
- 数据库分页 
    select * form tb limit 10 offset 0
    select * form tb limit 10 offset 10
    select * form tb limit 10 offset 20
    select * form tb limit 10 offset 30
    ...
    select * form tb limit 10 offset 3000000
    
    答案一:
        先查主键,在分页。
        select * from tb where id in (
            select id from tb where limit 10 offset 30
        )
    答案二:
        按照也无需求是否可以设置只让用户看200页
        
    答案三:
        记录当前页  数据ID最大值和最小值
        在翻页时,根据条件先进行筛选;筛选完毕之后,再根据limit offset 查询。
        
        select * from (select * from tb where id > 22222222) as B limit 10 offset 0
        
        如果用户自己修改页码,也可能导致慢;此时对url种的页码进行加密(rest framework )。
复制代码
复制代码
- 引擎
- 设计表
    - FK
    - M2M
- 基本操作
    - 库
    - 表
- 存储过程、视图、函数、触发器
    - 触发器,在数据库某个表进行‘增删改’前后定义一些操作。
    - 函数,在SQL语句中使用函数。
            - select sleep(5)
            - select date_format(ctime,'%m') from tb;
    - 存储过程,将SQL语句保存到数据库中,并命名;以后在代码中调用时,直接发送名称。
        参数:
            - in 
            - out
            - inout 
        代码:
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            import pymysql

            conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
            cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
            # 执行存储过程
            cursor.callproc('p1', args=(1, 22, 3, 4))
            # 获取执行完存储的参数
            cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
            result = cursor.fetchall()

            conn.commit()
            cursor.close()
            conn.close()


            print(result)
    
    - 视图,对某些表进行SQL查询,将结果显示实时显示出来(只能查)
            v = select * from tb where id <1000
            
            select * from v 
            
            select * from (select * from tb where id <1000) as v 
            
    PS: 都是保存在数据库

- 索引 
    
- 命中索引
    
- 优化 
    - 不用 select * 
    - 固定长度字段列,往前放
    - char和varchar
    - 固定数据放入内存:choice 
    - 读写分离,利用数据库的主从进行分离:主,用于删除、修改更新;从,查。
    - 分库,当数据库中表太多,将表分到不同的数据库;例如:1w张表
    - 分表,
        - 水平分表,将某些列拆分到另外一张表;例如:博客+博客详细
        - 垂直分表,将历史信息分到另外一张表中;例如:账单
    - 缓存:利用redis、memcache
- 其它:
    - 慢日志
    - 执行计划 
    
- 分页 

补充:
    text类型,创建索引,只能创建前几个字符;
复制代码

 

posted on 2019-05-14 10:58  斜阳红红  阅读(165)  评论(0编辑  收藏  举报