Mycat的简单使用(三)【分库分表】(1)

| mysql |

| performance_schema |

| sys |

±-------------------+

5 rows in set (0.00 sec)

MySQL [(none)]> exit

Bye

[root@mycat ~]#

配置mycat


分库规则:

  • dn1:department部门表、user用户表、register患者挂号表

  • dn2:drugs 药品表、disease 疾病表

修改mycat的schema.xml重新配置分库规则:

<?xml version="1.0"?>

<mycat:schema xmlns:mycat=“http://io.mycat/”>

<dataHost name=“host1” maxCon=“1000” minCon=“10” balance=“0”

writeType=“0” dbType=“mysql” dbDriver=“native” switchType=“1”

slaveThreshold=“100”>

select user()

<dataHost name=“host2” maxCon=“1000” minCon=“10” balance=“0”

writeType=“0” dbType=“mysql” dbDriver=“native” switchType=“1”

slaveThreshold=“100”>

select user()

</mycat:schema>

启动mycat


在mycat/bin目录中执行

./mycat console

登录mycat创建表结构

/dn1/

CREATE TABLE department (

id int(9) NOT NULL AUTO_INCREMENT COMMENT ‘id’,

DeptCode varchar(64) NOT NULL COMMENT ‘科室编码’,

DeptName varchar(64) NOT NULL COMMENT ‘科室名称’,

DeptCategory varchar(64) DEFAULT NULL COMMENT ‘科室分类’,

DeptTypeID int(9) NOT NULL COMMENT ‘科室类型’,

DelMark int(1) DEFAULT NULL COMMENT ‘删除标记’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE user (

id int(9) NOT NULL COMMENT ‘id’,

UserName varchar(64) NOT NULL COMMENT ‘登录名’,

Password varchar(64) DEFAULT NULL COMMENT ‘密码’,

RealName varchar(64) NOT NULL COMMENT ‘真实姓名’,

UserTypeID int(9) DEFAULT NULL COMMENT '1 - 挂号人员 2 - 门诊医生 3 - 医技医生 4 - 药房人员 5 - 财务人员 6 - 行政人员 ',

DocTitleID int(9) DEFAULT NULL COMMENT ‘医生职称’,

IsScheduling int(9) DEFAULT NULL COMMENT ‘是否排班’,

DeptId int(9) NOT NULL COMMENT ‘所在科室ID’,

RegistId int(9) DEFAULT NULL COMMENT ‘挂号级别ID’,

DelMark int(1) DEFAULT NULL COMMENT ‘删除标记’,

PRIMARY KEY (id),

KEY FK_科室id (DeptId),

CONSTRAINT FK_科室id FOREIGN KEY (DeptId) REFERENCES department (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE register (

id int(9) NOT NULL COMMENT ‘id’,

RealName varchar(64) DEFAULT NULL COMMENT ‘真实姓名’,

Gender int(9) DEFAULT NULL COMMENT ‘性别’,

IDnumber varchar(18) DEFAULT NULL COMMENT ‘身份证号’,

BirthDate date DEFAULT NULL COMMENT ‘出生日期’,

Age int(3) DEFAULT NULL COMMENT ‘年龄’,

AgeType int(9) DEFAULT NULL COMMENT ‘年龄类型’,

HomeAddress varchar(64) DEFAULT NULL COMMENT ‘家庭住址’,

CaseNumber varchar(64) DEFAULT NULL COMMENT ‘一名患者在同一医院看诊多次,根据患者是否使用同一个病历本,确定该患者的“病历号码”是否相同。’,

VisitDate date NOT NULL COMMENT ‘本次看诊日期’,

Noon int(9) NOT NULL COMMENT ‘午别’,

DeptId int(9) DEFAULT NULL COMMENT ‘本次挂号科室ID’,

UserId int(9) DEFAULT NULL COMMENT ‘本次挂号医生id’,

IsBook int(1) NOT NULL COMMENT ‘病历本要否’,

RegisterTime datetime DEFAULT NULL COMMENT ‘挂号时间’,

RegisterID int(9) NOT NULL COMMENT ‘挂号员ID’,

VisitState int(9) DEFAULT NULL COMMENT ‘本次看诊状态’,

PRIMARY KEY (id),

KEY FK_医生id (UserId),

CONSTRAINT FK_医生id FOREIGN KEY (UserId) REFERENCES user (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/dn2/

CREATE TABLE disease (

id int(9) NOT NULL COMMENT ‘id’,

DiseaseCode varchar(64) DEFAULT NULL COMMENT ‘疾病助记编码’,

DiseaseName varchar(255) DEFAULT NULL COMMENT ‘疾病名称’,

DiseaseICD varchar(64) DEFAULT NULL COMMENT ‘国际ICD编码’,

DiseaseType varchar(64) DEFAULT NULL COMMENT ‘疾病所属分类’,

DelMark int(1) DEFAULT NULL COMMENT ‘删除标记’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE drugs (

id int(9) NOT NULL COMMENT ‘id’,

Drugs_Code char(14) DEFAULT NULL COMMENT ‘药品编码’,

Drugs_Name varchar(64) DEFAULT NULL COMMENT ‘药品名称’,

Drugs_Format varchar(64) DEFAULT NULL COMMENT ‘药品规格’,

Drugs_Unit varchar(64) DEFAULT NULL COMMENT ‘包装单位’,

Manufacturer varchar(512) DEFAULT NULL COMMENT ‘生产厂家’,

Drugs_Dosage varchar(64) DEFAULT NULL COMMENT ‘药品剂型’,

Drugs_Type varchar(64) DEFAULT NULL COMMENT ‘药品类型’,

Drugs_Price decimal(8,2) DEFAULT NULL COMMENT ‘药品单价’,

Mnemonic_Code varchar(64) DEFAULT NULL COMMENT ‘拼音助记码’,

Creation_Date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘创建时间’,

DelMark int(1) DEFAULT NULL COMMENT ‘有效性标记’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

验证


创建完成后分别在mycat客户端、dn1节点、dn2节点查看表存储情况

在这里插入图片描述

Mycat客户端验证

执行过程如下:

[root@mycat ~]# mysql -umycat -p123456 -h 127.0.0.1 -P8066

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB)

Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MySQL [(none)]> use TESTDB

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

MySQL [TESTDB]> CREATE TABLE department (

-> id int(9) NOT NULL AUTO_INCREMENT COMMENT ‘id’,

-> DeptCode varchar(64) NOT NULL COMMENT ‘科室编码’,

-> DeptName varchar(64) NOT NULL COMMENT ‘科室名称’,

-> DeptCategory varchar(64) DEFAULT NULL COMMENT ‘科室分类’,

-> DeptTypeID int(9) NOT NULL COMMENT ‘科室类型’,

-> DelMark int(1) DEFAULT NULL COMMENT ’ 删除标记’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.02 sec)

MySQL [TESTDB]>

MySQL [TESTDB]> CREATE TABLE user (

-> id int(9) NOT NULL COMMENT ‘id’,

-> UserName varchar(64) NOT NULL COMMENT ‘登录名’,

-> Password varchar(64) DEFAULT NULL COMMENT ‘密码’,

-> RealName varchar(64) NOT NULL COMMENT ‘真实姓名’,

-> UserTypeID int(9) DEFAULT NULL COMMENT '1 - 挂号人员 2 - 门诊医生 3 - 医技医生 4 - 药房人员 5 - 财务人员 6 - 行政人员 ',

-> DocTitleID int(9) DEFAULT NULL COMMENT ‘医生职称’,

-> IsScheduling int(9) DEFAULT NULL COMMENT ‘是否排班’,

-> DeptId int(9) NOT NULL COMMENT ‘所在科室ID’,

-> RegistId int(9) DEFAULT NULL COMMENT ‘挂号级别ID’,

-> DelMark int(1) DEFAULT NULL COMMENT ’ 删除标记’,

-> PRIMARY KEY (id),

-> KEY FK_科室id (DeptId),

-> CONSTRAINT FK_科室id FOREIGN KEY (DeptId) REFERENCES department (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.06 sec)

MySQL [TESTDB]>

MySQL [TESTDB]>

MySQL [TESTDB]> CREATE TABLE register (

-> id int(9) NOT NULL COMMENT ‘id’,

-> RealName varchar(64) DEFAULT NULL COMMENT ‘真实姓名’,

-> Gender int(9) DEFAULT NULL COMMENT ‘性别’,

-> IDnumber varchar(18) DEFAULT NULL COMMENT ‘身份证号’,

-> BirthDate date DEFAULT NULL COMMENT ’ 出生日期’,

-> Age int(3) DEFAULT NULL COMMENT ‘年龄’,

-> AgeType int(9) DEFAULT NULL COMMENT ’ 年龄类型’,

-> HomeAddress varchar(64) DEFAULT NULL COMMENT ‘家庭住址’,

-> CaseNumber varchar(64) DEFAULT NULL COMMENT ‘一名患者在同一医院看诊多次,根据患者是否使用同一个病历本,确定该患者的“病历号码”是否相同。’,

-> VisitDate date NOT NULL COMMENT ‘本次 看诊日期’,

-> Noon int(9) NOT NULL COMMENT ‘午别’,

-> DeptId int(9) DEFAULT NULL COMMENT ‘本次挂号科室ID’,

-> UserId int(9) DEFAULT NULL COMMENT ‘本次挂号医生id’,

-> IsBook int(1) NOT NULL COMMENT ‘病历本要否’,

-> RegisterTime datetime DEFAULT NULL COMMENT ‘挂号时间’,

-> RegisterID int(9) NOT NULL COMMENT ‘挂号员ID’,

-> VisitState int(9) DEFAULT NULL COMMENT ‘本次看诊状态’,

-> PRIMARY KEY (id),

-> KEY FK_医生id (UserId),

-> CONSTRAINT FK_医生id FOREIGN KEY (UserId) REFERENCES user (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.03 sec)

MySQL [TESTDB]>

MySQL [TESTDB]>

MySQL [TESTDB]> /dn2/

MySQL [TESTDB]> CREATE TABLE disease (

-> id int(9) NOT NULL COMMENT ‘id’,

-> DiseaseCode varchar(64) DEFAULT NULL COMMENT ‘疾病助记编码’,

-> DiseaseName varchar(255) DEFAULT NULL COMMENT ‘疾病名称’,

-> DiseaseICD varchar(64) DEFAULT NULL COMMENT ‘国际ICD编码’,

-> DiseaseType varchar(64) DEFAULT NULL COMMENT ‘疾病所属分类’,

-> DelMark int(1) DEFAULT NULL COMMENT ’ 删除标记’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.03 sec)

MySQL [TESTDB]>

MySQL [TESTDB]>

MySQL [TESTDB]> CREATE TABLE drugs (

-> id int(9) NOT NULL COMMENT ‘id’,

-> Drugs_Code char(14) DEFAULT NULL COMMENT ‘药品编码’,

-> Drugs_Name varchar(64) DEFAULT NULL COMMENT ‘药品名称’,

-> Drugs_Format varchar(64) DEFAULT NULL COMMENT ‘药品规格’,

-> Drugs_Unit varchar(64) DEFAULT NULL COMMENT ‘包装单位’,

-> Manufacturer varchar(512) DEFAULT NULL COMMENT ‘生产厂家’,

-> Drugs_Dosage varchar(64) DEFAULT NULL COMMENT ‘药品剂型’,

-> Drugs_Type varchar(64) DEFAULT NULL COMMENT ‘药品类型’,

-> Drugs_Price decimal(8,2) DEFAULT NULL COMMENT ‘药品单价’,

-> Mnemonic_Code varchar(64) DEFAULT NULL COMMENT ‘拼音助记码’,

-> Creation_Date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘创建时间’,

-> DelMark int(1) DEFAULT NULL COMMENT ’ 有效性标记’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.03 sec)

MySQL [TESTDB]> show tables;

±--------------------+

| Tables_in_his_mycat |

±--------------------+

| disease |

| drugs |

| department |

| register |

| user |

±--------------------+

5 rows in set (0.01 sec)

MySQL [TESTDB]>

dn1节点验证

[root@mycat bin]# mysql -uroot -proot -h 172.17.0.2 -P 3306

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MySQL connection id is 17

Server version: 5.7.34 MySQL Community Server (GPL)

Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MySQL [(none)]> use his_mycat

Database changed

MySQL [his_mycat]> show tables;

±--------------------+

| Tables_in_his_mycat |

±--------------------+

| department |

| register |

| user |

±--------------------+

3 rows in set (0.00 sec)

MySQL [his_mycat]>

dn2节点验证

[root@mycat ~]# mysql -uroot -proot -h 172.17.0.3 -P 3306

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MySQL connection id is 13

Server version: 5.7.34 MySQL Community Server (GPL)

Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MySQL [(none)]> use his_mycat

Database changed

MySQL [his_mycat]> show tables;

±--------------------+

| Tables_in_his_mycat |

±--------------------+

| disease |

| drugs |

±--------------------+

2 rows in set (0.00 sec)

MySQL [his_mycat]>

分表

============================================================

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中。

需求


在电信行业有电信计费系统(BOSS系统),假设其中存储如下信息:

  • 客户手机账户(手机号)信息

  • 手机通话记录信息

  • 字典表(如存储常用的码表信息,例如 通话类型,01:呼出,02:呼入等)

简单ER图如下:

在这里插入图片描述

**MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,

需要进行水平拆分(分表)进行优化。BOSS系统预测5年内客户手机账户表5000万条以上。解决方案是将手机号表进行水平拆分。

表结构sql语句如下:**

/* 创建数据库 */

CREATE DATABASE boss;

USE boss;

/* 客户手机号表 */

CREATE TABLE customer (

id bigint(20) NOT NULL COMMENT ‘主键’,

cid bigint(20) DEFAULT NULL COMMENT ‘客户id’,

name varchar(500) DEFAULT NULL COMMENT ‘客户名称’,

phone varchar(500) DEFAULT NULL COMMENT ‘电话号’,

provice varchar(500) DEFAULT NULL COMMENT ‘所属省份’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘电信客户信息(手机号)’;

/* 手机号通话记录 */

CREATE TABLE calllog (

id bigint(20) NOT NULL COMMENT ‘id’,

phone_id bigint(20) DEFAULT NULL COMMENT ‘主键’,

type varchar(10) DEFAULT NULL COMMENT ‘通话类型’,

duration bigint(20) DEFAULT NULL COMMENT ‘通话时长(秒)’,

othernum varchar(20) DEFAULT NULL COMMENT ‘对方电话号’,

PRIMARY KEY (id),

KEY FK_Reference_1 (phone_id),

CONSTRAINT FK_Reference_1 FOREIGN KEY (phone_id) REFERENCES customer (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘通话记录’;

/* 字典表 */

CREATE TABLE dict (

id bigint(20) NOT NULL COMMENT ‘id’,

caption varchar(100) DEFAULT NULL COMMENT ‘代码类型名称’,

code varchar(10) DEFAULT NULL COMMENT ‘代码’,

name varchar(10) DEFAULT NULL COMMENT ‘名称’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘字典表’;

分表实现(取模)


此规则为对分片字段求摸运算

user_id

mod-long

3

**上面 columns 标识将要分片的表字段,algorithm 分片函数,

此种配置非常明确即根据 id 进行十进制求模预算,相比固定分片 hash,此种在批量插入时可能存在批量插入单

事务插入多数据分片,增大事务一致性难度(因此种方式实现最简单所以优先说明)。**

原则

以客户表(customer)为例可以采用不同字段进行分表:

| 序号 | 分表字段 | 说明 |

| — | — | — |

| 1 | id(主键、或创建时间) | 从业务上来看同一个客户的不同手机号分布在不同的数据节点上,可能造成查询效率降低 |

| 2 | cid(客户 id)、provice(省份) | 根据客户 id 去分,两个节点访问平均,一个客户所有的手机号都在同一个数据节点上。 |

安装数据库

此处同上述过程一样采用docker容器模拟不同的数据节点。此处为测试方便创建两个MySQL数据库容器。

docker run --name spt1 -p 3416:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

docker run --name spt2 -p 3426:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

执行过程如下:

[root@mycat ~]# docker run --name spt1 -p 3416:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 && docker run --name spt2 -p 3426:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

c9273c38f676aaf09321c6b117cf9445d5a15a632694480daf02db8cc9352bf6

5b19f22dbefbd00a65aaa6185a0c493518b4d71a5ff10b63f0bef6404efbb9bc

[root@mycat ~]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

5b19f22dbefb mysql:5.7 “docker-entrypoint.s…” 4 seconds ago Up 2 seconds 33060/tcp, 0.0.0.0:3426->3306/tcp, :::3426->3306/tcp spt2

c9273c38f676 mysql:5.7 “docker-entrypoint.s…” 6 seconds ago Up 4 seconds 33060/tcp, 0.0.0.0:3416->3306/tcp, :::3416->3306/tcp spt1

[root@mycat ~]#

创建数据库、表

分别连接两个容器,并执行上述sql脚本用于创建数据库、数据库表。

1、查询两个容器的ip地址

[root@mycat ~]# docker inspect --format ‘{{ .NetworkSettings.IPAddress }}’ spt1 | awk ‘{print “spt1:”,$1}’ && docker inspect --format ‘{{ .NetworkSettings.IPAddress }}’ spt2 | awk ‘{print “spt2:”,$1}’

spt1: 172.17.0.2

spt2: 172.17.0.3

[root@mycat ~]#

2、连接容器spt1,执行数据库脚本

[root@mycat ~]# mysql -uroot -proot -h172.17.0.2 -P 3306

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.7.34 MySQL Community Server (GPL)

Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MySQL [(none)]> /* 创建数据库 */

MySQL [(none)]> CREATE DATABASE boos;

Query OK, 1 row affected (0.00 sec)

MySQL [(none)]>

MySQL [(none)]> USE boos;

phone varchar(500) DEFAULT NULL COMMENT ‘电话号’,

provice varchar(500) DEFAULT NULL COMMENT ‘所属省份’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘电信客户信息(手机号)’;

/* 手机号通话记录 */

CREATE TABLE calllog (

id bigint(20) NOT NULL COMMENT ‘id’,

phone_id bigint(20) DEFAULT NULL COMMENT ‘客户手机号外键’,

type varchar(10) DEFAULT NULL COMMENT ‘通话类型’,

duration bigint(20) DEFAULT NULL COMMENT ‘通话时长(秒)’,

othernum varchar(20) DEFAULT NULL COMMENT ‘对方电话号’,

PRIMARY KEY (id),

KEY FK_Reference_1 (phone_id),

CONSTRAINT FK_Reference_1 FOREIGN KEY (phone_id) REFERENCES customer (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘通话记录’;

/* 字典表 */

CREATE TABLE dict (

id bigint(20) NOT NULL COMMENT ‘id’,

caption varchar(100) DEFAULT NULL COMMENT ‘代码类型名称’,

code varchar(10) DEFAULT NULL COMMENT ‘代码’,

name varchar(10) DEFAULT NULL COMMENT ‘名称’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFDatabase changed

MySQL [boos]>

MySQL [boos]> /* 客户手机号表 */

MySQL [boos]> CREATE TABLE customer (

-> id bigint(20) NOT NULL COMMENT ‘主键’,

-> cid bigint(20) DEFAULT NULL COMMENT ‘客户id’,

-> name varchar(500) DEFAULT NULL COMMENT ‘客户名称’,

-> phone varchar(500) DEFAULT NULL COMMENT ‘电话号’,

-> provice varchar(500) DEFAULT NULL COMMENT ‘所属省份’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘电信客户信息(手机号)’;

AULT CHARSET=utf8mb4 COMMENT=‘字典表’;Query OK, 0 rows affected (0.04 sec)

MySQL [boos]>

MySQL [boos]>

MySQL [boos]> /* 手机号通话记录 */

MySQL [boos]> CREATE TABLE calllog (

-> id bigint(20) NOT NULL COMMENT ‘id’,

-> phone_id bigint(20) DEFAULT NULL COMMENT ‘主键’,

-> type varchar(10) DEFAULT NULL COMMENT ‘通话类型’,

-> duration bigint(20) DEFAULT NULL COMMENT ‘通话时长(秒)’,

-> othernum varchar(20) DEFAULT NULL COMMENT ‘对方电话号’,

-> PRIMARY KEY (id),

-> KEY FK_Reference_1 (phone_id),

-> CONSTRAINT FK_Reference_1 FOREIGN KEY (phone_id) REFERENCES customer (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘通话记录’;

Query OK, 0 rows affected (0.03 sec)

MySQL [boos]>

MySQL [boos]>

MySQL [boos]> /* 字典表 */

MySQL [boos]> CREATE TABLE dict (

-> id bigint(20) NOT NULL COMMENT ‘id’,

-> caption varchar(100) DEFAULT NULL COMMENT ‘代码类型名称’,

-> code varchar(10) DEFAULT NULL COMMENT ‘代码’,

-> name varchar(10) DEFAULT NULL COMMENT ‘名称’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘字典表’;

Query OK, 0 rows affected (0.02 sec)

MySQL [boos]> show tables;

±---------------+

| Tables_in_boos |

±---------------+

| calllog |

| customer |

| dict |

±---------------+

3 rows in set (0.00 sec)

MySQL [boos]>

3、连接容器spt1,执行数据库脚本

[root@mycat ~]# mysql -uroot -proot -h172.17.0.3 -P 3306

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.7.34 MySQL Community Server (GPL)

Copyright © 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MySQL [(none)]> /* 创建数据库 */

MySQL [(none)]> CREATE DATABASE boos;

Query OK, 1 row affected (0.00 sec)

MySQL [(none)]>

MySQL [(none)]> USE boos;

phone varchar(500) DEFAULT NULL COMMENT ‘电话号’,

provice varchar(500) DEFAULT NULL COMMENT ‘所属省份’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘电信客户信息(手机号)’;

/* 手机号通话记录 */

CREATE TABLE calllog (

id bigint(20) NOT NULL COMMENT ‘id’,

phone_id bigint(20) DEFAULT NULL COMMENT ‘主键’,

type varchar(10) DEFAULT NULL COMMENT ‘通话类型’,

duration bigint(20) DEFAULT NULL COMMENT ‘通话时长(秒)’,

othernum varchar(20) DEFAULT NULL COMMENT ‘对方电话号’,

PRIMARY KEY (id),

KEY FK_Reference_1 (phone_id),

CONSTRAINT FK_Reference_1 FOREIGN KEY (phone_id) REFERENCES customer (id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘通话记录’;

/* 字典表 */

CREATE TABLE dict (

id bigint(20) NOT NULL COMMENT ‘id’,

caption varchar(100) DEFAULT NULL COMMENT ‘代码类型名称’,

code varchar(10) DEFAULT NULL COMMENT ‘代码’,

name varchar(10) DEFAULT NULL COMMENT ‘名称’,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFDatabase changed

MySQL [boos]>

MySQL [boos]> /* 客户手机号表 */

MySQL [boos]> CREATE TABLE customer (

-> id bigint(20) NOT NULL COMMENT ‘主键’,

-> cid bigint(20) DEFAULT NULL COMMENT ‘客户id’,

-> name varchar(500) DEFAULT NULL COMMENT ‘客户名称’,

-> phone varchar(500) DEFAULT NULL COMMENT ‘电话号’,

-> provice varchar(500) DEFAULT NULL COMMENT ‘所属省份’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘电信客户信息(手机号)’;

AULT CHARSET=utf8mb4 COMMENT=‘字典表’;Query OK, 0 rows affected (0.04 sec)

MySQL [boos]>

MySQL [boos]>

MySQL [boos]> /* 手机号通话记录 */

MySQL [boos]> CREATE TABLE calllog (

-> id bigint(20) NOT NULL COMMENT ‘id’,

-> phone_id bigint(20) DEFAULT NULL COMMENT ‘主键’,

-> type varchar(10) DEFAULT NULL COMMENT ‘通话类型’,

-> duration bigint(20) DEFAULT NULL COMMENT ‘通话时长(秒)’,

-> othernum varchar(20) DEFAULT NULL COMMENT ‘对方电话号’,

-> PRIMARY KEY (id),

-> KEY FK_Reference_1 (phone_id),

-> CONSTRAINT FK_Reference_1 FOREIGN KEY (phone_id) REFERENCES customer (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘通话记录’;

Query OK, 0 rows affected (0.03 sec)

MySQL [boos]>

MySQL [boos]>

MySQL [boos]> /* 字典表 */

MySQL [boos]> CREATE TABLE dict (

-> id bigint(20) NOT NULL COMMENT ‘id’,

-> caption varchar(100) DEFAULT NULL COMMENT ‘代码类型名称’,

-> code varchar(10) DEFAULT NULL COMMENT ‘代码’,

-> name varchar(10) DEFAULT NULL COMMENT ‘名称’,

-> PRIMARY KEY (id)

-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘字典表’;

Query OK, 0 rows affected (0.02 sec)

MySQL [boos]> show tables;

±---------------+

| Tables_in_boos |

±---------------+

| calllog |

| customer |

| dict |

±---------------+

3 rows in set (0.00 sec)

MySQL [boos]>

mycat实现分表

根据需求此处需要将customer 进行水平拆分,并分布到两个数据节点spt1、spt2上。需要做如下修改

1、修改schema.xml

<?xml version="1.0"?>

<mycat:schema xmlns:mycat=“http://io.mycat/”>

<dataHost name=“host1” maxCon=“1000” minCon=“10” balance=“0”

writeType=“0” dbType=“mysql” dbDriver=“native” switchType=“1”

slaveThreshold=“100”>

select user()

<dataHost name=“host2” maxCon=“1000” minCon=“10” balance=“0”

writeType=“0” dbType=“mysql” dbDriver=“native” switchType=“1”

slaveThreshold=“100”>

select user()

</mycat:schema>

2、修改rule.xml配置customer_rule规则

在 rule 配置文件里新增分片规则 customer_rule,并指定规则适用字段为cid,

cid

mod-long

**还有选择分片算法 mod-long(对字段求模运算),cid对两个节点求模,根据结果分片

配置算法 mod-long 参数 count 为 2,两个节点**

2

配置完的完整的rule.xml如下

<?xml version="1.0" encoding="UTF-8"?>

<mycat:rule xmlns:mycat=“http://io.mycat/”>

cid

mod-long

id

func1

user_id

func1

sharding_id

hash-int

id

rang-long

id

mod-long

id

murmur

id

crc32slot

create_time

partbymonth

calldate

latestMonth

id

rang-mod

id

jump-consistent-hash

<function name=“murmur”

class=“io.mycat.route.function.PartitionByMurmurHash”>

0

2

160

<function name=“crc32slot”

class=“io.mycat.route.function.PartitionByCRC32PreSlot”>

2

<function name=“hash-int”

class=“io.mycat.route.function.PartitionByFileMap”>

partition-hash-int.txt

<function name=“rang-long”

class=“io.mycat.route.function.AutoPartitionByLong”>

autopartition-long.txt

2

8

128

<function name=“latestMonth”

class=“io.mycat.route.function.LatestMonthPartion”>

24

<function name=“partbymonth”

class=“io.mycat.route.function.PartitionByMonth”>

yyyy-MM-dd

2015-01-01

partition-range-mod.txt

3

</mycat:rule>

启动Mycat,登录Mycat插入数据进行验证

insert into customer (id, cid, name, phone, provice) values(‘1’,‘1’,‘张飞’,‘13800000001’,‘燕人’);

insert into customer (id, cid, name, phone, provice) values(‘2’,‘2’,‘赵云’,‘13800000002’,‘真定’);

insert into customer (id, cid, name, phone, provice) values(‘3’,‘3’,‘诸葛亮’,‘13800000003’,‘沂南’);

insert into customer (id, cid, name, phone, provice) values(‘4’,‘4’,‘关羽’,‘13800000004’,‘运城’);

insert into customer (id, cid, name, phone, provice) values(‘5’,‘5’,‘刘玄德’,‘13800000005’,‘涿州’);

insert into customer (id, cid, name, phone, provice) values(‘6’,‘6’,‘孙策’,‘13800000006’,‘东吴’);

插入数据后在Mycat客户端、数据节点spt1、sp2上分别执行查询发现

  • 数据节点spt1、spt2分别保存一部分数据

  • mycat客户端可以查询出所有数据

在这里插入图片描述

需要注意的点,mycat插入时根据字段分片,需要提供字段枚举

正确的插入sql

insert into customer (id, cid, name, phone, provice) values('5','5','刘玄德','13800000005','涿州');

错误的sql

insert into customer values('6','6','孙策','13800000006','东吴');

不提供列的枚举会报如下错误:

MySQL [TESTDB]> insert into customer values(‘6’,‘6’,‘孙策’,‘13800000006’,‘东吴’);

ERROR 1064 (HY000): partition table, insert must provide ColumnList

Mycat 的分片 join


Join 绝对是关系型数据库中最常用一个特性,然而在分布式环境中,跨分片的 join 确是最复杂的,最难解决一个问题。

Mycat性能建议

**尽量避免使用 Left join 或 Right join,而用 Inner join

在使用 Left join 或 Right join 时,ON 会优先执行,where 条件在最后执行,所以在使用过程中,条件尽

可能的在 ON 语句中判断,减少 where 的执行

少用子查询,而用 join。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。

资料领取方式:点击这里免费领取前端全套学习资料

css源码pdf

JavaScript知识点
g4MzkxNw==,size_16,color_FFFFFF,t_70)

需要注意的点,mycat插入时根据字段分片,需要提供字段枚举

正确的插入sql

insert into customer (id, cid, name, phone, provice) values('5','5','刘玄德','13800000005','涿州');

错误的sql

insert into customer values('6','6','孙策','13800000006','东吴');

不提供列的枚举会报如下错误:

MySQL [TESTDB]> insert into customer values(‘6’,‘6’,‘孙策’,‘13800000006’,‘东吴’);

ERROR 1064 (HY000): partition table, insert must provide ColumnList

Mycat 的分片 join


Join 绝对是关系型数据库中最常用一个特性,然而在分布式环境中,跨分片的 join 确是最复杂的,最难解决一个问题。

Mycat性能建议

**尽量避免使用 Left join 或 Right join,而用 Inner join

在使用 Left join 或 Right join 时,ON 会优先执行,where 条件在最后执行,所以在使用过程中,条件尽

可能的在 ON 语句中判断,减少 where 的执行

少用子查询,而用 join。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-ixiMAVUq-1713547654429)]

[外链图片转存中…(img-FjNEQGBB-1713547654430)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-Dk9CHEJU-1713547654430)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

[外链图片转存中…(img-h0qDQIRx-1713547654430)]

最后

javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。

资料领取方式:点击这里免费领取前端全套学习资料

[外链图片转存中…(img-RwbZ09gg-1713547654430)]

[外链图片转存中…(img-7pCrAucM-1713547654431)]

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值