1. 程式人生 > >Netty遊戲伺服器實戰開發(11):Spring+mybatis 手寫分庫分表策略(續)

Netty遊戲伺服器實戰開發(11):Spring+mybatis 手寫分庫分表策略(續)

在大型網路遊戲中,傳統的遊戲伺服器無法滿足效能上的需求。所以有了分散式和微服務新起,在傳統web伺服器中,我們儲存使用者等資訊基本都是利用一張單表搞定,但是在遊戲伺服器中,由於要求比較高,我們不能存在大表操作,即分庫分表策略。在以前的文章中有關介紹分庫分表的,下面我們來實戰一下,首先我們做一個這樣的計算。

在博主開源的遊戲伺服器中有這樣一個場景:玩家資料儲存到player表中,其中將遊戲資料庫分為100個數據庫(可動態擴充套件),每個庫中有player表10張。一張表我們打算最多存放2w條資料。所以我們可以負載總使用者=100(庫)x10(表)x20000=2千萬。

但是我們不可能手動去建立這麼多表,所以我們會編寫指令碼去執行,提供一個sql模板,然後批量去建立庫。首先我們要建立100個數據庫。指令碼如下:

user=root
password=123456
socket=/usr/local/mysql/mysql.sock
mycmd="mysql -u$user -p$password -S $socket"
for  i in `seq 0 99` 
do
#   $mycmd -e "create database game_service_0$i"
  if [ $i -lt 10 ]
  then
    echo create database game_service_0$i"
     mysql -u root -e "create database game_service_0$i"; 
  fi
  if [ $i -ge 10 ]
     then
     echo " create database  game_service$i"
     mysql -u root -e "create database game_service_$i";
  fi 
done 

從指令碼中我們可以看到,迴圈建立100個名稱叫做game_service_*資料庫。

然後我們在編寫指令碼來執行sql語句,同樣我們編寫如下指令碼,指令碼功能主要是在一百個庫裡面執行sql檔案中的內容

databaseCount=99

databaseBaseName="game_service_"

sql_str=$(cat $1)

for  i in `seq 0 $databaseCount`
do
if [ $i -lt 10 ]
then
db_name=$databaseBaseName"0"$i
echo "executor sql in database $db_name"
mysql -u root  $db_name -e "$sql_str"
echo "executor over"
fi
if [ $i -ge 10 ]
then
db_name1=$databaseBaseName$i
echo "exectuor sql in database $db_name1"
mysql -u root  $db_name1 -e "${sql_str}"
echo "executor over"
fi
done

有了這些簡單的指令碼我們來編寫一個能夠建立10個庫的sql語句內容如下

/*
 Navicat Premium Data Transfer
 Date: 23/10/2018 20:00:18
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for player_0
-- ----------------------------
DROP TABLE IF EXISTS `player_0`;
CREATE TABLE `player_0`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_1`;
CREATE TABLE `player_1`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_2`;
CREATE TABLE `player_2`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_3`;
CREATE TABLE `player_3`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_4`;
CREATE TABLE `player_4`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_5`;
CREATE TABLE `player_5`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_6`;
CREATE TABLE `player_6`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_7`;
CREATE TABLE `player_7`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `player_8`;
CREATE TABLE `player_8`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `player_9`;
CREATE TABLE `player_9`  (
  `player_id` bigint(32) NOT NULL COMMENT '玩家id',
  `player_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '玩家名稱',
  `open_id` varbinary(100) NOT NULL COMMENT 'openid',
  `birthday` date NULL DEFAULT NULL COMMENT '生日',
  `gold_num` int(11) NULL DEFAULT 0 COMMENT '金幣數量',
  `diamond` int(11) NULL DEFAULT 0 COMMENT '鑽石數量',
  `player_head` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '玩家頭像',
  `last_logout_time` datetime(0) NULL DEFAULT NULL COMMENT '上次退出登入時間',
  `coun_login_time` datetime(0) NULL DEFAULT NULL COMMENT '當前登入時間',
  `buttle_num` int(11) NULL DEFAULT NULL COMMENT '闖關進度',
  `ladder_lv` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '排位賽等級(包括歷史賽季),規則程式定',
  `vip_lv` int(11) NULL DEFAULT NULL COMMENT 'vip等級',
  `player_lv` int(11) NULL DEFAULT 0 COMMENT '玩家等級',
  `exp_num` int(11) NULL DEFAULT NULL COMMENT '經驗值',
  `max_source` int(11) NULL DEFAULT NULL COMMENT '歷史最高分',
  `tong_id` bigint(32) NULL DEFAULT NULL COMMENT '戰隊id',
  `usable` int(2) NULL DEFAULT NULL COMMENT '是否可用',
  `add_money_num` int(11) NULL DEFAULT NULL COMMENT '累計充值數量',
  PRIMARY KEY (`player_id`) USING BTREE,
  UNIQUE INDEX `player_index`(`player_id`, `open_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

當我們執行指令碼後得到100個庫中有10個表。因此我們準備工作做完。接下來我們要編寫程式,使得我們通過使用者的uid來定位到使用者在某個庫中的某個表的位置。。效果圖如下:

在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述

遊戲專案後臺在短連線部分玩家資料,所以我們在技術選型上採用spring+mybatis。分庫分表的原理我們在

springMVC +mybatis+mysql多套資料來源配置
中已經介紹相關的技術。此處省略部分程式碼,主要講解一下動態資料來源的核心配置。

首先我們來看分庫分表策略DbManager



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 分庫分表策略
 *
 * @author twjitm - [Created on 2018-10-22 11:50]
 */
public class DbManager {
    private static Logger logger = LoggerFactory.getLogger(DbManager.class);

    /**
     * 分表數量
     */
    private static final int TABLE_SHARING_COUNT = 10;
    /**
     * 分庫總數
     */
    private static final int DB_SHARING_COUNT = 100;
    /**
     * 資料庫字首名稱
     */
    private static final String DB_BASE_NAME = "game_service_";


    /**
     * 獲取資料庫名稱索引
     *
     * @param playerId 根據玩家的uid來進行分庫
     * @return 返回庫索引
     */
    public static String getDataBaseName(long playerId) {
        int i = (int) (playerId % DB_SHARING_COUNT);
        if (i < TABLE_SHARING_COUNT) {
            return DB_BASE_NAME + "0" + i;
        } else {
            return DB_BASE_NAME + i;
        }
    }

    /**
     * 獲取表索引
     */
    public static int getDataTableIndex(long playerId) {
        return (int) (playerId % DB_SHARING_COUNT);

    }
}

通過程式,我們生成100個jdbc連線,內容太多,沒有截圖完整。
在這裡插入圖片描述

然後利用spring 管理這些連寫物件,通過程式生成100個連線物件

在這裡插入圖片描述

然後把這100個連線物件放到一個map集和中,新增一個application-map.xml

在這裡插入圖片描述

在動態資料來源的地方引用這個map

    <!--動態資料來源的配置-->
    <bean id="dynamicDataSource" class="com.twjitm.game.server.core.database.mybatis.DynamicDataSource">
        <property name="targetDataSources" ref="dbDataSourceMap"/>
        <!--預設資料來源-->
          <property name="defaultTargetDataSource" ref="game_service_00"/>

    </bean>

為了實現分表,我們編寫一個基礎類,當有需要使用分表的時候,mybatis對應的實體類必須繼承此類物件

/**
 * <pre>
 *     需要分表的欄位必須繼承這個類,並且需要設定index索引
 * <pre/>
 * @author twjitm - [Created on 2018-10-22 11:44]
 */
public class BasePo {
    protected int tableIndex;

    public int getTableIndex() {
        return tableIndex;
    }

    public void setTableIndex(int tableIndex) {
        this.tableIndex = tableIndex;
    }
}

在使用的時候我們在dao層

在這裡插入圖片描述

後記:上篇文章有小夥伴留言給我說事務配置失效

在這裡插入圖片描述

在這裡插入圖片描述

博主我測試沒有問題呀?