设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 站长学院 > MySql教程 > 正文

别再问“分库分表”了,再问就崩溃了!(3)

发布时间:2019-12-20 09:47 所属栏目:115 来源:站长网
导读:①全局表:全局表,也可看做是数据字典表,就是系统中所有模块都可能依赖的一些表,为了避免跨库 join 查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。 ②字

①全局表:全局表,也可看做是"数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库 join 查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。

②字段冗余:一种典型的反范式设计,利用空间换时间,为了性能而避免 join 查询。

例如:订单表保存 userId 时候,也将 userName 冗余保存一份,这样查询订单详情时就不需要再去查询"买家 user 表"了。

但这种方法适用场景也有限,比较适用于依赖字段比较少的情况。而冗余字段的数据一致性也较难保证,就像上面订单表的例子,买家修改了 userName 后,是否需要在历史订单中同步更新呢?这也要结合实际业务场景进行考虑。

③数据组装:在系统层面,分两次查询,第一次查询的结果集中找出关联数据 id,然后根据 id 发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。

④ER 分片:关系型数据库中,如果可以先确定表之间的关联关系,并将那些存在关联关系的表记录存放在同一个分片上,那么就能较好的避免跨分片 join 问题。在 1:1 或 1:n 的情况下,通常按照主表的 ID 主键切分。

如下图所示:

别再问“分库分表”了,再问就崩溃了!

这样一来,Data Node1 上面的 order 订单表与 orderdetail 订单详情表就可以通过 orderId 进行局部的关联查询了,Data Node2 上也一样。

跨节点分页、排序、函数问题

跨节点多库进行查询时,会出现 limit 分页、order by 排序等问题。分页需要按照指定字段进行排序,当排序字段就是分片字段时,通过分片规则就比较容易定位到指定的分片;当排序字段非分片字段时,就变得比较复杂了。

需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。

如图所示:

别再问“分库分表”了,再问就崩溃了!

上图中只是取第一页的数据,对性能影响还不是很大。但是如果取得页数很大,情况则变得复杂很多。

因为各分片节点中的数据可能是随机的,为了排序的准确性,需要将所有节点的前 N 页数据都排序好做合并,最后再进行整体的排序,这样的操作是很耗费 CPU 和内存资源的,所以页数越大,系统的性能也会越差。

在使用 Max、Min、Sum、Count 之类的函数进行计算的时候,也需要先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终将结果返回。

如图所示:

别再问“分库分表”了,再问就崩溃了!

全局主键避重问题

在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库自生成的 ID 无法保证全局唯一。

因此需要单独设计全局主键,以避免跨库主键重复问题。有一些常见的主键生成策略:

①UUID

UUID 标准形式包含 32 个 16 进制数字,分为 5 段,形式为 8-4-4-4-12 的 36 个字符,例如:550e8400-e29b-41d4-a716-446655440000。

UUID 是主键是最简单的方案,本地生成,性能高,没有网络耗时。但缺点也很明显,由于 UUID 非常长,会占用大量的存储空间。

另外,作为主键建立索引和基于索引进行查询时都会存在性能问题,在 InnoDB 下,UUID 的无序性会引起数据位置频繁变动,导致分页。

②结合数据库维护主键 ID 表

在数据库中建立 sequence 表:

CREATE TABLE `sequence` (   

  `id` bigint(20) unsigned NOT NULL auto_increment,   

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读