T31 01,02架构设计与MySQL设计规约

261 阅读6分钟

项目介绍

类似12306

  • 查票、下单、付钱、通知主流程
  • 抽象商品、订单、支付核心模型
  • 处理票务异常和日志
  • 了解架构设计背后方法论
  • 以战促练,提升代码能力,设计能力,交付能力,协作能力

需求分析

分析背后的人性: 人性是提出需求的本源 • 需求产品化: 模块化、 配置化、 有逻辑 • 需求落地路径:需求分析->可行性->设计->编码->测试->发布

项目技术栈

  • Spring Boot
  • Spring Cloud
  • MyBatis
  • MySQL
  • Redis
  • Dubbo
  • RocketMQ

项目架构

  • 基于分布式微服务架构的购票系统

问题分层

  • 用户:支付
  • 业务:支持一切可以支付的第三方支付工具
  • 产品:支付需要逆向流程、异常流程、对账模块
  • 技术:高并发、可用性,实现第三方支付的链路

KISS原则

Keep it simple ans smil

架构理念:大道至简,解决问题

  • 如何系统可拓展性和可维护性
  • 如何系统恰到好处解决问题
  • 如何系统能够运行3-5年不重构
  • 业务部门挑战(价值问题)
  • 成本部门挑战(ROI问题)
  • 测试部门挑战(可测试性)
  • 技术部门挑战(可行性和工期)

DRY原则

Don't Repeat yourself

一切重复代码都可以抽象

重复代码危害:

  • 不一致性
  • 代码冗余
  • 易出BUG

七大设计原则

共同点:提升软件可拓展性、可维护性,是抽象思维和归纳思维的集中体现

实践点:类图设计,接口设计,组合设计

  • 单一职责

    • 最简单的,却是最难的
    • 高内聚、低耦合
  • 里氏替换原则

    • 鱼能游,鲨鱼能游,可以,繁殖:鲨鱼有牙齿,推导不出"鱼有牙齿"
    • 车能开,跑车能开,可以。反之: 跑车的推背感很强,“车的推背感”很强
    • 父类能够出现的地方,子类一定能够出现,这是里氏代换而子类出现的地方,用父类去代替,一般都有问题
  • 接口隔离原则

  • 组合复用原则

  • 依赖倒置原则

  • 迪米特原则

  • 开闭原则

  • 熵增定律

什么是架构?

架构是一种能力,不是一个职位

架构=组成+决策

组成=模块结构+模块关系

决策=约束+设计原则+演化方向

架构的目的

确定系统边界,在技术层面上做与不做 确定系统里各模块之间的依赖关系与模块的宏观输入与输出 使后续的子系统或模块设计在一个既定的框架内和技术方向上继续演化 明确非功能性需求,非功能性需求是指安全性、可用性、可扩展性等****

架构图

image.png

架构图分类

  • 业务架构

    • 一套方法论,对所涉及到的业务单元进行边界划分熟悉业务
    • 比如:团购网站系统->商品类目,订单服务,支付,退款等进行清晰划分
  • 应用架构

    • 对整个系统的实现进行可视化落地实践,系统的层次/开发原则/各个层次的应用服务,一般为垂直依赖型。比如:团购网站系统->数据层,服务层,通讯层,展现层
  • 数据架构

    • 是一套对存储数据的架构逻辑,根据各个系统应用场景、不同时间段的应用场景 ,对数据进行诸如数据异构、读写分离、缓存使用、分布式数据策略等划分。
  • 技术架构

    • 承接应用架构的技术需求,并根据识别的技术需求,进行技术选型,把各个关键技术和技术之间 的关系描述清楚

项目结构

image.png

MySQL设计规约

建表规约

表、字段命名:

  • 必须小写字母或数字
  • 进制数字开头
  • 进制两个_中间只出现数字
  • 不使用复数名词
  • 禁用保留字
  • 是与否必须用is_xxx

数据类型

  • 小数decimal
  • 货币数据使用最小货币单位bigint
  • 字符串长度几乎相等char
  • varchar长度不要超过5000

建表推荐规约:

  • 表命名:业务名称_表作用
  • 库名与应用尽量一致
  • 如果修改字段含义或对字段表示状态追加时,需要及时更新字段注释
  • 字段考虑数据一致
  • 单表行数超过500w或单表容量超过2GB,才推荐分库分表
  • 表必备三字段:id, create_time, update_time

索引规约

索引特性:持久性,有序性

索引分类

image.png 不可以创建的索引:覆盖索引

  1. 什么是覆盖索引,什么是回表

    什么叫覆盖索引,查找的数据都能在索引中找到数据,如user表中有name,age,phone字段,其中name、age创建了索引,根据用户名查询年龄时就走覆盖索引,查手机号时就走回表了

    什么叫回表,user表中name是索引,根据name查询,找到主键,再走主键索引找到这条记录,这就是回表,回表要走2遍索引

  1. 利用延迟关联或者子查询优化超多分页场景

select id, name, age from user limit 1000000, 10;

当offset很大时,此分页sql效率慢,有2个解决思路

1)假设id是有序的且知道上一页最后一个ID的值

select id, name, age from user where id > 9999999 limit 10;

2)先快速定位需要获取的ID段 , 然后再关联

select t1.* from table1 as t1, (select id from table1 where condition limit 100000, 10) as t2 where t1.id = t2.id

索引的数据结构:二叉查找树

image.png

索引的数据结构:btree

索引的数据结构:b+tree

image.png

索引命名规约

  • 主键索引名:pk_字段名
  • 唯一索引名:uk_字段名
  • 普通索引名:idx_字段名

创建索引规约

  • 有唯一特性字段必须建成索引
  • 在varchar字段建立索引时,必须指定长度
  • 建组合索引,区分度最高的在最左边

创建索引误解

image.png

SQL语句

  1. 推荐使用count(*)
  2. 使用ISNULL()来判断是否为NULL值---NULL参与运算的都返回NULL
  3. in操作能避免则避免,避免不了要控制后面的集合元素数据在1000个之内

ORM映射

  1. 在查询语句中一律不要用*

    • 增加查询分析器解析成本
    • 增减字段容易与resultMap配置不一致
    • 无用字段增加网络消耗
    • 可以利用覆盖索引
  2. pojo类布尔属性不能加is,而数据库字段必须加is_,所以在resultMap中进行字段与属性之间的映射

  3. 不要写一个大而全的数据更新接口

    • 易出错
    • 效率低
    • 增加binlog存储

数据库设计实战

设计思路

  1. 需求分析

    • 从名词提取实体和属性
    • 从动词提取关系
  2. 画E-R图

    • 实体对应一个表
    • 关系如果是多对多也对应一张表
  3. 画物理图