mysql+redis+memcached

数据库

数据库设计

 a. 单表
 b. FK(单表;一张表存储时,如果有重复出现的字段为了防止硬盘的浪费,所以做一个FK;去掉FK变成单表(这样子访问速度快了))
 c. M2M(多对多关系)
    
 到底是什么关系?
        单选的下拉框/radio FK;多选下拉框/checkbox M2M    

举个小例子:

问题:员工信息表员工当前薪资;保留员工的所有的调薪记录。
思路一:两张表
            员工表:
                id  name salary 
                
            调薪:
                id  price  time  员工ID 
                  
思路二:三张表
             员工表:
                id  name salary 
                
             调薪:
                id  price  time 
                
                
            员工调薪表:
                id   uid   sid

基本SQL

分组(group by)

select depart_id,count(1),max(salary),min(age),sum(age) from user group by depart_id
select depart_id,count(1),max(salary),min(age),sum(age) from user group by depart_id having count(1)>5

注意事项:

通过聚合条件group by然后进行筛选的用having不能用where

连表

inner join / left join / right join
inner join是保留两个共有的,如果一个没有就不保留。
left join 是以左表为主表,如果右表没数据,则为null
right join 是以右表为主表,如果左表没数据,则为null

举个小例子:

数据:
            部门表:
                id   title 
                1      销售
                2      运营
                3      IT
                
            用户表:
                id          name        部门id
                1           x1          1
                2           x2          1
                3           x3          1
                4           x4          1
                5           x5          1
     请问查到多少条数据?
            select * from userinfo left join depart on userinfo.did = depart.id    5
        
            select * from depart left join userinfo on userinfo.did = depart.id    7
        
            select * from userinfo inner join depart on userinfo.did = depart.id   5
        
            select * from depart inner join userinfo on userinfo.did = depart.id   5

MySQL数据库引擎以及区别?

a. 常见innodb、mysiam
b. 区别:
            - innodb:
                - 支持事务(特性:原子性、一致性、隔离性、持久性)
                  事务就是(要完成都完成,要不完成就回滚)
                - 表锁
                - 行锁
            - mysiam
                - 不支持事务
                - 表锁
                - 全文索引
                - 速度快                
补充:
            原生SQL
                begin;
                
                select * from xxx  for update;
                
                update ...
                
                commit;
            
            django:
                    
                with trancation.automic:
                    User.objects.filter().select_for_update()
应用场景:商品数据计数。

索引

作用:
        - 加速查找
        - 约束
    种类:
        - 索引:随便写
        - 唯一索引:允许Null + 不重复
        - 主键索引:不允许Null + 不重复
        
        - 联合索引:多列组成一个索引
        - 联合唯一索引:多列组成一个索引 + 唯一
            例如:
                name  email  pwd 
                
         命中索引遵循最左前缀的原则: name、name  email、name pwd、name  email  pw
补充:
        - 覆盖索引,当查找数据时候在索引表中就可以获取数据,无需去数据表中查找。
                    select name from user where name='xxx'
        - 索引合并, 使用多个单列索引进行查找。
                    select * from user where name='xx' email='xx'
                    
    
    为什么索引快?
        因为在索引结构中讲述按照B+来进行存放的数据。

优化数据库方案

    a. 索引。
    b. 固定长度的字段写在前面。
            id  name  age < id  age name
    c. 对于固定选择的内容:性别,可以将其对应关系保存在内存中。
    d. 分表
            - 垂直分分,将数据分割到N张表。
            - 水平分分,将列分到到N种表。
    e. 分库 
    f. 读写分离(主从复制)
        主:读写
        从:读        
            
        
        在django中的应用:
            models.Users.objects.filter(id=2).using('default')
            models.Users.objects.filter(id=2).using('db1')
    g. limit 
        select * from tb where name='alex' limit 1;
        
    h. 缓存
        将常用数据读取到redis中(缓存),读取速度快。
        

char和varchar的区别。

char是定长,不变的。
varchar是变长,可变的。
char 速度快,但是占空间。
varchar速度慢,但是省内存

视图、触发器、存储过程、函数

视图:视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结果集,并可以将其当作表来使用。
存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行。
mysql自定义函数就是实现程序员需要sql逻辑处理,参数是IN参数,含有RETURNS字句用来指定函数的返回类型,而且函数体必须包含一个RETURN value语句。
触发器:对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为。
事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

创建了引之后一定要命中索引

    - 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                -- 不使用索引

数据库对比

关系型数据库和非关系型数据库:
关系型数据库:MySQL、SQLite、SQLServer、access、oracle、db2 
非关系型数据库:redis、memcached、mongodb
持久化存到文件中:
MySQL、SQLite、mongodb、SQLServer、access、oracle、db2 
持久化存到内存中的是:
redis、memcached

redis和memcached的区别?

相同点:都是将数据保存到内存,存取速度都比较快。 自己想:在内存中存在一个大字典,你对字典进行操作。
不同点:
    - 数据类型:
                - redis,5大数据类型
                    {
                        k1:v1,
                        k2:[11,22],
                        k3:{
                            kk1:vv1,
                            kk2:vv2,
                        },
                        k4: {1,2,3},
                        k5: {('alex',8),('oldboy',5)}
                        
                    }
                - memcached,1中类型:字符串
                    {
                        k1:v1,
                    }
    - 持久化
                - redis,支持持久化
                - memcached,不支持。
     - 集群架构
                - redis,支持
                - memcached,不支持。
     - 自动过期策略
                - redis,支持
                    voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

                    volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
                    
                    volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
                    
                    allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
                    
                    allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
                    
                    no-enviction(驱逐):禁止驱逐数据
                - memcached,不支持。

redis持久化的两种方式

- AOF,记录下用户所有执行的命令。然后如果宕机了,或者出故障了,直接按照记录下的用户的命令就可以保持数据完整了。(恢复时间慢,但是数据能够保持完整)
- RDB,定时持久化。就是过一段时间保存一次(恢复时间快,但是数据不一定完整)

redis默认支持主从复制

主ip只用在配置文件中写上slaveof就行

redis的高可用(sentinel)哨兵

自动检测主服务器是否正常
哨兵的作用简单来说就是(主redis和复redis,主redis挂掉之后,哨兵会自动检测到,然后都连上哨兵,哨兵会自动检测谁死谁活,这就是哨兵的作用,另外哨兵尽量设置三个,如果因为网络原因或者遇到特殊情况的话,三个哨兵会以半数以上的方式决定这个redis是否宕机)

redis分布式(cluster)

 - redis cluster
 - codis 
 - Twemproxy
redis中默认有16834个哈希槽

redis分布式锁

连接所有的redis服务器,在服务器上设置 k1 = 随机字符串; 成功一半以上,表示获得锁。
其他人来,也会设置,但是设置时会成功 < 一半; 表示未获取锁,等待。
超时,锁自动释放。
释放锁;连接所有服务器删除 k1=原来设置的随机字符串 ;而且删除的时候不是执行命令,而是删除的是lua脚本,(因为脚本效率高)

 

posted @ 2018-11-21 20:10  hnlmy  阅读(677)  评论(0编辑  收藏  举报