数据库分库分表(上)

news2024/10/5 14:26:40

数据库分库分表

1,概念

  • 分库分表是一种数据库架构设计的方法,用于解决大规模数据存储和查询的性能问题。它将一个大型数据库拆分成多个小型数据库,每个数据库负责存储一部分数据,从而提高数据的读写效率和并发处理能力。

  • 分库分表的优势在于可以将数据分散存储在多个物理节点上,减轻单个数据库的负载压力,提高系统的可扩展性和稳定性。同时,通过将数据按照一定规则进行分片,可以实现数据的并行处理,提高查询的响应速度。

  • 分库分表技术被广泛应用于互联网行业,特别是大型的电商、社交网络和金融等领域。它不仅能够提升系统的性能,还能够降低成本和维护的复杂性。

ShardingSphere开源的分布式数据库中间件,,可以实现数据库的分库分表功能。它提供了一套完整的分库分表解决方案,可以将一个大型的数据库拆分成多个小型的数据库,从而提高数据库的性能和扩展性。

2、SpringBoot+ShardingSphere案例

官方文档:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/quick-start/sharding-jdbc-quick-start/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gaUhIehO-1688008136229)(E:\Java笔记\数据库\MySQL分库分表\分库分表\Sql分库分表.assets\image-20230629093700613.png)]

2.1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/2.0.0 https://maven.apache.org/xsd/maven-2.0.0.xsd">
    <modelVersion>2.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itsoku</groupId>
    <artifactId>sj-demo1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sj-demo1</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-core</artifactId>
            <version>2.1.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.2、单库多表

单库多表是一种数据库设计和管理的方法,数据库中创建多个表来存储不同类型的数据。这种方法可以提高数据库的性能和扩展性,减少单个表的数据量和查询负载。

create table if not exists order_table_0(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;
create table if not exists order_table_1(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;

java代码

package com.sin.sharding;

import com.zaxxer.hikari.HikariDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.underlying.common.config.properties.ConfigurationPropertyKey;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @CreateName SIN
 * @CreateDate 2023/06/29 9:47
 * @description
 */
public class DemoSharding {

    public static void main(String[] args)throws Exception {
        /**
         * 1、配置真实数据源
         */
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        dataSourceMap.put("demo1", dataSource1());

        /**
         * 2.配置表的规则
         */
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("order_table", "demo1.order_table_$->{0..1}");
        // 指定表的分片策略(分片字段+分片算法)
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "order_table_$->{order_id % 2}"));

        /**
         * 3、分片规则
         */
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        //将表的分片规则加入到分片规则列表
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        /**
         * 4、配置一些属性
         */
        Properties props = new Properties();
        //输出sql
        props.put(ConfigurationPropertyKey.SQL_SHOW.getKey(), true);

        /**
         * 5、创建数据源
         */
        DataSource dataSource = ShardingDataSourceFactory.
                createDataSource(dataSourceMap, shardingRuleConfig, props);

        /**
         * 6、获取连接,执行sql
         */
        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);

        /**
         * 测试向t_order表插入8条数据,8条数据会分散到2个表
         */
        PreparedStatement ps = connection.prepareStatement("insert into order_table (order_id,user_id,price) values (?,?,?)");
        for (long i = 1; i <= 8; i++) {
            int j = 1;
            ps.setLong(j++, i);
            ps.setLong(j++, i);
            ps.setDouble(j, 100 * i);
            System.out.println(ps.executeUpdate());
        }

        connection.commit();
        ps.close();
        connection.close();
    }


    private static DataSource dataSource1() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }

}


运行输出

tables:
  order_table:
    actualDataNodes: demo1.order_table_$->{0..1}
    logicTable: order_table
    tableStrategy:
      inline:
        algorithmExpression: order_table_$->{order_id % 2}
        shardingColumn: order_id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3PdnOd0-1688008136230)(E:\Java笔记\数据库\MySQL分库分表\分库分表\Sql分库分表.assets\image-20230629101830898.png)]

两张表中的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mb6ZvjJH-1688008136230)(E:\Java笔记\数据库\MySQL分库分表\分库分表\Sql分库分表.assets\image-20230629101152987.png)]

2.3、多库多表

多库多表是指在数据库设计中,使用多个数据库和多个数据表来存储和管理数据。这种设计可以提高数据库的性能和可扩展性,同时也可以更好地组织和管理数据。

create database demo_sharding0;
use demo_sharding0;
create table if not exists order_table_0(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;
create table if not exists order_table_1(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;
create database demo_sharding1;
use demo_sharding1;
create table if not exists order_table_0(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;
create table if not exists order_table_1(
    order_id int not null primary key comment '订单id',
    user_id int not null comment '用户id',
    price double  not null comment '价格'
)charset utf8;

代码

package com.sin.sharding;

import com.zaxxer.hikari.HikariDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.underlying.common.config.properties.ConfigurationPropertyKey;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @CreateName SIN
 * @CreateDate 2023/06/29 10:27
 * @description
 */
public class DemoSharding1 {
    public static void main(String[] args) throws SQLException {
        // 配置真实数据源
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        dataSourceMap.put("demo0", dataSource1());
        dataSourceMap.put("demo1", dataSource2());

        /**
         * 2.配置表的规则
         */
        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("order_table", "demo$->{0..1}.order_table_$->{0..1}");
        // 指定db的分片策略(分片字段+分片算法)
        orderTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "demo$->{user_id % 2}"));
        // 指定表的分片策略(分片字段+分片算法)
        orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "order_table_$->{order_id % 2}"));

        /**
         * 3、分片规则
         */
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        //将表的分片规则加入到分片规则列表
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

        /**
         * 4、配置一些属性
         */
        Properties props = new Properties();
        //输出sql
        props.put(ConfigurationPropertyKey.SQL_SHOW.getKey(), true);

        /**
         * 5、创建数据源
         */
        DataSource dataSource = ShardingDataSourceFactory.
                createDataSource(dataSourceMap, shardingRuleConfig, props);

        /**
         * 6、获取连接,执行sql
         */
        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        PreparedStatement ps = connection.prepareStatement("insert into order_table (order_id,user_id,price) values (?,?,?)");
        // 插入4条数据测试,每个表会落入1条数据
        for (long user_id = 1; user_id <= 2; user_id++) {
            for (long order_id = 1; order_id <= 2; order_id++) {
                int j = 1;
                ps.setLong(j++, order_id);
                ps.setLong(j++, user_id);
                ps.setLong(j, 100);
                System.out.println(ps.executeUpdate());
            }
        }

        connection.commit();
        ps.close();
        connection.close();
    }


    private static DataSource dataSource1() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo_sharding0?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }

    private static DataSource dataSource2() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo_sharding1?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }
}

运行输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8BkFExax-1688008136231)(E:\Java笔记\数据库\MySQL分库分表\分库分表\Sql分库分表.assets\image-20230629103847098.png)]

表数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BrjCxiyM-1688008136231)(E:\Java笔记\数据库\MySQL分库分表\分库分表\Sql分库分表.assets\image-20230629103722863.png)]

2.4、单库无分表规则

单库无分表规则是指在数据库设计中,将所有数据存储在一个数据库中,而不进行分表操作。这种规则在某些情况下可能是合理的,但在大多数情况下,分表是更好的选择。

分表可以将数据分散存储在多个表中,每个表只包含一部分数据,这样可以提高查询性能和数据管理的效率。当数据量较大时,单库无分表规则可能导致数据库性能下降,查询速度变慢,对数据库的维护和管理也会变得更加困难。

此外,分表还可以根据数据的特点进行优化,例如按照时间、地域等进行分表,以便更好地满足业务需求。而单库无分表规则则无法灵活应对不同的数据特点和查询需求。

单库无分表规则可能在某些特定场景下适用,但在大多数情况下,分表是更好的选择,可以提高数据库性能和管理效率。

若表未指定分片规则,则直接路由到对应的表。

use demo;
create table if not exists order_user(
    id int not null primary key auto_increment comment 'id',
    name varchar(20)character set utf8 not null comment '姓名'
)charset utf8;

代码

package com.sin.sharding;

import com.zaxxer.hikari.HikariDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.underlying.common.config.properties.ConfigurationPropertyKey;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @CreateName SIN
 * @CreateDate 2023/06/29 10:43
 * @description
 */
public class DemoSharding3 {
    public static void main(String[] args) throws SQLException {
        /**
         * 1.配置真实数据源
         */
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        dataSourceMap.put("demo", dataSource1());

        /**
         * 2、无分片规则
         */

        /**
         * 3、分片规则
         */
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();

        /**
         * 4、配置一些属性
         */
        Properties props = new Properties();
        //输出sql
        props.put(ConfigurationPropertyKey.SQL_SHOW.getKey(), true);

        /**
         * 5、创建数据源
         */
        DataSource dataSource = ShardingDataSourceFactory.
                createDataSource(dataSourceMap, shardingRuleConfig, props);

        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);

        PreparedStatement ps = connection.prepareStatement("insert into order_user (name) values (?)");
        ps.setString(1, "张三");
        System.out.println(ps.executeUpdate());

        connection.commit();
        ps.close();
        connection.close();
    }


    private static DataSource dataSource1() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }


}

运行输出

Logic SQL: insert into order_user (name) values (?)
Actual SQL: demo ::: insert into t_user (name) values (?) ::: [张三]

在这里插入图片描述

2.5、多库无分表规则

多库无分表规则指的是将数据分散存储在多个数据库中,而不是将数据分散存储在同一个数据库的多个表中。这种方式可以用于解决单个数据库的性能瓶颈问题,提高系统的扩展性和并发性。

use demo_sharding0;
create table if not exists order_user(
    id int not null primary key auto_increment comment 'id',
    name varchar(20)character set utf8 not null comment '姓名'
)charset utf8;
use demo_sharding1;
create table if not exists order_user(
    id int not null primary key auto_increment comment 'id',
    name varchar(20)character set utf8 not null comment '姓名'
)charset utf8;

java代码

下面配置2个数据源,向t_user表插入数据,看看数据会落在哪个库?

package com.sin.sharding;

import com.zaxxer.hikari.HikariDataSource;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.underlying.common.config.properties.ConfigurationPropertyKey;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @CreateName SIN
 * @CreateDate 2023/06/29 10:49
 * @description
 */
public class DemoSharding4 {
    public static void main(String[] args) throws SQLException {
        /**
         * 1.配置2个数据源
         */
        Map<String, DataSource> dataSourceMap = new LinkedHashMap<>();
        dataSourceMap.put("demo0", dataSource1());
        dataSourceMap.put("demo1", dataSource2());

        /**
         * 2、无分片规则
         */

        /**
         * 3、分片规则
         */
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();

        /**
         * 4、配置一些属性
         */
        Properties props = new Properties();
        //输出sql
        props.put(ConfigurationPropertyKey.SQL_SHOW.getKey(), true);

        /**
         * 5、创建数据源
         */
        DataSource dataSource = ShardingDataSourceFactory.
                createDataSource(dataSourceMap, shardingRuleConfig, props);

        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);

        //插入4条数据,测试效果
        for (int i = 0; i < 4; i++) {
            PreparedStatement ps = connection.prepareStatement("insert into order_user (name) values (?)");
            ps.setString(1, "张三");
            System.out.println(ps.executeUpdate());
        }

        connection.commit();
        connection.close();
    }


    private static DataSource dataSource1() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo_sharding0?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }

    private static DataSource dataSource2() {
        HikariDataSource dataSource1 = new HikariDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setJdbcUrl("jdbc:mysql://localhost:3306/demo_sharding1?characterEncoding=UTF-8");
        dataSource1.setUsername("root");
        dataSource1.setPassword("123456");
        return dataSource1;
    }
}

运行输出

输出如下,落入的库是不确定的。

Logic SQL: insert into order_user (name) values (?)
Actual SQL: demo0 ::: insert into t_user (name) values (?) ::: [张三]
1
Logic SQL: insert into order_user (name) values (?)
Actual SQL: demo1 ::: insert into t_user (name) values (?) ::: [张三]
1
Logic SQL: insert into order_user (name) values (?)
Actual SQL: demo1 ::: insert into t_user (name) values (?) ::: [张三]
1
Logic SQL: insert into order_user (name) values (?)
Actual SQL: demo0 ::: insert into t_user (name) values (?) ::: [张三]
1

3、分片

3.1、分片键

数据库中的分片键是用于将数据分散存储在不同的分片(shard)中的一种标识。分片键可以是一个或多个字段,用于确定数据在哪个分片中存储。通过将数据分散存储在多个分片中,可以提高数据库的扩展性和性能。

分片键的选择非常重要,它应该能够将数据均匀地分布在各个分片中,避免出现热点数据集中在某个分片的情况。同时,分片键还应该能够满足查询需求,使得常用的查询操作可以在单个分片上执行,减少跨分片查询的开销。

在选择分片键时,需要考虑数据的访问模式、数据分布的均匀性、数据的增长趋势等因素。一般来说,常见的选择分片键的策略包括基于时间戳、基于地理位置、基于用户ID等。

注意:选择分片键是一个复杂的问题,需要根据具体的应用场景和需求进行权衡和选择。不同的数据库系统可能有不同的分片策略和支持的分片键类型。

3.2、分片算法

MySQL分片算法是指将一个数据库分散存储在多个节点上的方法。常见的分片算法有以下几种:

  • 哈希分片算法:
    • 根据数据的哈希值将数据分散存储在不同的节点上。这种算法可以保证数据的均匀分布,但是在需要进行范围查询或排序时可能会有性能问题。
  • 范围分片算法:
    • 根据数据的某个范围值将数据分散存储在不同的节点上。这种算法适合于需要进行范围查询或排序的场景,但是可能会导致数据不均匀分布的问题。
  • 列分片算法:
    • 根据数据的某个列值将数据分散存储在不同的节点上。这种算法适合于根据某个列进行查询的场景,但是可能会导致数据不均匀分布的问题。
  • 一致性哈希分片算法:
    • 将数据和节点都映射到一个环上,根据数据的哈希值在环上找到对应的节点。这种算法可以保证数据的均匀分布,并且在节点的增加或删除时能够最小化数据的迁移。

以上是一些常见的MySQL分片算法,具体选择哪种算法需要根据具体的业务需求和数据特点来决定。

3.3、5种分片策略

多种分片策略可供选择,以下是其中的五种常见策略:

  • 垂直分片(Vertical Sharding):
    • 将数据库按照不同的表或列进行分片。每个分片只包含特定的表或列,可以根据业务需求将不同的数据存储在不同的分片中。
  • 水平分片(Horizontal Sharding):
    • 将数据库按照数据行进行分片。每个分片包含相同的表结构,但存储不同的数据行。可以根据数据的某个特定属性(如用户ID、地理位置等)将数据行分散到不同的分片中。
  • 哈希分片(Hash Sharding):
    • 根据数据的哈希值将数据分散到不同的分片中。通过对数据的某个属性进行哈希运算,可以将数据均匀地分布到不同的分片中,实现负载均衡。
  • 范围分片(Range Sharding):
    • 根据数据的某个范围进行分片。可以根据数据的某个连续属性(如时间、价格等)将数据按照范围进行划分,将不同范围的数据存储在不同的分片中。
  • 列分片(Column Sharding):
    • 将数据库按照列进行分片。每个分片只包含特定的列,可以根据业务需求将不同的列存储在不同的分片中,提高查询效率。

这些分片策略可以根据具体的业务需求和数据特点进行选择和组合,以实现高性能、高可用性和可扩展性的数据库架构。

3.4、总结

  • 分片策略是指将一个大的任务或数据分割成多个小的部分进行处理或存储的策略。这种策略可以提高任务的并行性和效率,减少单个节点的负载压力。

  • 在计算机领域,分片策略常用于分布式系统中的数据存储和处理。例如,将一个大型数据库分成多个分片,每个分片存储在不同的服务器上,可以提高数据库的读写性能和可扩展性。同时,分片还可以增加系统的容错性,当某个分片发生故障时,其他分片仍然可以正常工作。

  • 在任务处理中,分片策略可以将一个大的任务分成多个小的子任务,每个子任务由不同的处理节点执行。这样可以提高任务的并行处理能力,加快任务的完成速度。同时,分片策略也可以增加系统的容错性,当某个节点发生故障时,其他节点仍然可以继续处理剩余的子任务。

分片策略是一种有效的分解和管理大型任务或数据的方法,可以提高系统的性能、可扩展性和容错性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/699177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL数据库基础 17

第十七章 触发器 1. 触发器概述2. 触发器的创建2.1 创建触发器语法2.2 代码举例 3. 查看、删除触发器3.1 查看触发器3.2 删除触发器 4. 触发器的优缺点4.1 优点4.2 缺点4.3 注意点 在实际开发中&#xff0c;我们经常会遇到这样的情况&#xff1a;有 2 个或者多个相互关联的表&a…

虚幻引擎(UE5)-大世界分区WorldPartition教程(三)

文章目录 前言LevelInstance的使用1.ALevelInstance2.选择Actor创建关卡3.运行时加载LevelInstance 总结 上一篇&#xff1a;虚幻引擎(UE5)-大世界分区WorldPartition教程(二) 前言 在制作大关卡时&#xff0c;可能会遇到这样一种情况&#xff0c;就是关卡中的某些Actor会重复…

【每日一题】——Majority

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

A*算法学习笔记

1 算法思路 1、Dijkstra算法与A*算法 &#xff08;1&#xff09;Dijkstra算法&#xff08;贪心策略 优先队列&#xff09;&#xff1a; 集合S&#xff1a;已确定的顶点集合&#xff0c;初始只含源点s。 集合T&#xff1a;尚未确定的顶点集合。 算法反复从集合T中选择当前到…

开闭架构

在《不过时的经典层架构》里&#xff0c;有朋友留言关于Manager和Engine的概念&#xff0c;虽然朋友留言把概念解释清楚了。为了避免其他人有同样的疑问&#xff0c;这里我还是再解释一下。 以上是经典的四层架构&#xff0c;在这个架构中&#xff0c;Manager和Engine(引擎)都是…

【liunx配置服务自启动】liunx系统设置net Core程序开机自启动服务 centos系统

liunx系统设置net Core程序开机自启动服务 系统版本&#xff1a;Centos7.9 我的程序部署到/www/wwwroot/AcmeBookStoreHttpApiHost.com/目录下&#xff0c; 程序名是Meowv.Blog.HttpApi.Hosting.dll 1.新建自启动配置文件 首先跳转到system目录下 cd /usr/lib/systemd/syste…

【.net core】yisha框架,实体不在同一项目下设置swagger接口及实体模型注释,授权鉴权

1.Startup.cs中ConfigureServices方法中添加&#xff1a; 授权鉴权内容 #region 授权鉴权//Bearer 的scheme定义var securityScheme new OpenApiSecurityScheme(){Description "使用JWT方案授权&#xff0c;请求时&#xff0c;在请求头部信息中加入: \"Authoriza…

分布式计算模型详解:MapReduce、数据流、P2P、RPC、Agent

前言 本文隶属于专栏《大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据理论体系 思维导图 MapReduce MapReduce 是一种分布式计算模…

Tomcat与Undertow容器性能对比分析

&#x1f468;‍&#x1f393;作者&#xff1a;bug菌 ✏️博客&#xff1a; CSDN、 掘金、 infoQ、 51CTO等 &#x1f389;简介&#xff1a;CSDN博客专家&#xff0c;C站历届博客之星Top50&#xff0c;掘金/InfoQ/51CTO等社区优质创作者&#xff0c;全网合计8w粉&#xff0c;对…

BufferedImage将图片切成圆形

原图 修改后 方法一 //文件路径 File imageFile new File(path); public BufferedImage changeImages(File imageFile) {BufferedImage avatarImage null;try {avatarImage ImageIO.read(imageFile); avatarImage scaleByPercentage(avatarImage, avatarImage.getWidth(…

LENOVO联想笔记本电脑ThinkBook 15 G2-ITL(20VE)原装出厂Windows10系统恢复原厂OEM设置预装系统

Lenovo联想笔记本电脑&#xff0c;ThinkBook 15 G2-ITL(20VE)出厂Windows10系统&#xff0c;出厂预装系统 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xf…

最优化--凸函数--拉格朗日乘子法

目录 凸函数 凸函数定义 凸函数的判定 性质特点 拉格朗日乘子法 基本思想 有约束最优化问题 拉格朗日乘子法 凸函数 凸函数&#xff08;Convex Function&#xff09;是定义在凸集上的实值函数&#xff0c;具有以下性质&#xff1a;对于任意两个定义域内的点&#xf…

Windows11系统启动VMware Workstation 在此主机上不支持嵌套虚拟化导致无法启动虚拟机

问题复现&#xff1a; VMware Workstation中的虚拟机时启动失败&#xff0c;弹出错误弹窗&#xff1a; VMware Workstation 在此主机上不支持嵌套虚拟化。 模块“MonitorMode”启动失败。 未能启动虚拟机。 问题原因&#xff1a; 不要同时开启hyper-V和VMware虚拟机软件&…

(小程序)指定问题换一批功能实现

(小程序)指定问题换一批功能实现 vue3写法 html <view class"title"><p>推荐问题</p><view class"refresh" click"onRefresh"><text>换一批</text><image src"https://cdn.tudb.work/aios/web/im…

MongoDB的数据类型

BSON JSON作为一种轻量级的数据交换格式&#xff0c;JSON的可读性非常好&#xff0c;而且非常便于系统生成和解析&#xff0c;这些优势也让它逐渐取代了XML标准在Web领域的地位&#xff0c;当今许多流行的Web应用开发框架&#xff0c;如SpringBoot都选择了JSON作为默认的数据编…

007+limou+C语言基础排序算法(上)

0.前言 您好这里是limou3434的一篇博文&#xff0c;感兴趣可以看看我的其他内容。 排序算法简单理解就是&#xff1a;一串数组经过排序算法后得到有序的数组。排序算法在不同应用场景有不同的效果&#xff0c;因此我们有必要了解一些基础的排序算法。 而本次我给您带来的是一…

vue+leaflet实现聚合图(根据半径划分)

效果 官方示例 github地址 1. 安装leaflet.markercluster插件 npm install leaflet.markercluster -S** 2. 在项目中引入leaflet.markercluster和样式文件 ** import leaflet.markercluster/dist/MarkerCluster.css import leaflet.markercluster/dist/MarkerCluster.Def…

SqlServer定时执行存储过程

1.连接数据库后选择【SQL Server 代理】—【作业】——右键【新建作业】&#xff0c;具体操作如下图&#xff1a; 2.【新建作业】步骤如下图所示&#xff1a; 3.新建【步骤】&#xff0c;具体如下图所示&#xff1a; 4.新建【计划】&#xff0c;具体如下图所示&#xff1a; 6.配…

Ubuntu 20.04 下g++用不了,但是提示已经安装

问题描述 用sudo apt-get install g来安装&#xff0c;系统却又说g已经是最新版本了&#xff0c;但是用g -v查看又提示需要安装 g&#xff0c;如图片所示。 解决方法 未安装g&#xff0c;安装依赖只需运行命令行&#xff1a; sudo apt-get install build-essential仍然无法成…

docker部署redis

一、拉取镜像 docker search redis 我部署的是redis6.0&#xff0c;使用docker pull 拉取镜像 docker pull redis:6.0 拉取成功后使用docker image查看镜像 docker images | grep redis 二、创建挂载目录 在 /opt 目录下创建redis的 conf 和 data 目录 sudo mkdir /opt/re…