[shardingsphere]分表分库概念及实战

产品简介

什么是分布式数据库

分布式数据库系统通常使用较小的计算机系统,每台计算机可单独放在一个地方,每台计算机中都可能有DBMS(Database Management System)的一份完整拷贝副本,或者部分拷贝副本,并具有自己局部的数据库,位于不同地点的许多计算机通过网络互相连接,共同组成一个完整的、全局的逻辑上集中、物理上分布的大型数据库。

为什么要做分布式数据存储

传统的将数据集中存储至单一数据节点的解决方案,在性能可用性运维成本这三方面已经难于满足互联网的海量数据场景。
性能方面,由于关系型数据库大多采用B+树模型,导致数据量超过阈值的情况下,索引深度的增加导致磁盘IO访问次数增加,导致查询性能下降;同时高并发的访问请求也使得集中式数据库成为系统最大的瓶颈。
可用性方面,服务化的无状态能达到较小成本的随意扩容,但是导致所有压力都落在数据库,单一架构甚至简单的主从模式已经无力支撑。
运维成本方面考虑,当数据库达到单一数据库的阈值,对于DBA的运维压力就会增大,数据备份时间、恢复时间都会随着数据量增大变大,单一数据库应把数据量控制在1TB范围内。

什么是ShardingSphere

shardingsphere定位为关系型数据库中间件透明化的数据库代理端,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。
目前提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据。

产品架构

在这里插入图片描述

名词解释

SQL

逻辑表

水平拆分的数据库表的相同逻辑和数据结构表的总称。
例如:
医院信息表被拆分为biz_yy_info_0 ... biz_yy_info_9,他们对应的逻辑表为biz_yy_info

真实表

在分片数据库中真实存在的物理表。例如逻辑表中介绍的biz_yy_info_0...biz_yy_info_9

数据节点

数据源名称和数据表组成的数据分片最小单元。例如ds_0.biz_yy_info_0

绑定表

指分片规则相同的主表和子表。例如两张表,tbordertbperson,都按照同一个字段——person_id分片,因此这两张表互为绑定表。两张绑定表在关联时不会出现笛卡尔积,关联效率较高。

广播表

指所有分片数据源中都存在的表,表结构、数据在每个节点都完全一致。适用于数据量不大,需要与海量数据的表关联的场景。

分片

分片键

用于分片的数据库字段,用于将数据水平拆分的关键字段。sharding-sphere支持多个字段分片键。

分片算法(四种)

通过分片算法将数据分片,支持通过=>=<=><BETWEENIN分片。
注意:分片算法需要自行实现。
例如,下图是我实现的一个分片算法。
在这里插入图片描述
在这里插入图片描述

  • 精确分片算法
    对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=IN进行分片的场景。需要配合StandardShardingStrategy使用。

  • 范围分片算法
    对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND><>=<=进行分片的场景。需要配合StandardShardingStrategy使用。

  • 复合分片算法
    对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。

  • Hint分片算法
    对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。

分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。

  • 标准分片策略
    对应StandardShardingStrategy。提供对SQL语句中的=,>, <, >=, <=, INBETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithmRangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >,<, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
  • 复合分片策略
    对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >,<, >=, <=, INBETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
  • 行表达式分片策略
    对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。
  • Hint分片策略
    对应HintShardingStrategy。通过Hint而非SQL解析的方式分片的策略。
  • 不分片策略
    对应NoneShardingStrategy。不分片的策略。
SQL Hint

对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint支持通过Java APISQL注释(待实现)两种方式使用。

配置

分片规则

分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。
在这里插入图片描述

数据源配置

真实数据源列表。
在这里插入图片描述

表配置

逻辑表名称、数据节点与分表规则的配置。

数据节点配置

用于配置逻辑表与真实表的映射关系。可分为均匀分布自定义分布两种形式。

  • 均匀分布
    指数据表在每个数据源内呈现均匀分布的态势,例如:
db0
  ├── t_order0 
  └── t_order1 
db1
  ├── t_order0 
  └── t_order1

那么数据节点的配置如下:

db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
  • 自定义分布
    指数据表呈现有特定规则的分布,例如:
db0
  ├── t_order0 
  └── t_order1 
db1
  ├── t_order2
  ├── t_order3
  └── t_order4

那么数据节点的配置如下:

db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4
分片策略配置

对于分片策略存有数据源分片策略和表分片策略两种维度。

  • 数据源分片策略
    对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。

  • 表分片策略
    对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。

两种策略的API完全相同。

自增主键生成策略

通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。内置的分布式主键实现有UUIDSNOWFLAKE以及LEAF

编排治理

配置中心

集中实时的管理shardingsphere中的配置信息,默认支持zookeeper,其他可通过实现SPI接口实现。

数据脱敏

对敏感隐私数据信息的可靠保护手段。

读写分离

主库

添加、更新以及删除操作所使用的数据库,目前仅支持单主库。

从库

查询数据操作所使用的数据库,可支持多从库。

主从同步

主库通过mysql/postgresql的同步配置,将数据异步的同步到从库上面的操作(由于异步性可能导致主从库技间的短暂不一致性)。

负载均衡策略

通过负载均衡策略将查询疏导到不同的从库

事务类型

本地事务

事务是解决数据并发操作处理的模型 ,旨在满足多用户(多线程、进程)对数据操作的场景下,依然能保证逻辑正确执行,状态持久。
本地事务是相对于分布式事务的一个概念。本地事务满足A(Atomictiy)C(Consistency)I(Isolation)D(Durabilit)四个特性。

两阶段事务(XA)

两阶段事务提交采用的是X/OPEN组织所定义的DTP模型,通过抽象出来的AP(应用程序), TM(事务管理器), RM(资源管理器,通常是数据库)的概念可以保证事务的强一致性。 其中TM和RM间采用XA的协议进行双向通信。 与传统的本地事务相比,XA事务增加了prepare阶段,数据库除了被动接受提交指令外,还可以反向通知调用方事务是否可以被提交。 因此TM可以收集所有分支事务的prepare结果,最后进行原子的提交,保证事务的强一致性。

柔性事务

互联网场景下诞生,满足基本可用(Basically Available)柔性状态(Soft State)最终一致性(Eventual Consistency)的分布式事务类型。

产品优势

  • 上手容易,配置简单

  • 提供封装了数据库二进制协议的服务端版本,可以使用任何兼容MySQL/PostgreSQL协议的访问客户端操作数据

  • 对于开发者无需在意后端的实现,仅需要将其作为单个数据库看待

  • 提供丰富的SPI接口,可以在其上开发兼容属于自己的注册中心、SQL监控等

  • 提供分表分库算法接口,使用者可以设计满足自己的业务场景的分表分库算法

快速上手

1. 规则配置

编辑%shardingsphere%\conf\config-xxx.yaml。详情请参见配置说明。

编辑%shardingsphere%\conf\server.yaml。详情请参见配置说明。

2. 启动服务

使用默认配置项

${shardingsphere}\bin\start.sh

配置端口

${shardingsphere}\bin\start.sh ${port}

操作指南

1.配置说明

shardingsphere主目录下的conf目录中有如下几个配置文件:

[root@node15 conf]# ll
总用量 24
-rw-r--r-- 1 app app 3019 7月  30 2019 config-encrypt.yaml
-rw-r--r-- 1 app app 3582 4月  22 2019 config-master_slave.yaml
-rw-r--r-- 1 app app 6572 2月  18 18:04 config-sharding.yaml
-rw-r--r-- 1 app app 1322 4月  22 2019 logback.xml
-rw-r--r-- 1 app app 1888 2月   4 13:57 server.yaml

从上至下分别是:

config-encrypt.yaml (数据脱敏配置)
config-master_slave.yaml (读写分离配置)
config-sharding.yaml (数据分片配置)
logback.xml (日志输出配置)
server.yaml (全局信息配置)

这里抛去日志输出配置暂且不表(spring默认集成logback,配置比较简单),以下按照常用程度和重要性排序,对shardingsphere主要的配置进行说明。

server.yaml

用于配置注册中心、认证信息以及公用属性。

治理
orchestration:
  name: orchestration_ds #治理实例名称
  overwrite: true #是否覆盖本地配置
  registry: #注册中心配置
    type: zookeeper #配置中心类型
    serverLists: localhost:2181 #连接注册中心的服务器列表,多个地址逗号分隔
    namespace: orchestration #注册中心的命名空间
    digest: #连接注册中心的权限令牌
    operationTimeoutMilliseconds: 500 #操作超时的毫秒数,默认500毫秒
    maxRetries: 3 #连接失败后的最大重试次数,默认3次
    retryIntervalMilliseconds: 500 #重试间隔毫秒数,默认500毫秒
    timeToLiveSeconds: 60 #临时节点存活秒数,默认60秒
认证信息
authentication:
  users:
    root: #自定义用户名
      password: root #用户密码
    sharding: #自定义用户名
      password: sharding #用户密码
      authorizedSchemas: sharding_db #该用户授权访问的数据库,逗号分隔,如果缺省将拥有root用户的权利,访问所有数据库
公共属性
props:
  max.connections.size.per.query: 1 #每个查询的最大连接数
  acceptor.size: 16  #用于设置接收客户端请求的工作线程个数,默认为CPU核数*2
  executor.size: 16  #工作线程数量
  proxy.frontend.flush.threshold: 128  # 对于单个大查询,每多少个网络包返回一次
    # LOCAL: 代理使用本地事务
    # XA: 代理使用XA事务.
    # BASE: Proxy will run with B.A.S.E transaction.
  proxy.transaction.type: LOCAL #默认为LOCAL事务,允许LOCAL,XA,BASE三个值,XA采用Atomikos作为事务管理器,BASE类型需要拷贝实现ShardingTransactionManager的接口的jar包至lib目录中
  proxy.opentracing.enabled: false #是否开启链路追踪功能,默认为不开启。
  query.with.cipher.column: true #是否使用密文列查询
  sql.show: false #是否开启SQL显示
config-sharding.yaml

这个配置文件是使用的最多的配置文件,里面定义实际的数据源、分片规则等。

dataSources: #数据源配置,可配置多个data_source_name
  <data_source_name>: #<!!数据库连接池实现类> `!!`表示实例化该类
    driverClassName: #数据库驱动类名
    url: #数据库url连接
    username: #数据库用户名
    password: #数据库密码
    # ... 数据库连接池的其它属性

shardingRule:
  tables: #数据分片规则配置,可配置多个logic_table_name
    <logic_table_name>: #逻辑表名称
      actualDataNodes: #由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点。用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况
        
      databaseStrategy: #分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一
        standard: #用于单分片键的标准分片场景
          shardingColumn: #分片列名称
          preciseAlgorithmClassName: #精确分片算法类名称,用于=和IN。。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
          rangeAlgorithmClassName: #范围分片算法类名称,用于BETWEEN,可选。。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
        complex: #用于多分片键的复合分片场景
          shardingColumns: #分片列名称,多个列以逗号分隔
          algorithmClassName: #复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器
        inline: #行表达式分片策略
          shardingColumn: #分片列名称
          algorithmInlineExpression: #分片算法行表达式,需符合groovy语法
        hint: #Hint分片策略
          algorithmClassName: #Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器
        none: #不分片
      tableStrategy: #分表策略,同分库策略
      keyGenerator: 
        column: #自增列名称,缺省表示不使用自增主键生成器
        type: #自增列值生成器类型,缺省表示使用默认自增列值生成器。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID/LEAF_SEGMENT
        props: #属性配置, 注意:使用SNOWFLAKE算法,需要配置worker.id与max.tolerate.time.difference.milliseconds属性。若使用此算法生成值作分片值,建议配置max.vibration.offset属性
          <property-name>: 属性名称
      
  bindingTables: #绑定表规则列表
  - <logic_table_name1, logic_table_name2, ...> 
  - <logic_table_name3, logic_table_name4, ...>
  - <logic_table_name_x, logic_table_name_y, ...>
  broadcastTables: #广播表规则列表
  - table_name1
  - table_name2
  - table_name_x
  
  defaultDataSourceName: #未配置分片规则的表将通过默认数据源定位  
  defaultDatabaseStrategy: #默认数据库分片策略,同分库策略
  defaultTableStrategy: #默认表分片策略,同分库策略
  defaultKeyGenerator: #默认的主键生成算法 如果没有设置,默认为SNOWFLAKE算法
    type: #默认自增列值生成器类型,缺省将使用org.apache.shardingsphere.core.keygen.generator.impl.SnowflakeKeyGenerator。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID/LEAF_SEGMENT
    props:
      <property-name>: #自增列值生成器属性配置, 比如SNOWFLAKE算法的worker.id与max.tolerate.time.difference.milliseconds

  masterSlaveRules: #读写分离规则,详见读写分离部分
    <data_source_name>: #数据源名称,需要与真实数据源匹配,可配置多个data_source_name
      masterDataSourceName: #详见读写分离部分
      slaveDataSourceNames: #详见读写分离部分
      loadBalanceAlgorithmType: #详见读写分离部分
      props: #读写分离负载算法的属性配置
        <property-name>: #属性值
      
props: #属性配置
  sql.show: #是否开启SQL显示,默认值: false
  executor.size: #工作线程数量,默认值: CPU核数
  max.connections.size.per.query: # 每个查询可以打开的最大连接数量,默认为1
  check.table.metadata.enabled: #是否在启动时检查分表元数据一致性,默认值: false
config-master_slave.yaml

这个配置文件主要是读写分离的配置文件。

schemaName: master_slave_db #逻辑库名

dataSources:#定义数据源
  master_ds:#数据源名称,这里最好以名字区分主和从
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_master?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_0:#同上
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_slave_0?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_1:#同上
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_slave_1?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50

masterSlaveRule:#主从之间的绑定规则
  name: ms_ds #规则名称
  masterDataSourceName: master_ds #指定主数据源名称
  slaveDataSourceNames: #指定主对应的从数据源
    - slave_ds_0
    - slave_ds_1
config-encrypt.yaml

数据脱敏配置。

dataSource: #省略数据源配置

encryptRule:
  encryptors:
    <encryptor-name>:
      type: #加解密器类型,可自定义或选择内置类型:MD5/AES 
      props: #属性配置, 注意:使用AES加密器,需要配置AES加密器的KEY属性:aes.key.value
        aes.key.value: 
  tables:
    <table-name>:
      columns:
        <logic-column-name>:
          plainColumn: #存储明文的字段
          cipherColumn: #存储密文的字段
          assistedQueryColumn: #辅助查询字段,针对ShardingQueryAssistedEncryptor类型的加解密器进行辅助查询
          encryptor: #加密器名字
props:
  query.with.cipher.column: true #是否使用密文列查询
复杂配置范例

该范例集合了分表分库及读写分离,是比较有说服性的较为复杂的例子,对于实战使用有一定的借鉴意义:

schemaName: sharding_db

dataSources:
  ds_0:
    url: jdbc:mysql://192.168.133.15:3306/demo_1?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_0_slave:
    url: jdbc:mysql://192.168.133.15:3306/demo_1_slave?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1:
    url: jdbc:mysql://192.168.133.15:3306/demo_2?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1_slave:
    url: jdbc:mysql://192.168.133.15:3306/demo_2_slave?serverTimezone=UTC&useSSL=false
    username: pcloud
    password: pcloud
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
shardingRule:
  tables:
    tborder:
      actualDataNodes: ms_ds${0..1}.tborder
      databaseStrategy:
        standard:
          shardingColumn: personId
          preciseAlgorithmClassName: org.apache.shardingsphere.api.sharding.impl.HashShardingAlgorithm
    tbperson:
      actualDataNodes: ms_ds${0..1}.tbperson
      databaseStrategy:
        standard:
          shardingColumn: personId
          preciseAlgorithmClassName: org.apache.shardingsphere.api.sharding.impl.HashShardingAlgorithm
      #tableStrategy:
        #complex:
          #shardingColumns: orderId,createTime
          #algorithmClassName: org.apache.shardingsphere.api.sharding.impl.ECComplexShardingAlgorithm
      #keyGenerator:
          #type: SNOWFLAKE
          #column: personId
  bindingTables:
    - tborder,tbperson
  defaultDatabaseStrategy:
    none:
  defaultTableStrategy:
    none:

  masterSlaveRules:
    ms_ds0:
      masterDataSourceName: ds_0
      slaveDataSourceNames:
        - ds_0_slave
      loadBalanceAlgorithmType: ROUND_ROBIN
    ms_ds1:
      masterDataSourceName: ds_1
      slaveDataSourceNames:
        - ds_1_slave
      loadBalanceAlgorithmType: ROUND_ROBIN

2.实现自己的分表分库算法并应用到shardingsphere

上面名词介绍里面已经介绍,shardingsphere有四种分片算法,因此shardingsphere提供了4种类型的接口,在sharding-core-api模块下的org.apache.shardingsphere.api.sharding包内,类名为PreciseShardingAlgorithm(精准分片)、RangeShardingAlgorithm(范围分片)、HintShardingAlgorithm(Hint分片)、ComplexKeysShardingAlgorithm(复杂分片)。
以下举例说明,通过实现精准分片接口,算法对拆分键进行hash算法后路由到指定的节点,演示如何将自己的分片算法集成到shardingsphere中并使用。

(1)首先,完成自己的分片算法

package org.apache.shardingsphere.api.sharding.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;
import java.util.Iterator;

/*
 * @author: YoungLu
 * @date: 2020/2/4 10:23
 * @description:
*/
@Slf4j
public class HashShardingAlgorithm implements PreciseShardingAlgorithm<String> {
    @Override
    public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<String> shardingValue) {
        String columnName = shardingValue.getColumnName();
        String tableName = shardingValue.getLogicTableName();
        String value = shardingValue.getValue();
        log.debug("column:{},tableName:{},value:{}", new Object[]{columnName, tableName, value});
        int shardingCount = availableTargetNames.size();
        log.debug("shardingCount:{}", shardingCount);
        int hashNum = this.hash(value, shardingCount);
        Iterator it = availableTargetNames.iterator();

        String targetName;
        do {
            if (!it.hasNext()) {
                throw new UnsupportedOperationException();
            }

            targetName = (String) it.next();
        } while (!targetName.endsWith(hashNum + ""));

        log.debug("recent return target is : {}", targetName);
        return targetName;
    }

    private int hash(final String text, final int shardsNum) {
        return Math.abs(text.hashCode() % shardsNum);
    }
}

(2)将分片算法打成jar包,jar包的目录结构需要根据你的类所在的包决定,例如上述的算法包名为:
package org.apache.shardingsphere.api.sharding.impl;则对应需要创建的目录结构为:
在这里插入图片描述
(3)将打包好的jar包放入服务器部署的%shardingsphere%\lib\目录下:
在这里插入图片描述

常见问题

1.除了支持自带的分布式自增主键之外,还能否支持原生的自增主键?

回答:是的,可以支持。但原生自增主键有使用限制,即不能将原生自增主键同时作为分片键使用。

由于shardingsphere并不知晓数据库的表结构,而原生自增主键是不包含在原始SQL中内的,因此shardingsphere无法将该字段解析为分片字段。如自增主键非分片键,则无需关注,可正常返回;若自增主键同时作为分片键使用,shardingsphere无法解析其分片值,导致SQL路由至多张表,从而影响应用的正确性。

而原生自增主键返回的前提条件是INSERT SQL必须最终路由至一张表,因此,面对返回多表的INSERT SQL,自增主键则会返回零。

2.Windows环境下,通过Git克隆shardingsphere源码时为什么提示文件名过长,如何解决?

回答:

为保证源码的可读性,shardingsphere编码规范要求类、方法和变量的命名要做到顾名思义,避免使用缩写,因此可能导致部分源码文件命名较长。由于Windows版本的Git是使用msys编译的,它使用了旧版本的Windows Api,限制文件名不能超过260个字符。

解决方案如下:

打开cmd.exe(你需要将git添加到环境变量中)并执行下面的命令:

git config --global core.longpaths true

3.如果SQL在ShardingSphere中执行不正确,该如何调试?

回答:

shardingsphere提供了sql.show的配置,可以将解析上下文和改写后的SQL以及最终路由至的数据源的细节信息全部打印至info日志。 sql.show配置默认关闭,如果需要请通过配置开启。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值