我们已经准备好了,你呢?

2026我们与您携手共赢,为您的企业形象保驾护航!

[]

前言

数据库拆分是中高级开发者需要处理的任务,但具体操作还需根据企业实际情况来定。各种情形都可能发生,本文将围绕Mycat展开数据库拆分的实现方法。至于拆分的核心理念,将在后续文章中详细阐述。在此,我们先简要概述,暂不讨论其优缺点,读者在实践或阅读过程中可自行体会,大致可分为两大类:

分库分表这项技术看似强大,但在实际项目操作中,往往无需采用,甚至不进行分库分表可能更为适宜!

垂直拆分-分库

垂直分库是指依据业务间的相互依赖程度,将那些相互关联性较小的多个表格分散存储至不同的数据库中。这一做法与将大型系统拆分成若干个小系统的策略相仿,都是依据业务类别进行独立分割。它和“微服务治理”的实践相呼应,即每一个微服务都配备了一个专用的数据库。

Mycat数据库拆分技术_Mycat分库分表配置方案_mysql 独立表空间配置

垂直拆分-分表

在数据库操作中,垂直分表是按照“列”来进行的。若某个表的字段数量较多,我们可以创建一个新的扩展表。这样,可以将那些不常使用或字段长度较大的字段从原表中分离出来,并放置到这个扩展表中。当涉及众多字段时,比如一个包含超过100个字段的庞大表格,采用“大表拆小表”的策略将大大提升开发与维护的便捷性。此外,这种方法还能有效规避跨页现象。须知,MySQL系统底层是以数据页的形式进行数据存储的,若单条记录占用的空间过大,便可能引发跨页,进而增加不必要的性能损耗。此外,数据库以行为基准将数据导入内存,由于表中字段长度较短且被频繁访问,内存能够容纳更多的数据,提高了数据检索的命中率,进而降低了磁盘输入输出的次数,有效提升了数据库的整体性能。

mysql 独立表空间配置_Mycat分库分表配置方案_Mycat数据库拆分技术

水平拆分

当一款应用难以进一步在细小的垂直方向上进行分割,或者分割后数据量庞大,导致单个数据库在读写和存储方面出现性能限制时,便有必要采取水平切分的方式。

水平切分涉及库内分表与分库分表两种方式,这一过程依据表中数据的内在逻辑关系,将单一表中的数据根据特定条件分散至多个数据库或不同的表中。每个单独的表仅承载部分数据,这样做可以有效减小单个表的数据量,进而实现数据分布的效果。具体如图所示:

mysql 独立表空间配置_Mycat分库分表配置方案_Mycat数据库拆分技术

库内分表仅针对单个表数据量庞大这一问题有所缓解,然而并未实现将表分散至不同机器库中的目的。故此,其对减轻MySQL数据库压力的效用有限。大家依然在争夺同一物理机的CPU、内存和网络I/O资源。因此,最理想的解决方案还是采用分库分表策略。

垂直拆分-分库实现方式配置mycat的配置文件




	
	
		
		
select user() select user()

在两个mysql实例中分别创建数据库

CREATE DATABASE orders;

登陆Mycat创建四张表

-- 用户表,假如有20W用户
CREATE TABLE customer(
	id INT AUTO_INCREMENT,
	NAME VARCHAR(20),
	PRIMARY KEY (id)
);
-- 订单表,假如有2000W个订单
CREATE TABLE orders(
	id INT AUTO_INCREMENT,
	order_type INT,
	customer_id INT,
	amount DECIMAL(10,2),
	PRIMARY KEY (id)
);
-- 订单详情表,数据量和订单表一样
CREATE TABLE order_detail(
	id INT AUTO_INCREMENT,
	detail VARCHAR(20),
	order_id INT,
	PRIMARY KEY (id)
);
字典表中,若数据量达到20条,则与订单类型相对应的字典会以数字来表示类型说明,而订单表中仅需存储这些数字即可。
CREATE TABLE dict_order_type(
	id INT AUTO_INCREMENT,
	order_type VARCHAR(20),
	PRIMARY KEY (id)
);

查看表

正如图中所示,完成Mycat的创建后,Mycat界面能够成功查询到四张表格,其中一张位于上方,另外三张也排列在上方,这与我们预期的效果完全一致。

Mycat数据库拆分技术_Mycat分库分表配置方案_mysql 独立表空间配置

水平拆分-分库分表

我们注意到order表以及另一张表中的数据量极其庞大,若将它们存放在同一节点上的同一数据库中,性能将遭受影响。鉴于此,我们计划将order表和该表拆分,并将全量数据分布式存储,均匀分布在两个节点上。

切片规则

配置mycat的.xml配置文件




	
	
		
		
select user() select user()

配置rule.xml配置文件



    
    	
        customer_id
        
        mod-long
    


    
    2

在dn2服务器上构建数据表,随后对mycat进行重启操作,并成功登录mycat后向该表中添加数据。

我们之前曾提到,在SQL语法中,表名后的字段名是可以省略的。然而,在mycat进行分库分表的场景下,添加数据时则不能省略字段名,这是因为必须明确指出哪一列数据对应的是customer_id。
向订单表插入一条数据,其中订单编号为1,订单类型为101,客户编号为100,订单金额为100100元。
向订单表插入一条数据,其中订单编号为2,订单类型为101,客户编号为100,订单金额为100300元。
向订单表插入一条记录,其中订单编号为3,订单类型为101,客户编号为101,订单金额为120000元。
向订单表插入数据,其中订单编号为4,订单类型为101,客户编号为101,订单金额为103000元。
向订单表插入数据,其中订单编号为5,订单类型为102,客户编号为101,订单金额为100400元。
向订单表插入数据,其中订单编号为6,订单类型为102,客户编号为100,订单金额为100020元。

mysql 独立表空间配置_Mycat分库分表配置方案_Mycat数据库拆分技术

从图中可以观察到,向mycat中插入了六条数据,在mycat端进行查询时,能够查到全部数据,但显示的顺序并非依据id进行排列。若需实现数据的有序展示,可以通过使用order by子句进行排序。通过这种方式,我们可以在查询时分别检索出三条数据,从而实现了数据的横向拆分。

水平拆分的join关联查询

观察图表可知,当我们执行join内关联查询时,系统会提示表无法找到;既然我们对主表进行了切分,相应的,我们也需要对从表进行切分并配置。

.xml文件



在dn2上创建表,重启mycat插入数据再做查询

-- 插入数据和查询都是在mycat端操作
-- 插入数据
向订单详情表中插入一条记录,其ID为1,详情内容为'detail',所属订单ID为1。
向订单详情表中插入一条记录,其ID为2,详情内容为'detail',所属订单ID为2。
向订单详情表插入一条记录,其ID为3,详情内容为'detail',所属订单ID为3。
向订单详情表中插入一条新记录,记录编号为4,详情内容为'detail',所属订单编号为4。
向订单详情表中插入一条新记录,其ID为5,详情内容为'detail',所属订单ID为5。
向订单详情表插入数据,指定字段id为6,字段detail的值为'detail',字段order_id的值为6。
-- 连接查询
从订单表中选择所有数据,与订单详情表进行内连接,连接条件为订单表的主键与订单详情表的订单ID相等。

Mycat分库分表配置方案_Mycat数据库拆分技术_mysql 独立表空间配置

至此,我们的纵向与横向分割工作已暂告一段落,然而,这并非终点,实在令人难以置信,怎么还没结束?心态都快崩溃了。不过,大家别慌,还是按照老规矩,来杯茶,咱们接着干。

全局表

在业务表中,当数据量庞大时,往往需要进行切分处理。然而,即便是一些附属表,例如我们这里的字典表,它们之间也需要建立关联。值得注意的是,字典表的数据量并不大,且数据变动并不频繁,因此进行切片操作并不必要。在Mycat中,这类表被定义为全局表。

特点

修改.xml配置文件


保存在dn2上创建字典表,重启mycat

向字典订单类型表中插入一条记录,其中id字段值为101,order_type字段值为'type1'。
向字典订单类型表中插入一条记录,其中ID为102,订单类型为“type2”。

我们检查了数据,发现dn1和dn2上都有两条完整的数据,尽管存在数据重复的情况,幸运的是,这些表中的数据量并不大,因此无需进行数据切分即可直接进行JOIN操作。

常用分片规则

在上面的示例中,我们在进行数据分割时采用了取余数的方法,接下来,我将详细介绍在开发过程中常见的其他数据分割手段。

枚举分片

在配置文件中需设定可能涉及的枚举标识符,自行设定数据分片规则,例如依据省份或县级行政区划分存储。鉴于我国全国范围内的省份和县级行政区划是既定的,这些规则适用于此类场景。

修改.xml配置文件


修改rule.xml配置文件


	
		areacode
		hash-int
	

......

	
	partition-hash-int.txt
	
	1
	
	0

修改-hash-int.txt配置文件

110=0
120=1

重启mycat,创建表插入数据

-- 创建表
创建一个名为orders_ware_info的表结构。
	id INT AUTO_INCREMENT,
	order_id INT,
	address VARCHAR(20),
	areacode VARCHAR,
	PRIMARY KEY(id)
);
-- 插入数据
向orders_ware_info表插入数据,具体包括id字段为1,order_id字段为1,地址字段为'北京',区域代码字段为'110'。
向订单商品信息表插入数据,其中id为2,order_id为2,地址为天津,区域代码为120。

Mycat数据库拆分技术_Mycat分库分表配置方案_mysql 独立表空间配置

查询结果显示,在mycat系统中检索到的信息包括两条记录,其中一条位于北京,另一条则位于天津。

范围约定分片

例如,针对我们的用户标识符,我们将其中的0至、至等数字按照一定的区间进行存储,这种做法适用于那些事先已确定范围的应用场景。在此,我们以支付信息表作为具体的应用实例。

配置.xml文件


配置rule.xml配置文件


	
		order_id
		rang-long
	

......

	autopartition-long.txt
	0

修改-long.txt文件

注意:将原本有的配置删除

0-102 = 0
103-200=1

重启mycat,创建表,插入数据

CREATE TABLE payment_info(
	id INT AUTO_INCREMENT,
	order_id INT,
	payment_status INT,
	PRIMARY KEY (id)
);
向payment_info表插入数据,其中id为1,order_id为101,payment_status为0。
向payment_info表中插入数据,具体为:id字段值为2,order_id字段值为102,payment_status字段值为1。
向payment_info表插入数据,具体为:id字段值为3,order_id字段值为103,payment_status字段值为0。
向payment_info表插入数据,其中id字段值为4,order_id字段值为104,payment_status字段值为1。

mysql 独立表空间配置_Mycat分库分表配置方案_Mycat数据库拆分技术

观察mycat,我们发现其能够检索全部数据,具体来说,在某个平台展示了其中两条,而在另一个平台也展示了另外两条,同时数据的分布情况也是准确的。

按照日期分片

我们按照天进行划分,设定时间格式、范围

修改.xml配置文件


修改rule.xml配置文件


	
		login_date
		shardingByDate
	

......

	
	yyyy-MM-dd
	
	2020-04-01
	
	2020-04-04
	
	2

重启Mycat,创建表插入数据

CREATE TABLE login_info(
	id INT AUTO_INCREMENT,
	user_id INT,
	login_date date,
	PRIMARY KEY (id)
);
向login_info表插入数据,指定id为1,user_id为101,login_date为“2020-04-01”。
向login_info表插入数据,指定id为2,user_id为102,login_date为“2020-04-02”。
向login_info表插入一条数据,其中id字段值为3,user_id字段值为103,login_date字段值为“2020-04-03”。
向login_info表插入数据,其中id字段值为4,user_id字段值为104,login_date字段值为“2020-04-04”。
向登录信息表插入一条记录,其中ID为5,用户ID为103,登录日期为2020年4月5日。
向login_info表插入一条数据,其中id字段值为6,user_id字段值为104,login_date字段值为2020年4月6日。

mysql 独立表空间配置_Mycat分库分表配置方案_Mycat数据库拆分技术

观察结果可知,前四份数据因超出了截止日期而需重新划分区域,而对于后两份数据,大家可以依据个人意愿进行操作,检验其效果是否与预期相符,不妨深入感受一番!至此,我们已成功实施了基于Mycat的数据库分割任务,并提供了几种常见的分割方法以供参考。

全局序列

在采用分库分表的架构中,数据库中自增主键的独立性无法得到保障,因此Mycat引入了全局序列机制。这一机制支持本地配置与数据库配置的多样化实现途径。

本地文件

此方法将Mycat的配置信息写入文件,一旦调用该配置,Mycat便会自动更新相应的值。

数据库方式(推荐使用)

采用数据库的某张表执行累计操作时,并非每次生成序列都要对数据库进行读写,这样做效率较低。Mycat会提前将一部分数据加载到其内存中,使得大多数读写操作能在内存内部完成。一旦内存中的序列段用尽,Mycat便会再次从数据库中获取数据。

在dn1上创建序列表

CREATE TABLE MYCAT_SEQUENCE (
	name VARCHAR(50) NOT NULL,
	current_value INT NOT NULL,
将整数值INT设置为必填项,其默认值为100。
	PRIMARY KEY(name)
)ENGINE=InnoDB;

创建函数获取当前的值

DELIMITER $
构建一个名为“mycat_seq_currval”的函数,该函数接受一个类型为VARCHAR(50)的参数“seq_name”,并返回一个类型为VARCHAR(64)的字符串值,同时使用utf8字符集。
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
执行查询,将当前值转换为字符类型,并与增量值以逗号分隔后,将结果存入变量retval,同时从名为MYCAT_SEQUENCE的序列表中选取对应seq_name的记录。
RETURN retval;
END $
DELIMITER ;

创建函数设置的值

DELIMITER $
定义一个名为“mycat_seq_setval”的函数,该函数接受两个参数:第一个参数为字符串类型,长度不超过50个字符,用于指定序列名称;第二个参数为整型,用于设定序列的值。函数执行后返回一个字符串,长度为64个字符,字符集为UTF-8。
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
返回当前序列值,该值对应于名为`seq_name`的序列。
END $
DELIMITER ;

创建函数获取下一个的值

DELIMITER $
定义一个名为mycat_seq_nextval的函数,该函数接受一个类型为VARCHAR(50)的参数seq_name,返回一个类型为VARCHAR(64)的字符串,并使用utf8字符集。
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
将当前值增加增量,条件是名称等于序列名称,并更新current_value。
RETURN mycat_seq_currval(seq_name);
END $
DELIMITER ;

初始化序列表

新增一条记录,指定名称为ORDERS,初始设定为400000,采用increment100规则,即Mycat系统重启后该值将自动增加100,具体数值需根据业务需求自行调整。
向MYCAT_SEQUENCE表中插入数据,指定名称为'ORDERS',当前值为400000,增量设置为100。

修改.xml文件

修改Mycat的.文件

序列名称对应于特定节点,例如在dn1上建立的序列,若序列是在dn2上创建的,相应地应将节点名称更改为dn2。

#sequence stored in datanode
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1

修改.xml文件

在配置使用序列时,Mycat支持三种不同的方法,分别是:0号选项采用本地文件配置,1号选项则通过数据库进行配置,而2号选项则是基于时间戳的配置方式。

添加数据

语法操作涉及将ID的数值调整为“咱们这里序列名称”所对应的下一个值。

向订单表插入数据,其中订单编号为MYCATSEQ_ORDERS序列的下一个值,订单类型为101,客户编号为102,订单金额为1000元。

查询数据

SELECT * FROM orders;

Mycat分库分表配置方案_mysql 独立表空间配置_Mycat数据库拆分技术

时间戳方式

全局序列ID由64位二进制数构成,其中包含42位表示毫秒、5位表示机器ID、5位表示业务编码以及12位用于重复累加。将此二进制数转换为十进制后,得到的long类型序列ID为18位,且每毫秒能够支持12位的二进制数进行并发累加。

自主生成

在项目实施过程中,您可以选择自行编写生成序列的代码,亦或是采用redis的incr命令来生成序列,尽管后者也是一种可行的方法,但需要您在程序中添加相应的编码实现。尽管如此,我们仍建议您优先考虑使用Mycat自带的全球序列生成功能,即第二种方案。

总结

觉得内容精彩,不妨动手关注并收藏,若在阅读过程中遇到难以理解或存在错误之处,欢迎在评论区留言指正!

二维码
扫一扫在手机端查看

本文链接:https://by928.com/9277.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线