2401_83078831 2024-06-17 18:55 采纳率: 61.5%
浏览 5

shardingjdbc分片策略模拟广播表数据的插入与更新

有数据库a,它有des信息表,有数据库b,它也有des信息表,shardingjdbc配置文件中设置did为分片值,映射真实表为a.des,b.des,那么使用standard策略,它的分库精确值算法类不管did值为多少,都返回a、b,分表精确值算法类不管did值为多少,都返回des,那么是不是在进行数据插入时,两个库的des都会插入同样的数据 ,理论上比如插入一条did为1的数据,两个表都会有这条数据。对其中某一个表进行操作,另外一个表也会进行一样的操作,我这个算不算用分片策略模拟了广播表的插入与更新?

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-17 18:55
    关注

    引自免费微信小程序:皆我百晓生

    要使用ShardingJDBC模拟广播表的插入与更新行为,确实可以通过特定的分片策略实现。在标准分片策略(StandardShardingStrategyConfiguration)中,你可以自定义分库和分表策略,使得不论传入的分片键是什么值,数据都能被路由到所有指定的数据库和表上。

    配置示例

    首先,创建分库策略类和分表策略类,它们将始终返回所有数据库和表,无论分片键是什么。

    1. 分库策略类

    public class AlwaysAllDatabasesShardingAlgorithm implements ShardingSphereAlgorithm {
    
        @Override
        public Collection<String> doSharding(Collection<String> availableTargetNames, ShardingValue shardingValue) {
            return availableTargetNames;
        }
    }
    

    2. 分表策略类

    public class AlwaysAllTablesShardingAlgorithm implements ShardingSphereAlgorithm {
    
        @Override
        public Collection<String> doSharding(Collection<String> availableTargetNames, ShardingValue shardingValue) {
            return availableTargetNames;
        }
    }
    

    3. ShardingJDBC配置

    在ShardingJDBC的配置中,使用上述自定义的策略类:

    ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
    shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
    shardingRuleConfig.setBindingTableGroups(Arrays.asList("t_order,t_order_item"));
    shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("did", new AlwaysAllDatabasesShardingAlgorithm()));
    shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("did", new AlwaysAllTablesShardingAlgorithm()));
    
    DataSourceRuleConfiguration dataSourceRuleConfig = new DataSourceRuleConfiguration();
    dataSourceRuleConfig.getDataSources().put("ds_0", new DataSourceParameter("jdbc:mysql://localhost:3306/db_a?serverTimezone=UTC&useSSL=false", "root", "password"));
    dataSourceRuleConfig.getDataSources().put("ds_1", new DataSourceParameter("jdbc:mysql://localhost:3306/db_b?serverTimezone=UTC&useSSL=false", "root", "password"));
    
    ShardingSphereDataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceRuleConfig, shardingRuleConfig, new Properties());
    

    测试插入与更新

    为了验证数据是否正确地被插入并更新到所有的数据库和表中,可以编写一些测试代码:

    public class BroadcastTest {
        private static final String SQL_INSERT = "INSERT INTO t_order (order_id, user_id, status) VALUES (?, ?, ?)";
        private static final String SQL_UPDATE = "UPDATE t_order SET status = ? WHERE order_id = ?";
        
        @Test
        public void testInsert() throws SQLException {
            try (Connection conn = dataSource.getConnection();
                 PreparedStatement ps = conn.prepareStatement(SQL_INSERT)) {
                ps.setInt(1, 1);
                ps.setInt(2, 1);
                ps.setString(3, "INIT");
                ps.executeUpdate();
            }
        }
    
        @Test
        public void testUpdate() throws SQLException {
            try (Connection conn = dataSource.getConnection();
                 PreparedStatement ps = conn.prepareStatement(SQL_UPDATE)) {
                ps.setString(1, "FINISH");
                ps.setInt(2, 1);
                ps.executeUpdate();
            }
        }
    }
    

    结论

    通过上述配置和测试,每次执行插入或更新操作时,数据将被复制到所有分片中的对应表。这实质上实现了广播表的功能,即每个分片都包含相同的数据集。不过,要注意的是,这种策略可能会导致数据冗余和存储成本增加,因此在实际生产环境中使用时需谨慎考虑。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月17日

悬赏问题

  • ¥15 Sumo软件无法运行
  • ¥15 如何在vscode里搭建stata的编辑环境?
  • ¥15 怎么用C++程序实现因式分解多项式
  • ¥15 dify知识库创建问题
  • ¥15 如何用C#的chart画1000万个点不卡顿
  • ¥15 爬虫技术找到网上看过房源客户的电话
  • ¥20 代码:Python随机森林反演生物量数据处理问题
  • ¥15 Linux系统的命令行窗口回车变成了换行,无法执行命令了
  • ¥15 vb6.0调用ImageMagick进行图片转换问题
  • ¥15 安卓组件化工程引入Arouter报错there's no route matched path[/login/LoginActivity,如何解决?