《Sharding-JDBC》——数据库分表+数据库脱敏实现方案

本文从实际情况出发,解决生产中单表数据过大,和数据被拖库导致的问题,并进行的解决方案。本案例使用的框架为轻量型的jfinal,分表+数据库脱敏,均采用了Apache的shardingsphere

首先我们要先明确这样一个业务场景,如果生产上某个表的数据在100w+,那么sql语句进行表操作,还不会出现什么瓶颈问题,如果数据量再增加到500w+,可以通过索引,备份等方式,减少数据库的单表压力。如果继续增加到1000w。或者单表一天的数据量就能达到1000w。那么建议索引就无法在解决在这个问题。这时候,我们就需要通过分表的操作,来降低单表的压力。

实现思路:
  1. 上面我们已经知道了问题所在,下面来分析一下解决方案。既然单个表无法满足生产上是数据量,那么就需要创建多个表。而如何将多个表进行关联起来,我们就需要用到分表组件:ShardingSphere中的sharding-jdbc模块。
解决方案:(全部代码会在文末全部提供)

1.首先,我们数据库中只有一张表 t_blog。假设这张表的数据量已经达到的1000w的级别。接下来我们在创建8张表,表名为t_blog_x,这8张表的结构和原来的完全一样,这8张表我们把它称为真实表,而原来的t_blog表,我们称为逻辑表
在这里插入图片描述

2.创建好表之后,接下来进行代码部分实现。主要核心的class有下列三个。HashPreciseShardingAlgorithm为分表策略。ShardingCacheKit为缓存分表结果(可有可无)。ShardingDruidPlugin分表数据源配置。
在这里插入图片描述

3.紧接着,我们需要在配置文件中,配置之分表内容。

# 主数据源
master.jdbcUrl = jdbc:mysql://localhost/jfinal_demo?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
master.user = root
master.password =123456

## 分表规则 :对t_blog进分表,分表规则为根据id进行分表,共分为8张真实表
sharding = t_blog:8:id

devMode = true

4.在项目的主函数中配置分表代码。

	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置 druid 数据库连接池插件
		Map<String,DruidPlugin> dataSourceMap = new HashMap<String, DruidPlugin>();

		DruidPlugin masterPlugin = new DruidPlugin(p.get("master.jdbcUrl"), p.get("master.user"), p.get("master.password").trim());

		dataSourceMap.put("jf_master",masterPlugin);

		// 配置分表规则
		ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
		shardingRuleConfiguration.setDefaultDataSourceName("jf_master");

		shardingRuleConfiguration.setEncryptRuleConfig(getOrderEncryptRuleConfiguration());

		List<TableRuleConfiguration> tableRuleConfigurations = new LinkedList<>();
		// 读取分表配置,生成分表规则
		String sharding = p.get("sharding");
		String [] rule = sharding.split(":");
		if(!Objects.isNull(rule)){
			// 1. 获得真实表数目
			int num = Integer.parseInt(rule[1]);
			// 2.// 获得逻辑表名
			String tableName = rule[0];
			// 3.// 分表字段
			String shardingColumn = rule[2];
			ShardingCacheKit.me().setCache(tableName,num);
			// 4.分表规则和生成分表表达式
			TableRuleConfiguration tableRuleConfiguration =
					new TableRuleConfiguration(tableName,"jf_master." + tableName + "_${0.. " + (num -1 ) +"}");

			// 5.配置分表策略
			StandardShardingStrategyConfiguration shardingStrategyConfiguration =
					new StandardShardingStrategyConfiguration(shardingColumn,new HashPreciseShardingAlgorithm());
			tableRuleConfiguration.setTableShardingStrategyConfig(shardingStrategyConfiguration);
			// 6. 加入策略
			tableRuleConfigurations.add(tableRuleConfiguration);
			shardingRuleConfiguration.setTableRuleConfigs(tableRuleConfigurations);

		}

		Properties props = new Properties();
		props.setProperty(ShardingPropertiesConstant.SQL_SHOW.getKey(),"true");
		// 加入分表插件
		ShardingDruidPlugin shardingDruidPlugin = new ShardingDruidPlugin(shardingRuleConfiguration,dataSourceMap,props);

		me.add(shardingDruidPlugin);

		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(shardingDruidPlugin);
		// 所有映射在 MappingKit 中自动化搞定
		_MappingKit.mapping(arp);
		me.add(arp);

		// 配置缓存插件
		me.add(new EhCachePlugin());
	}

5.然后启动项目进行测试,在这里我写了一个简单的save方法,接口返回uuid和该数据存在的真实表表名。

在这里插入图片描述

在这里插入图片描述

  1. 接口调用两次后,我们可以看到,两次的数据保存在了不同的表中。

7.接下来我们配置数据库脱敏。

	/**
	 * 脱敏配置
	 * @return
	 */
	private static EncryptRuleConfiguration getOrderEncryptRuleConfiguration() {
		EncryptRuleConfiguration encryptRuleConfiguration = new EncryptRuleConfiguration();
		Properties properties = new Properties();
		// 设置算法的密钥
		properties.setProperty("aes.key.value", "123456");
		// 将逻辑表t_blog的content列进行脱敏,算法采用AES
		EncryptorRuleConfiguration encryptorRuleConfiguration =
				new EncryptorRuleConfiguration("AES", "t_blog.content", properties);
		encryptRuleConfiguration.getEncryptorRuleConfigs().put("user_encryptor", encryptorRuleConfiguration);

		return encryptRuleConfiguration;
	}

8.两次数据库中的内容如下

在这里插入图片描述

在这里插入图片描述

该项目源码地址:
GitHub项目地址

参考文档:

shardingsphere官方网站

欢迎关注本人个人公众号,交流更多技术信息

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tomatocc

赏杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值