zoukankan      html  css  js  c++  java
  • 第四章-shceme和数据类型优化

    选择数据类型的原则:

    1.更小通常更好。因为占用更少磁盘,内存和cpu缓存。但是要确保没有低估,因为进行alter时,是很耗时和头疼的操作。所以当无法确定数据类型的时候,选择不会超过范围的最小类型。

    2.简单就好。简单的数据类型消耗的cpu更好,比如整型比字符串好

    3.尽量避免使用null。主要是因为mysql的内部实现问题,但这种优化一般效益比较小。

    Decimal 的缺点:

    1.占用内存多

    2.计算消耗的cpu多 所以不到必须情况最好不要使用。一种优化方法是对decimal乘以一定的量级,然后用bigint对数据进行存储


    Varchar 和 char

    Varchar 是不定长的,所以一般比char省空间,但是如果这个字段频繁被更新,可能会导致内存碎片。所以如果数据的长度比较大,而且更新很少,推荐使用这个。

    Char是定长的,适合短小的数据,可以频繁更新。

    和varchar char类似的数据还有binary,varbinary。binary是使用字节码进行存储,在做比较运算的时候比char快。

    blob和txt

    Blob和text的区别是,blob存储的是二进制数据,text存储的是文本。当数据太大的时候,可能会在一块专门的区域对他们进行存储,在数据表中存放指针。如果在这类数据类型上建立索引,一般只在前面一小部分的字符进行建立索引。可以使用max_sort_length进行设置。


    enum

    枚举在表中的存储占用的内存很小,在表中存储的是枚举的数字,如果使用字符和枚举进行匹配,会有映射操作的存在,比较消耗性能。另外,向枚举中添加成员会比较头疼,所以使用的时候要谨慎。


    时间类型

    Datetime 保存的时间的范围比较大,占用内存也多,和时区无关

    Timestamp 保存的时间范围很小,占用内存是Datetime的一半,可以根据时区进行自动转换。timestamp列默认是not null,然后可以配置自动更新。

    Mysql目前无法存储精确到秒级别的数据类型,所以需要想别的办法。


    位类型

    位数据类型 mysql把bit当做字符串类型来存储,所以检索的时候,读出来的是字符串的0或1,而不是ASCII码的0或1.但是在数字上下文的场景中,mysql会把字符串转换成数字。

    SET是一系列打包bit的集合。


    选择标识符

    选择标识符 标识列可能被用来和别的列做比较(比如关联查询中),或者通过标识列来寻找其他列。所以选择标识列的数据类型最好选用执行计算效率高的数据类型,还要确保在做列比较的时候,是使用相同类型的列进行比较,否则做类型转换会带来开销,或者错误。整数类型的性能很好。

    mysql scheme的陷阱:

    1.巨宽的表。在mysql中,在查询时,需要对行数据进行转换,如果列太多,会消耗很多的性能。

    2.太多的表关联。mysql限制了每个关联操作最多只能有61张表。而且关联表太多,会很消耗性能。

    3.滥用枚举。一个是枚举用来比较时性能不好,另外,对枚举进行修改时需要alter。

    范式和反范式:

    范式的讲解:https://i.cnblogs.com/PostDone.aspx?postid=9057094&actiontip=保存修改成功

    范式的优点和缺点:

    1.范式的更新操作通常比反范式快

    2.如果进行了很好的范式化,就很少有重复的数据,所以修改的时候只需修改很少的数据

    3.范式化的表通常更好,可以更好的放到内存里

    4.很少有多余的数据,意味着查询的时候会更少的需要distinct或者group by

    -1.范式化的设计,在查询的时候,需要做很多的关联

    -2.做关联价格比较昂贵,而且可能使一些聚簇索引失效

    反范式的优点和缺点:

    1.做一些数据的冗余,可以很好的避免关联

    2.如果不需要关联表,即使在查询的时候没有使用索引,进行全表扫描,也是顺序IO,不会造成随机IO。

    3.单独的表,可能会有更有效的索引。

    完全的范式和反范式都是实验室里才有的东西,在现实里,经常会混用范式和反范式,缓存表,以及其它技巧。

    缓存表和汇总表:

    缓存表 表示存储那些可以从其它表中获取,但是获取速度比较慢的表。进行数据的冗余查询(逻辑上的冗余)。在缓存表中,可以设置一些特殊的索引,来满足一些查询的需要。

    汇总表 保存的是使用group by语句聚合数据的表(例如:数据不是逻辑上的冗余)例如,想要得到表中的行数,但是每次都这样查询的话会比较慢,就在另外一个表中,每隔一段时间进行一次统计。

    维护缓存表和汇总表的俩种方式:1.定期重建 2.实时维护

    影子表:在更新表的时候,同时更新影子表。 需要做表切换的时候,直接对表进行重命名。

    计数器表:

    1.计数器表有一行数据,然后更新这行数据的数值。

    2.为了增加并发,可以创建多行数据,随机的更新哪一行,然后把这些行的数据加起来,就是总数。

    加快alter的速度的方法:

    1. 在从库上,先不提供服务,然后进行alter操作,然后进行主从切换

    2. 创建一个新表,进行数据备份,然后进行影子切换

    其他方法感觉不太会用到,暂不介绍。

    Ps:以下内容摘自帅哥的wiki

    表设计与字段设计的最佳实践

    库表设计

    (1)将⼤字段、访问频率低的字段拆分到单独的表中存储,分离冷热数据。

    (2)推荐使⽤HASH进⾏散表,表名后缀使⽤⼗进制数,数字必须从0开始。

    (3)按⽇期时间分表需符合YYYY[MM][DD][HH]格式,例如2013071601。年份必须⽤4位数字表⽰。例如按⽇散表user_20110209、 按月散表user_201102。

    (4)采⽤合适的分库分表策略。例如千库⼗表、⼗库百表等。

    字段设计

    (1)建议使⽤UNSIGNED存储⾮负数值。

    (2)建议使⽤INT UNSIGNED存储IPV4。

    (3)⽤DECIMAL代替FLOAT和DOUBLE存储精确浮点数。例如与货币、⾦融相关的数据。

    (4)INT类型固定占⽤4字节存储,例如INT(4)仅代表显⽰字符宽度为4位,不代表存储⻓度。

    (5)区分使⽤TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT数据类型。例如取值范围为0-80时,使⽤TINYINT UNSIGNED。

    (6)强烈建议使⽤TINYINT来代替ENUM类型。

    (7)尽可能不使⽤TEXT、BLOB类型。

    (8)禁⽌在数据库中存储明⽂密码。

    (9)使⽤VARBINARY存储⼤⼩写敏感的变⻓字符串或⼆进制内容。

    (10)使⽤尽可能⼩的VARCHAR字段。VARCHAR(N)中的N表⽰字符数⽽⾮字节数。

    (11)区分使⽤DATETIME和TIMESTAMP。存储年使⽤YEAR类型。存储⽇期使⽤DATE类型。 存储时间(精确到秒)建议使⽤TIMESTAMP类型。

    (12)所有字段均定义为NOT NULL。

  • 相关阅读:
    JS 获取本月第一天零点时间戳并转化成yy-mm-dd
    JS 两个对象数组合并并去重
    element ui datePicker 设置当前日期之前的日期不可选
    整理一些vue elementui 问题 + 链接方法
    css 修改placeholder的颜色
    js循环内0.5s停止
    自定义border 为 dashed 时的虚线间距
    如何让浮动元素水平/垂直居中
    centos7.6设置sftp服务
    HikariCP Druid比较
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/9057498.html
Copyright © 2011-2022 走看看