分库分表。卖家模块表结构:可以通过如下SQL获取商品相关的店铺信息和地理区域信息:SELECTp.*,r.[地理区域名称],s.[店铺名称],s.[信誉]FROM[商品信息]pLEFTJOIN[地理区域]rONp.[产地]=r.[地理区域代码]LEFTJOIN[店铺信息]sONp.id=s.[加盟店]WHEREp.id=?随着公司业务的快速发展,数据库中的数据量急剧增加,访问性能也随之变慢,优化迫在眉睫。分析问题出在哪里?关系型数据库本身比较容易成为系统瓶颈,单机的存储容量、连接数、处理能力都是有限的。当单表数据量达到1000W或100G时,由于查询维度较多,即使加从库,优化索引,在做很多操作时,性能还是会严重下降。方案一:通过提升服务器硬件能力来提升数据处理能力,比如增加存储容量、CPU等。这种方案成本非常高,如果瓶颈是MySQL本身,也需要提升硬件。解决方案二:将数据分散在不同的数据库中,以减少单个数据库的数据量来缓解单个数据库的性能问题,从而达到提升数据库性能的目的,如下图:拆分e-commerce数据库拆分成若干个独立的数据库,并将大表拆分成若干个小表,通过这种拆分数据库的方式解决了数据库的性能问题。分库分表是为了解决由于数据量过大导致数据库性能下降的问题。将原来独立的数据库拆分成若干个数据库,将大数据表拆分成若干个数据表,使单个数据库和单个数据表的数据量变小,从而达到提高性能的目的数据库的性能。垂直分库分库分表包括分库和分表两部分。在生产中,通常包括四种方式:垂直分仓、水平分仓、垂直分表、水平分表。先说垂直分表:通常情况下,产品详情是不会在产品列表中展示的,如下图:用户在浏览产品列表时,只有在感兴趣的时候才会查看产品的详细描述在产品中。因此,商品信息中商品描述字段的访问频率低,该字段存储空间大,访问单个数据IO耗时长;产品信息中的产品名称、产品图片、产品价格等字段数据被频繁访问。由于这两类数据的特点不同,他考虑将商品信息表拆分为:将访问频率低的商品的描述信息单独存放在一张表中,将访问频率高的商品的基本信息存放在一张表中。一个单独的表。商品列表可以使用如下sql:SELECTp.*,r.[地理区域名称],s.[店铺名称],s.[信誉]FROM[商品信息]pLEFTJOIN[地理区域]rONp.[产地]=r.[地理区域编码]LEFTJOIN[店铺信息]sONp.id=s.[StoreAffiliated]WHERE...ORDERBY...LIMIT...当需要获取商品描述时,可以通过以下sql获取:SELECT*FROM[ProductDescription]WHERE[商品ID]=?垂直表定义:将一个表按照字段分成多个表,每个表存储一部分字段。它带来的改进有:1、为了避免IO争用,减少锁表的机会,用户查看详情和商品信息浏览互不影响。2、充分发挥热门数据的运营效率,商品信息运营的高效率会被物品描述的低效所拖累。为什么大字段IO效率低:一是因为数据量本身很大,读取时间比较长;二是跨页,页是数据库的存储单元。许多搜索和定位操作都是基于页面的,单个页面字段中的数据行越多,数据库的整体性能就越好。但是大字段占用空间大,单页存储行数少,IO效率低。三、数据库以行为单位加载数据到内存,这样表中的字段长度越短,访问频率越高,内存可以加载更多的数据,命中率更高,磁盘IO减少,从而提高数据库的性能。一般来说,一个业务实体中各个数据项的访问频率是不同的,有些数据项可能是BLOB或者TEXT,占用的存储空间比较大。如上例中的产品描述。因此,当表数据量较大时,可以按字段拆分表,将热门字段和冷门字段分别放在不同的库中。这些库可以放在不同的存储设备上,避免IO争用。垂直分片带来的性能提升主要集中在热点数据的运行效率,以及磁盘争用的减少。通常我们按照以下原则进行垂直拆分:1将不常用的字段放在一个表中;2拆分text、blob等大字段,放到附表中;3把经常合并查询的列放在一个表中;垂直表分区的性能通过垂直表分区得到了一定程度的提升,但是目前还达不到要求,磁盘空间也快不够用了,因为数据还是局限在一台服务器上,图书馆垂直分表只是解决了单表的问题。数据量过大的问题,但是表并没有分布到不同的服务器上,所以每个表还是会竞争同一台物理机的CPU、内存、网络IO、磁盘。经过思考,他将原来的SELLER_DB(卖家数据库)分为PRODUCT_DB(商品数据库)和STORE_DB(门店数据库),并将这两个数据库分布到不同的服务器上,如下图所示:由于商品信息与商品的耦合descriptionbusiness度数高,所以一起存储在PRODUCT_DB(商品数据库)中;而门店信息相对独立,所以单独存储在STORE_DB(门店数据库)中。垂直分库是指按照业务对表进行分类,分布到不同的数据库中。每个数据库都可以放在不同的服务器上。它的核心概念是致力于专用数据库。它带来的提升是:解决了业务层面的耦合,清晰了业务,在不同业务中对数据进行分级管理、维护、监控、扩展。单机硬件资源的瓶颈是通过按业务对表进行分类,将数据库垂直划分,然后分布在不同的数据库中,这些数据库可以部署在不同的服务器上,从而达到多服务器分担压力的效果,但还是没有解决单表数据的问题。过剩的问题。水平分库经过垂直分库后,一定程度上解决了数据库性能问题,但是随着业务量的增长,单个PRODUCT_DB(商品数据库)存储的数据已经超出了预估。粗略估计,目前有8万家门店,每家门店平均有150种不同规格的商品。算上增长,商品数量估计有150万+,PRODUCT_DB(商品数据库)是访问频率非常高的资源。单个服务器不能再支持了。这个时候怎么优化?又是分库?但是,从业务的角度来看,现在的情况已经不能再垂直划分数据库了。尝试横向划分数据库,将店号为奇数的商品信息和店号为偶数的商品信息分别放入两个库中。也就是说,要对一条数据进行操作,首先要解析出这条数据所属店铺的ID。如果storeID是double,将这个操作映射到RRODUCT_DB1(商品数据库1);如果商店ID为奇数,则将操作映射到RRODUCT_DB2(商品数据库2)。此操作访问数据库名称的表达式为RRODUCT_DB[storeID%2+1]。数据库水平分区就是将同一个表的数据按照一定的规则拆分到不同的数据库中,每个数据库可以放在不同的服务器上。垂直分片是将不同的表拆分到不同的数据库中。它拆分数据行而不影响表结构。它带来的改进是:解决了单库大数据和高并发的性能瓶颈。提高了系统稳定性和可用性。稳定性体现在IO冲突和锁的减少上。Availability指的是某个库的问题,有的是可用的。存储性能的瓶颈此时需要水平分片。水平分片优化后,往往可以解决单库的存储容量和性能瓶颈。但是,由于同一张表分配在不同的数据库中,需要对数据操作进行额外的路由工作,大大增加了系统的复杂度。按照水平分库的思路,PRODUCT_DB_X(商品库)中的表也可以水平拆分。目的是解决单表数据量大的问题,如下图:类似水平分库的思路,但是这个操作的目标是表,商品信息和产品描述分为两组表格。如果商品ID为偶数,将本次操作映射到商品信息1表;如果产品ID为奇数,则将操作映射到产品信息2表。本次操作访问表名的表达式为商品信息[商品ID%2+1]。水平分表就是在同一个数据库中,将同一个表的数据按照一定的规则拆分成多个表。它带来的改进有:优化单表数据量过大带来的性能问题避免IO争用,降低锁表概率库内水平分表解决单表数据量过大问题小表只包含部分减少单表数据量,提高检索性能。总结一下垂直分表:宽表的字段可以根据访问频率和是否是大字段拆分成多个表,这样既可以让业务清晰,也可以提高一些性能。拆分后,从业务角度尽量避免联检,否则得不偿失。垂直分库:可以将多张表按照业务耦合分类存放在不同的库中。这些库可以分布在不同的服务器上,让访问压力由多台服务器来承担,大大提高了性能,改善了整体架构。业务清晰,不同业务库可根据自身情况定制优化方案。但它需要解决跨库带来的所有复杂性。水平分库:一个表的数据(按数据行)可以分到多个不同的数据库,每个数据库只有这个表的部分数据,这些数据库可以分布在不同的服务器上,这样访问压力大由多个服务器加载,大大提高了性能。不仅要解决所有跨库带来的复杂问题,还要解决数据路由问题(数据路由问题后面会介绍)。水平拆分表:可以将一个表的数据(按数据行)拆分成同一个数据库的多个表,每个表只有本表的部分数据。这样可以略微提高性能,只是作为水平数据库分区的一种补充优化。一般来说,在系统设计阶段,应根据业务耦合的松紧程度来确定垂直分库分表方案。当数据量和访问压力不是特别大的时候,首先要考虑缓存、读写分离、索引技术。如果数据量特别大,而且还在不断增长,那就考虑水平分库水平分表的方案。
