mysql分表分为127张表_GitHub - ShenYiQian/SASDN-Database

SASDN-Database是基于Typeorm的数据库封装,支持分库分表。通过ShardKey字段进行一致性哈希,实现数据自动分布到不同分表。分库则依据用户配置的shardingStrategies策略,将表分散到多个数据库连接。用户只需遵循一定的规范,如使用ShardTable装饰器指定分表数量,继承BaseOrmEntity等,即可轻松进行分库分表操作。
摘要由CSDN通过智能技术生成

SASDN-Database

1. 简介

SASDN-Database是基于Typeorm的封装,内部实现了分库分表的功能,对于开发者来说,只需要遵循一些规范即可像原来一样通过操作对象的方式来操作数据库。

2. 功能

2.1 ShardKey

若需要使用分表功能,首先要了解什么是ShardKey, ShardKey是表中的一个字段,但是一定要保证唯一。插件读取此字段的值然后根据一致性hash算法去计算该条数据具体落在那一张分表上。用户只需在设计表时思考好今后使用哪一个字段并保证其唯一性即可。

该字段在设计表结构时需要定义,在代码编写运行时会用到,在设置及Entity代码定义中不需要使用。

2.2 分表

当用户指定完ShardKey后,可以通过装饰器ShardTable定义所需分表的数量,插件会自动进行分表操作,对用户来说是无感知的。一张需要进行分表的Entity类似下面的代码:

import { Entity, Column, PrimaryColumn } from 'typeorm';

import { BaseOrmEntity, ShardTable } from 'sasdn-database';

@Entity('shard_table') // 定义表名

@ShardTable(5) // 定义分表数量

export class ShardEntity extends BaseOrmEntity { // 继承BaseOrmEntity

@PrimaryColumn({ type: 'bigint', name: 'table_id' })

tableId: number;

@Column({ type: 'varchar', name: 'table_desc', length: 255})

tableDesc: string;

}

2.3 分库

分库将根据用户给定的DatabaseOptions中的shardingStrategies字段读取用户希望那张表落于那个库上,若用户不指定则默认使用取余的方式将所有表散列到所有库上。自定义配置如下,有两种情况需要注意:

有分表需求,则需要在原来的表名后添加_${表号}

shardingStrategies: [

{

connctionName: 'test_shard_0',

entities: [

'ShardEntity_0',

'ShardEntity_3',

],

},

{

connctionName: 'test_shard_1',

entities: [

'ShardEntity_1',

'ShardEntity_4',

],

},

{

connctionName: 'test_shard_2',

entities: [

'ShardEntity_2',

],

},

],

无分表需求,则只需给定具体那张表落在那个库上即可

shardingStrategies: [

{

connctionName: 'test_shard_0',

entities: [

'GameUser',

],

},

{

connctionName: 'test_shard_1',

entities: [

'GameBind',

'GameGuid',

],

},

{

connctionName: 'test_shard_2',

entities: [

'GameInfo',

],

},

],

3. 规范定义

所有Entity类均需要继承BaseOrmEntity

分表需要使用ShardTable装饰器,并给定分表数量

将所有Entity类统一放在一个entities文件夹中,并且在命名中不要使用_

统一通过getEntity方法获得获得具体Entity类

使用DatabaseOptions对数据库链接进行声明,并调用initialize进行初始化

4. 具体使用

4.1 定义数据库文件

首先需要定义数据库文件的sql文件(若使用NOSQL则无需定义),然后根据定义好的sql文件写相应的Entity,一个简单的EntityClass如下:

import { Entity, Column, PrimaryColumn } from 'typeorm';

import { BaseOrmEntity, ShardTable } from 'sasdn-database';

@Entity('shard_table') // 定义表名

@ShardTable(5) // 定义分表数量

export class ShardEntity extends BaseOrmEntity { // 继承BaseOrmEntity

@PrimaryColumn({ type: 'bigint', name: 'guid' })

tableid: number;

@Column({ type: 'varchar', name: 'table_desc', length: 255})

tableDesc: string;

}

4.2 定义DatabaseOptions

然后我们可以在通过sql文件创建完表之后编写数据库链接配置:

const databaseOptions: DatabaseOptions = {

name: 'mysql',

type: 'mysql',

// 需要先在数据库上生成对应的表,不然会报错

// 第一次使用可不指定,使用默认进行表分配

shardingStrategies: [

{

connctionName: 'test_shard_0',

entities: [

'ShardEntity_0',

'ShardEntity_3',

],

},

{

connctionName: 'test_shard_1',

entities: [

'ShardEntity_1',

'ShardEntity_4',

],

},

{

connctionName: 'test_shard_2',

entities: [

'ShardEntity_2',

],

},

],

connectionList: [

{

name: 'test_shard_0',

type: 'mysql',

host: '127.0.0.1',

port: 3306,

username: 'root',

password: 'root',

database: 'test_shard_0',

synchronize: false,

// 默认采用*.js进行泛指

entities: [LibPath.join(__dirname, 'entities/*.js')],

},

{

name: 'test_shard_1',

type: 'mysql',

host: '127.0.0.1',

port: 3307,

username: 'root',

password: 'root',

database: 'test_shard_1',

synchronize: false,

entities: [LibPath.join(__dirname, 'entities/*.js')],

},

{

name: 'test_shard_2',

type: 'mysql',

host: '127.0.0.1',

port: 3308,

username: 'root',

password: 'root',

database: 'test_shard_2',

synchronize: false,

entities: [LibPath.join(__dirname, 'entities/*.js')],

},

],

};

4.3 初始化链接

然后我们就需要调用初始化函数:

// 第二个参数将在制定目录生成一份数据库链接对应具体Entity的Json文件,方便

// 后续进行维护和查询,若不指定可从console中查看具体输出

DatabaseFactory.instance.initialize(databaseOptions, __dirname);

4.4 编写业务代码

然后我们就可以编写对应的数据库操作:

\\ Write

const EntityModule = DatabaseFactory.instance.getEntity(ShardEntity.name, shardKey);

const entity = new EntityModule(shardKey);

entity.tableId = shardKey;

entity.tableDesc = shardKey.toString();

try {

const result = await entity.save();

console.log(`write[${success}] success result = ${result}`);

} catch (error) {

console.log('on save caught error = ', error);

}

\\ Read

const EntityModule = DatabaseFactory.instance.getEntity(ShardEntity.name, shardKey);

try {

let result = await EntityModule.findOne({ tableId: shardKey });

console.log(`read[${success}] success result = ${result}`);

} catch (error) {

console.log('on save caught error = ', error);

}

具体可以参考samples中的例子。例子中使用sqlite3进行一个简单的数据库操作,在目录下直接执行npm start即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值