zoukankan      html  css  js  c++  java
  • mysql理论结合实际篇(一)

    最近两天做需求,是要将退款和退货报表里使用的临时表改用固定表,

    自己建表时,如(只是举例):

    CREATE TABLE tasks ( 
    task_id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    parent_id INT UNSIGNED NOT NULL DEFAULT 0, 
    task VARCHAR(100) NOT NULL, 
    test_id INT UNSIGNED NOT NULL DEFAULT 0, 
    date_added TIMESTAMP NOT NULL, 
    date_completed TIMESTAMP, 
    PRIMARY KEY (task_id), 
    key parent_id(parent_id), 
    key test_id (test_id )
    )engine=INNODB;
    

    像parent_id及test_id在连表查询时,多次出现在where的条件中,所以要给他们加上索引。

    在此过程中,我想了这么几个问题:为什么这里要用key而不用index呢?临时表有什么特点,它是存放在内存中吗?

    问题1.mysql中index和key的区别?

    ---这种问题其实也是stackoverflow里的常见问题(http://stackoverflow.com/questions/1401572/what-are-differences-between-index-v-s-key-in-mysql)---

    key 是数据库的物理结构,处于模型层面的,它包含两层意义,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的)。包括primary key, unique key, foreign key 等。

    ->primary key 

    两个作用,一是约束作用(constraint),用来规范一个存储主键和唯一性,但同时也在此key上建立了一个index;

    ->unique key

    两个作用,一是约束作用(constraint),规范数据的唯一性,但同时也在这个key上建立了一个index;

    ->foreign key

    两个作用,一是约束作用(constraint),规范数据的引用完整性,但同时也在这个key上建立了一个index;

    总结来说:MySQL中的key是同时具有constraint和index的意义

    MySQL requires every Key also be indexed, that's an implementation detail specific to MySQL to improve performance.
    

    index是数据库的物理结构,处于实现层面的,它只是辅助查询的,它创建时会在另外的表空间(mysql中的innodb表空间)以一个类似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等;因此,索引只是索引,它不会去约束索引的字段的行为(那是key要做的事情)。   

    Mysql常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引。

    问题2.mysql中内存表和临时表的区别?

    内存表:

    1. 参数控制:max_heap_table_size=1024M。
    2. 到达上线后报错,所以在同一时间需要足够的内存。
    3. 表定义保存在磁盘上,数据和索引保存在内存里面。
    4. 不能包含TEXT,BLOB等字段。
    ------------------------------------------
    5.多个session,创建表的名字不能一样
    6. 一个session创建会话后,对其他session也是可见的
    7. data目录下只有tmp_memory.frm ,表结构放在磁盘上,数据放在内存中
    8. mysql 重启或者关闭后内存表里的数据会丢失,但是表结构仍然存在
    9. 可以创建索引,删除索引,支持唯一索引
    10. 不影响主备,主库上插入的数据,备库也可以查到
    11. show tables 看得到表  

    使用内存表需注意:

    -> 内存表需要自己delete数据或者drop表;需要drop权限,这点比较危险

    ->内存表的表结构是保存在磁盘上的,如果多个session使用同一个表名,会存在冲突;如果不需要使用表名,如果使用一次都需要创建表结构,到时候会有很多小文件存在,不利于db的维护,dba清理表也有风险;

    临时表:

    1. 参数控制:tmp_table_size=1024M。
    2. 到达上线后创建文件在磁盘上。
    3. 表定义和数据都在内存里。
    4. 可以包含TEXT, BLOB等字段。
    ----------------------
    5. 创建的表的名字可以一样 
    6. 表结构和数据都放在内存中
    7. 会话消失表结构和数据都消失
    8. 可以创建索引,删除索引
    9. 主库创建的表,备库查不到,
    10. show tables 看不到表
    

    另外:临时表和内存表的ENGINE 不同,临时表默认的是MyISAM,而内存表是MEMORY

    我想之前用临时表的考虑主要是下面两个特点:

    -> 临时表是会话级别的,即使多个session创建的表名一样,都相互不影响

    -> 会话消失,所有的都消失,这点很不利于应用排查问题

    ->无论内存表还是临时表都需要消耗额外的内存空间,虽然db端可以忍受,但是不太可控;

    ->DB端还有这个参数:max_tmp_tables 一个客户能同时保持打开的临时表的最大数量,这个值默认32,可以根据需要调整此值

    参考文章:mysql的内存表和临时表

    问题3.MySQL单列索引和联合索引

    有同事小伙伴说,根据需要与否,你可以考虑下联合索引。

    “如果你对索引的理解不够,很常见的一个错误就是,为每个列穿件独立的多音,或者按照错误的顺序创建多列索引。”

    谈到索引策略,很多听到的诸如“把where条件里的列都建上索引”这样模糊的建议是非常错误的。这种方法最好的情况也只能是“一星”索引,

    要实现真正更优的索引,得花精力优化索引列的顺序,或者创建一个全覆盖的索引。

    ---注:在《高性能MySQL》中文第三版提到了索引的评估:三星评估(three-star system)

    索引将相关的记录放到一起获得一星;

    如果索引中的数据顺序和查找中的排列顺序一致获得两星;

    如果索引中的列包含了查询中需要的全部列则获得三星;

    最近几天看《高性能MySQL》还是收获挺大,勤看书还是很有必要的,同时和实践结合起来!

    后续再来补充,如有我理解不正确的地方,希望有人能提出!

  • 相关阅读:
    单变量微积分笔记19——数值积分
    单变量微积分笔记18——定积分的应用3(均值、权重、概率)
    同桌的你
    单变量微积分笔记17——定积分的应用2(体积)
    连通问题
    疯狂!!!
    单变量微积分笔记16——定积分的应用1(对数与面积)
    概率笔记1——独立事件下的简单概率
    上传图片流到服务器(AFN方法) (多张图片)(图片流)
    iOS开发通过AFNetworking上传图片到服务器
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/5767871.html
Copyright © 2011-2022 走看看