《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官方網站

歡迎關注本人個人公衆號,交流更多技術信息

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章