1. 程式人生 > >mysql使用取摸方式分表

mysql使用取摸方式分表

AR ava 根據 不存在 mysql服務器 bsp 主鍵 年份 分享

MySQL如何優化

表的設計合理化(符合3NF)

添加適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引]

SQL語句優化

分表技術(水平分割、垂直分割)

讀寫[寫: update/delete/add]分離

存儲過程 [模塊化編程,可以提高速度]

mysql配置優化 [配置最大並發數my.ini, 調整緩存大小 ]

mysql服務器硬件升級

定時的去清除不需要的數據,定時進行碎片整理(MyISAM)

水平拆分

上面談到垂直切分只是把表按模塊劃分到不同數據庫,但沒有解決單表大數據量的問題,而水平切分就是要把一個表按照某種規則把數據劃分到不同表或數據庫裏。例如像計費系統,通過按時間來劃分表就比較合適,因為系統都是處理某一時間段的數據。而像

SaaS應用,通過按用戶維度來劃分數據比較合適,因為用戶與用戶之間的隔離的,一般不存在處理多個用戶數據的情況,簡單的按user_id範圍來水平切分

通俗理解:水平拆分行,行數據拆分到不同表中, 垂直拆分列,表數據拆分到不同表中

水平分割案例

思路:在大型電商系統中,每天的會員人數不斷的增加。達到一定瓶頸如何優化查詢

可能大家會想到索引,萬一用戶量達到級別,如何進行優化呢?

使用水平分割拆分數據庫表。

如何使用水平拆分數據庫

使用水平分割拆分,具體根據業務需求,有的按照註冊時間、取摸、賬號規則年份等。

代碼實戰

項目結構圖

技術分享圖片

package cn.zhiwei.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

/**
 * 首先在數據庫新建一個表存放自增id
 * CREATE TABLE UUID(id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT)ENGINE=MYISAM CHARSET utf8;
 * Created by 劉誌威 on 2018/4/26.
 */
@Service
public class UserService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //進行分表,按數據庫的主鍵id來分
    public boolean markTable(String name){
        // 1.先獲取到 自定增長ID
        String idInsertSQL = "INSERT INTO uuid VALUES (NULL);";
        jdbcTemplate.update(idInsertSQL);
        //得到了三個表共用一個自增id
        Long insertId = jdbcTemplate.queryForObject("select last_insert_id()", Long.class);
        //利用取模算法得到表名 表為user0 user1 user2
        String table ="user" +insertId % 3;
        //拼成添加的sql
        String sql="insert into "+table+" values (‘"+insertId+"‘,‘"+name+"‘);";
        System.out.println("SQL:" + sql);
        //執行添加方法
        int update = jdbcTemplate.update(sql);

        return update>0?true:false;
    }
    //分表查詢
    public String getUserName(Long id) {
        //得到表名
        String tableName = "user" + id % 3;
        //拼接查詢語句
        String sql = "select name from " + tableName + "  where id="+id;
        System.out.println("SQL:" + sql);
        String name = jdbcTemplate.queryForObject(sql, String.class);
        return name;
    }
}

  

package cn.zhiwei.controller;

import cn.zhiwei.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by 劉誌威 on 2018/4/26.
 */
@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/insertUser")
    public Object insertUser(String name){
        return userService.markTable(name);
    }

    @RequestMapping("/selectName")
    public Object selectName(Long id){
        return userService.getUserName(id);
    }
}

  

package cn.zhiwei;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 啟動類
 * Created by 劉誌威 on 2018/4/26.
 */
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
}

 

頁面效果

 技術分享圖片

技術分享圖片

技術分享圖片

mysql使用取摸方式分表