Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

38 | 电商系统表设计优化案例分析

刘超 2019-08-17
你好,我是刘超。今天我将带你一起了解下电商系统中的表设计优化。
如果在业务架构设计初期,表结构没有设计好,那么后期随着业务以及数据量的增多,系统就很容易出现瓶颈。如果表结构扩展性差,业务耦合度将会越来越高,系统的复杂度也将随之增加。这一讲我将以电商系统中的表结构设计为例,为你详讲解在设计表时,我们都需要考虑哪些因素,又是如何通过表设计来优化系统性能。

核心业务

要懂得一个电商系统的表结构设计,我们必须先得熟悉一个电商系统中都有哪些基本核心业务。这部分的内容,只要你有过网购经历,就很好理解。
一般电商系统分为平台型和自营型电商系统。平台型电商系统是指有第三方商家入驻的电商平台,第三方商家自己开设店铺来维护商品信息、库存信息、促销活动、客服售后等,典型的代表有淘宝、天猫等。而自营型电商系统则是指没有第三方商家入驻,而是公司自己运营的电商平台,常见的有京东自营、苹果商城等。
两种类型的电商系统比较明显的区别是卖家是 C 端还是 B 端,很显然,平台型电商系统的复杂度要远远高于自营型电商系统。为了更容易理解商城的业务,我们将基于自营型电商系统来讨论表结构设计优化,这里以苹果商城为例。
一个电商系统的核心业务肯定就是销售商品了,围绕销售商品,我们可以将核心业务分为以下几个主要模块:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(17)

  • -W.LI-
    外键关联,对表数据操作时,一锁锁好几张表。删除时还要做校验。影响性能

    作者回复: 对的

    2019-08-17
    15
  • 张德
    老师好 请教一个问题 以前阿里面试官就问过这么一个问题 比如在订单表中缓存了商品的名称 后来这个商品改了名字了 那我原先在订单表中的字段应该怎么处理 或者是类似的订单表中缓存的字段名称发生了改变 希望老师可以解答 谢谢

    作者回复: 订单表冗余了商品的名称,如果修改了商品名称,我们一般不会再去修改订单中的冗余数据了。

    商品是有唯一标识的,商品的具体名称的修改,其实是不会影响到用户的体验,如果商品名称修改比较大,会影响到用户体验了,这个时候我们建议下架商品,上架一个新的商品。

    2019-09-01
    3
  • 小橙橙
    老师,文中说的“通过大数据查询订单信息”这部分,能不能深入讲一下大数据实现的方案

    作者回复: 收到

    2019-08-20
    3
  • QQ怪
    逻辑复杂,且性能低下
    2019-08-17
    3
  • 失火的夏天
    外键是一个强制性的约束,插入数据会强制去外键表里先查是否有这个数据。
            更新删除的时候还得去获取外键数据的锁,并发性能下降,高并发情况还可能造成死锁。
           使用外键,讲代码层的逻辑转移到了数据库中,数据库性能开销变大,性能容易产生瓶颈。
           除了以上几个,好像还有在水平分表和分库情况下,外键是无法生效的。倒是我一直没理解是为什么。老师能说一下为什么吗?还有外键在如果存在在分库分表的系统中会有什么样的问题?
    2019-08-17
    1
  • 黎波拉小建
    说订单表需要提前用snowflake生成Id,我有点没太明白
    首先第一点 如果原始变不用自增Id用UUID是不是就行了?(不考虑UUID长度问题)
    第二主键Id与业务耦合是怎么来理解呢?
    第三用最初的自增ID到左后snowflakeId变换的复杂点在哪呢?是不是先要先加列生成新ID,同时关联表也加上新ID,然后再删除主表的老ID和关联表的老ID?

    作者回复: 我们在新建表时,DBA会要求innodb存储引擎的表中,默认需要配置自增主键ID,并且该主键ID耦合在业务中。使用自增主键主要是因为innodb中的主键索引是聚族索引,B+树中的叶子节点存储了行数据,数据记录本身被存于主索引的叶子节点上,同一个叶子节点内的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。

    如果使用非自增主键,由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构。

    DBA要求自增主键ID不参与业务,主要考虑后续数据迁移的难度。

    2019-10-17
    1
  • 风轻扬
    老师,您文中提到的键值对数据库。是指的redis,memcache,这种吗?还是RocksDB、LevelDB这种呢?

    作者回复: redis mongodb 以及es这些

    2019-09-24
  • Demon.Lee
    比较好的方式是通过一个公共表字段来存储一些具有共性的字段,创建单独的商品类型表,例如手机商品一个表、服饰商品一个表。但这种方式也有缺点,那就是可能会导致表非常多,查询商品信息的时候不够灵活,不好实现全文搜索。

    这时候,我们可以基于一个公共表来存储商品的公共信息,同时结合搜索引擎,将商品详细信息存储到键值对数据库,例如 ElasticSearch、Solr 中。

    -------------------
    老师,这段话我没有理解透,能否再深入说说,谢谢了。没搞明白到底是一个表还是多个表。

    作者回复: 一个公共表存储商品的共同信息,例如商品的sku 编码、价格、图片地址、商品类型等,这些字段都是所有商品都有的属性。

    而一些分的比较细的属性,例如商品颜色、尺寸、材料、品牌等信息则可以存储在键值对数据库。

    2019-09-19
  • godtrue
    课后思考及问题
    1:目前互联网公司一般建议逻辑上实现各个表之间的关联,而不建议使用外键来实现实际的表关联,你知道这为什么吗?
    这是因为操作复杂,性能低下。操作的复杂性体现在操作时有先后顺序的约束,有对于外键检查的约束。性能低下主要是因为数据库本身也要去对应的表中检查外键是否合法,多做了一些事情必然更耗性能。
    另外,我们使用数据库还有几条规则
    1:不允许物理删除
    2:每张表必须有id/isDel/status/createTime/createPin/updateTime/updatePin/ts这几个字段
    3:表的查询操作要尽量简单
    4:建表及改表结构必须经过架构师review
    5:对库中核心表的操作留有操作历史记录,要知道谁?啥时候?操作了啥?

    作者回复: 这几条规则已经是行业内的标准规则,值得借鉴

    2019-09-15
  • better
    老师,以订单表为例,怎么简单理解什么叫水平分表,什么叫垂直分表呢

    作者回复: 以订单的某个列作为hash,通过hash求余或一致性哈希算法来分表,例如 数据A和数据B,水平分表后就会放到两张表中;

    垂直分表则是将一张表的一些列分开到另外一张表中,例如,订单表有 订单号、付款金额、付款时间等,如果将付款金额和付款时间单独为另外一张表,这种情况就是垂直分表。

    2019-09-11
  • 疯狂咸鱼
    老师能不能讲一下设计表结构的时候的范式规则和反范式规则

    作者回复: 这块比较理论,有什么不懂的可以细节问我

    2019-08-28
  • 灿烂明天
    老师,你好,那逻辑上实现表的关联,具体怎么做才好呢?举个例子吧,谢谢

    作者回复: 例如,订单表和详细订单表中,如果是物理关联的情况下,是以订单表的ID关联详细订单表外键orderID。

    在逻辑上关联的意思就是,在没有任何业务操作的情况下,详细订单表依然有orderID字段,只是我们不需要再物理关联订单表ID了。一旦有业务操作,我们记得在业务层将两张表的操作关联起来,例如,删除主订单,此时记得删除详细订单表。

    2019-08-23
  • 星星滴蓝天
    双云
    2019-08-20
  • 小笨蛋
    有两个疑问,第一:如果把订单表以用户id维度水平分表,商家要查看他们店的所有订单情况怎么办?第二:如果商品比较多,商品也需要分表的话,用户搜索商品怎么处理?商家的要看自己店的商品怎么办?

    作者回复: 第一个疑问,商家的订单表可用冗余数据来实现,商家查看的一套数据存放在键值对数据库;第二个问题,如果商品数据量比较大,我们可将商品存放在Elasticsearch、Solr。

    2019-08-18
  • 张学磊
    主要会影响性能和并发度,外键为保证数据一致性和完整性以及级联操作会增加额外的操作,这样会影响操作性能,并且修改数据需要去另外一个表检查数据,并需要获取额外的锁,在高并发场景下,使用外键容易造成死锁

    作者回复: 会存在死锁的可能👍🏻

    2019-08-17
  • 许童童
    外键对数据库性能有影响,比如保持数据的一致性,所以我们在程序层面保证数据的一致性,这样数据库的性能就会好很多。

    作者回复: 对的,用逻辑关联来保证各个表数据的一致性。

    2019-08-17
  • 老杨同志
    使用外键,在手工处理数据时特别麻烦。update数据要求先后顺序。程序在更新数据时多了外键约束检查也影响性能

    作者回复: 是的,即麻烦又影响性能。

    2019-08-17
收起评论
17
返回
顶部