Mysql分区,分库和分表

本文介绍了一种基于SpringBoot+Mybatis+Druid+Sharding-Jdbc的技术栈实现Mysql水平分表的方法。通过具体配置示例展示了如何设置数据源、分表策略等关键步骤。

作者说的非常清楚了,感谢。地址为:http://haitian299.github.io/2016/05/26/mysql-partitioning/。

本人项目实践,使用sharding-jdbc进行Mysql水平分表,从参数可以看出来分表策略。

项目是基于Spring Boot + Mybatis + Druid + Sharding-Jdbc技术进行开发。

配置:

sharding.jdbc.datasource.names = mysqlDataSource
sharding.jdbc.datasource.mysqlDataSource.type = com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.mysqlDataSource.driverClassName = com.mysql.jdbc.Driver
sharding.jdbc.datasource.mysqlDataSource.url = jdbc:mysql://testhost:3306/test-database
sharding.jdbc.datasource.mysqlDataSource.username = root
sharding.jdbc.datasource.mysqlDataSource.password = root
sharding.jdbc.datasource.mysqlDataSource.maxActive = 60
sharding.jdbc.datasource.mysqlDataSource.maxWait = 20000
sharding.jdbc.datasource.mysqlDataSource.initSize = 10
sharding.jdbc.datasource.mysqlDataSource.decrypt = false
sharding.jdbc.datasource.mysqlDataSource.removeAbandoned = false
sharding.jdbc.datasource.mysqlDataSource.minIdle = 10
sharding.jdbc.datasource.mysqlDataSource.timeBetweenEvictionRunsMillis = 60000
sharding.jdbc.datasource.mysqlDataSource.minEvictableIdleTimeMillis = 300000
sharding.jdbc.datasource.mysqlDataSource.validationQuery = select 1 from dual
sharding.jdbc.datasource.mysqlDataSource.testWhileIdle = true
sharding.jdbc.datasource.mysqlDataSource.testOnBorrow = false
sharding.jdbc.datasource.mysqlDataSource.testOnReturn = false
sharding.jdbc.datasource.mysqlDataSource.poolPreparedStatements = true
sharding.jdbc.datasource.mysqlDataSource.maxPoolPreparedStatementPerConnectionSize = 100
sharding.jdbc.datasource.mysqlDataSource.removeAbandonedTimeout = 180
sharding.jdbc.datasource.mysqlDataSource.logAbandoned = true
sharding.jdbc.datasource.mysqlDataSource.filters = config,stat,mergeStat

sharding.jdbc.config.sharding.default-data-source-name = mysqlDataSource
sharding.jdbc.config.sharding.tables.test_table.actualDataNodes = mysqlDataSource.test_table_${0..1}
sharding.jdbc.config.sharding.tables.test_table.tableStrategy.inline.shardingColumn = test_column
sharding.jdbc.config.sharding.tables.test_table.tableStrategy.inline.algorithm-expression = test_table_${Math.abs(test_column.hashCode()) % 2}

Springboot配置类:

@MapperScan(basePackages = {"com.bj.services.mysql.dao"}, sqlSessionFactoryRef = "mysqlSqlSessionFactory")
@EnableConfigurationProperties(MybatisProperties.class)
@Configuration
public class DBMysqlConfig {

    /*@Bean(name = "mysqlDataSource")
    @ConfigurationProperties("spring.datasource.druid.mysql")
    public DataSource mysqlDatasource() {
        return DruidDataSourceBuilder.create().build();
    }*/

    @Bean(name = "mysqlTransactionManager")
    public DataSourceTransactionManager mysqlTransactionManager(@Qualifier("shardingDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "mysqlSqlSessionFactory")
    public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("shardingDataSource") DataSource dataSource, MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider) throws Exception {
        return buildSessionFactory(dataSource, properties, interceptorsProvider);
    }

    @Bean(name = "mysqlSqlSessionTemplate")
    public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sessionFactory) {
        sessionFactory.openSession(false);
        return new SqlSessionTemplate(sessionFactory);
    }

    // mybatis page plugin
//    @Bean
    /*public Interceptor pageInterceptor() {
        PageHelper pageHelper = BeanUtils.instantiate(PageHelper.class);
        pageHelper.setProperties(PropertiesBuilder.builder().put("dialect", "mysql").toBuild());
        return pageHelper;
    }*/

    static SqlSessionFactory buildSessionFactory(DataSource dataSource, MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setVfs(SpringBootVFS.class);
        Interceptor[] interceptors = interceptorsProvider.getIfAvailable();
        if (!ObjectUtils.isEmpty(interceptors)) {
            sessionFactory.setPlugins(interceptors);
        }
        if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
            sessionFactory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
            sessionFactory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
        }
        properties.setMapperLocations(new String[]{"classpath:mybatis/mysql/**/*Mapper.xml"});
        if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
            sessionFactory.setMapperLocations(properties.resolveMapperLocations());
        }
        //sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(READONLY_MAPPER_PACKAGES));
        return sessionFactory.getObject();
    }

 

转载于:https://www.cnblogs.com/rayallenbj/p/9802277.html

### MySQL 分区分库分表的概念及最佳实践 #### 一、MySQL 分区 (Partitioning) MySQL分区功能允许将一张大表的数据按照一定的规则划分为多个较小的逻辑部分。这些部分可以分布在同一个数据库的不同文件中,从而提高查询性能并简化维护工作。 - **分区的优点**: 提高查询效率,减少 I/O 开销,优化备份恢复操作[^3]。 - **常见分区类型**: - `RANGE` 分区: 基于某个字段范围划分数据,适用于日期或数值类型的列。 ```sql CREATE TABLE sales ( id INT NOT NULL, sale_date DATE NOT NULL ) PARTITION BY RANGE (YEAR(sale_date)) ( PARTITION p0 VALUES LESS THAN (2010), PARTITION p1 VALUES LESS THAN (2015), PARTITION p2 VALUES LESS THAN MAXVALUE ); ``` - `LIST` 分区: 类似於 RANGE,但用于离散值集合。 - `HASH` 分区: 使用哈希函数分配记录到不同的分区。 ```sql CREATE TABLE employees ( emp_id INT NOT NULL, emp_name VARCHAR(50) ) PARTITION BY HASH(emp_id) PARTITIONS 4; ``` #### 二、MySQL 分库 (Sharding) 分库是一种水平扩展技术,通过将整个数据库拆分成若干个小规模的独立数据库实例来实现负载均衡。这种策略通常称为数据库分片(Database Sharding),它能够显著提升系统的可伸缩性并发处理能力。 - **分库的核心原则**: - 数据分布均匀以避免热点问题[^1]。 - 尽量减少跨节点事务的数量以便降低复杂度延迟时间。 - **具体实施方案**: - 利用中间件工具如 MyCat 或者 ProxySQL 来完成透明化的路由转发服务。 - 自定义业务逻辑层中的 sharding key 定义机制确保一致性的映射关系建立起来。 #### 三、MySQL 分表 (Table Splitting) 当单张表内的数据量过大时,则可以通过垂直或者水平方向上的切割方式来进行分表操作。前者指的是把不同属性组分开存放到各自的实体当中去;后者则是依据某些特定条件比如时间段等标准再细分成更多子集形式存在于此之上继续运作下去而已啦! - **水平分表例子**: ```sql -- 创建按月份分割的历史订单表结构模板 CREATE TABLE orders_YYYYMM( order_id BIGINT PRIMARY KEY AUTO_INCREMENT , customer_id INT UNSIGNED NOT NULL , product_info JSON DEFAULT '{}' COMMENT '商品详情' )ENGINE=InnoDB; -- 动态生成对应年月的实际存储对象名称 SET @current_month := DATE_FORMAT(NOW(), '%Y%m'); PREPARE stmt FROM CONCAT('CREATE TABLE IF NOT EXISTS orders_',@current_month,' LIKE orders_template;'); EXECUTE stmt ; DEALLOCATE PREPARE stmt ; INSERT INTO orders_202310(...)VALUES(...); ``` --- ### 总结说明 对于大规模应用而言,在设计初期就应该充分考虑到未来可能面临的挑战,并采取合适的措施加以应对。例如采用合理的索引策略配合高效的缓存体系共同作用下才能真正意义上达到理想效果。而针对具体的场景需求则需灵活调整上述提到的各种手段组合运用才最为有效果[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值