zoukankan      html  css  js  c++  java
  • 高性能可扩展MySQL数据库设计及架构优化 电商项目(慕课)第1章 数据库开发规范的制定

    课程准备:       MySQL 5.7版本+SQLyog

    数据库设计规范

    • 数据库命名规范

             所有的数据库对象名称必须使用小写字母并用下划线分割(数据库名 表名 列名...) 大小写敏感

            所有的数据库对象名称禁止使用MySQL保留关键字

            所有的数据库对象命名做到见名识义,最多不超过32个字符

           例如:用户数据库 mc_userdb

                     用户账号表 user_account

            临时库表必须以tmp_为前缀以日期为后缀

            备份库、备份表以bak_为前缀并以日期为后缀

             所有存储相同数据的列名和列类型必须一致

    • 数据库基本设计规范         如存储引擎的选择,字符集选择

            MySQL5.5使用之前Myisam(默认存储引擎)所有表必须使用Innodb存储引擎,(特殊需求:列存储除外,空间数据)  5.6以后的默认Innodb存储引擎,支持事务,行级锁,更好的恢复性,高并发下性能更好。

           数据库和表的字符集统一使用UTF8,兼容性更好,避免乱码。

           所有表和字段都要添加注释COMMENT,从一开始就进行数据字典的维护

           尽量控制单表数据量的大小,建议控制在500万行内,但500万行不是MySQL数据库的限制。过大对于修改表结构,备份,恢复都会有很大问题。MySQL没有对存储有限制,取决于存储设置和文件系统。

            可以使用历史数据归档,分库分表等手段来实现控制数据量大小

             谨慎使用MySQL分区表

                           分区表在物理上表现为多个文件,在逻辑上表现为一个表

                            谨慎选择分区键,跨区查询效率可能更低

                            建议采用物理分表的方式管理大数据

              尽量做到冷热数据分离,减小表的宽带

                             MySQL限制最多存储4096列,且每行不能超过65535字节。足够大了

                             减少磁盘IO,保证热数据的内存缓存命中率

                             更有效的利用缓存,避免读入无用的冷数据

                             经常一起使用的列放在一个表中

                 禁止在表中建立预留字段

                              其实很牵强,无法确认预留字段的数据类型

                              对预留字段类型进行修改,会对表进行锁定

                  禁止在数据库中存储图片,文件等二进制数据

                             使用文件服务器

                  禁止在线上数据库压力测试

                  禁止从开发环境,测试环境直接连生产环境数据库

    • 数据库索引设计规范         索引列选择的常规方式,索引优化建议及技巧

                  "双刃剑"

                  避免建立冗余索引和重复索引

                              冗余:index(a,b,c) index(a,b) index(a)

                   限制每张表的索引数量,建议单张表索引不超过5个

                               索引不是越多越好!索引可以提高效率同样也可以降低效率

                               索引可以增加查询效率,但同样也会降低插入和更新效率

                               禁止给表中的每一列都建立单独的索引

            Innodb是按照哪个索引的顺序来组织表的呢?答案:主键

                               每个Innodb表必须有一个主键(或者非空唯一的字段或自动生成的但是性能不大好)

                                不使用更新频繁的列作为主键,不能用多列做主键(联合索引)

                                不适用UUID,MD5,HASH,字符串列作为主键

                                 建议主键使用自增ID值

    常见索引列建议:select update delete语句的where从句的列

                                包含order by group by distinct中的字段       组成联合索引

                                多表join的关联列

    如何选择索引列的顺序:

                                 区分度最高(重复率低)的列放在联合索引的最左侧

                                 字段长度小的列放在联合索引的最左侧

                                 使用最频繁的列房到联合索引的左侧

    如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。

             尽量避免使用外键

                        不建议使用外键约束,但一定在表与表之间的关联键上建立索引

    • 数据库字段设计规范         如何选择列的字段类型,与性能息息相关

    优先选择符合需要的最小数据类型

                      比如:字符串转数字类型存储  INET_ACTION('255.255.255.0')=4294967295

                                                                        INET_NTOA(4294967295)='255.255.255.0'

    对于非负的数据来说,要优先使用无符号整型来存储  UNSIGNED 

    VARCHAR(N)中的N代表的是字符数,而不是字节数

    使用UTF8存储汉字VARCHAR(255)=765个字节

    过大的定义长度会消耗更多的内存

    避免使用TEXT,BLOG数据类型,使用varchar()或者把BLOB或者TEXT列分离到单独的扩展表中。

    避免使用枚举ENUM数据类型

    尽可能把所有列定义为NOT NULL

                 由于索引NULL列需要额外的空间来保存,所以要占用更多的空间

                 进行比较和计算时要对null值做特别的处理

    使用timestamp或者datetime存储时间类型 timestamp更小4字节,另一个8字节但有范围限制

    财务相关的金额类数据,使用decimal数据类型(精准浮点)float和double属于非精准浮点类型

    • 数据库SQL开发规范

     

           避免使用双%号 和  like

           使用left join 或not exists来优化not  in操作

           禁止跨库查询  为数据迁移和分库分表留出余地,降低耦合度,降低风险

            禁止使用select  * 

                       消耗更多的cpu和io以及网络带宽资源

                       无法使用覆盖索引

                       减小表结构变更带来的影响

    禁止使用不含字段列表的insert语句

    insert into t values(‘a’,‘b’,‘c’);不允许

    insert into t (c1,c2,c3)values(‘a’,‘b’,‘c’);

    避免使用子查询,可以把子查询优化为join操作(一般情况);

    因为子查询的结果集无法使用索引

    子查询会产生临时表,如果子查询数据量大会严重影响效率

    消耗过多的cpu以及io资源

    避免使用join关联太多的表,意见不超过5个

    每join一个表多占用一部分内存(join_buffer_size)

    会产生临时表操作,影响查询效率

    减少同数据库的交互次数

    数据库更适合批量操作

    合并多个相同的操作到一起,可提高处理效率

    例如:alter操作 add和change一起

    使用in代替or  in里的值不要超过500个

    禁止使用order by rand()进行随机排序

    禁止where从句中对列进行函数转换和计算

    例如:where date(createtime)=‘20160901’ 会无法使用createtime列上索引

    改成    where createtime>='20160901'

                and createtime <'20160902'

    尽量 union all 代替 union 

    拆分复杂的大SQL为多个小SQL

        MySQL一个SQL只能使用一个CPU进行计算

    • 数据库操作行为规范    运维人员

        对于大表修改使用pt-online-schema-change修改表结构

                    避免大表修改产生的主从延迟

                    避免在对表字段进行修改时进行锁表

          禁止为程序使用的账号赋予super权限

          对于程序连接数据库账号,遵循权限最小原则

  • 相关阅读:
    第七章第五题(打印不同的教)(Print distinct numbers)
    第七章第四题(分析成绩)(Analyze scores)
    第七章第三题(计算数字的出现次数)(Count occurrence of numbers)
    第七章第二题(倒置输入的数)(Reverse the numbers entered)
    第七章第一题(指定等级)(Assign grades)
    第六章第三十九题(几何:点的位置)(Geometry: point position)
    第六章第三十八题(生成随机字符)(Generate random characters)
    Java提示错误: 找不到或无法加载主类
    第六章第三十七题(格式化整数)(Format an integer)
    第六章第三十六题(几何:正多边形的面积)(Geometry: area of a regular polygon)
  • 原文地址:https://www.cnblogs.com/jiang910/p/10038623.html
Copyright © 2011-2022 走看看