针对高并发、数据量大的场景,通常会考虑采用分库分表进行优化。在这篇文章,我们重点盘点一下Node.js主流ORM框架的动态分表方案:

分表规则
比如我们需要对订单表进行分表操作。可以根据实际业务需求设计分表规则,在这里,我们根据顾客Id取模动态生成表名。比如,拆分为16张表,顾客Id为129,对应的表名如下:

const tableName = Order_${129 % 16}; // Order_1
TypeORM
在TypeORM中可以按照如下方式设置动态表名:

// 获取repository
const repositoryOrder = dataSource.createQueryBuilder().connection.getRepository(EntityOrder);
// 设置动态表名
const userId = 129;
const tableName = Order_${userId % 16};
repositoryOrder.metadata.tablePath = tableName;
// 查询订单
const orders = await repositoryOrder.find();
Drizzle ORM
schema.ts

const orderFactory = userId => pgTable(
Order_${userId % 16},
{
id: serial(‘id’).primaryKey(),
name: text(‘name’).notNull(),
},
);

export const order0 = orderFactory(0);

export const order15 = orderFactory(15);
query.ts

import * as schema from ‘./db/schema’;

const db = drizzle(process.env.DATABASE_URL!, { schema });

const userId = 129;
const modelName=order${userId % 16};
const orders = await db.query[modelName].findMany();
Prisma ORM
Prisma ORM对动态表名的支持还在规划当中,参见:Table Partitioning

作为备选方案,我们可以使用$queryRawUnsafe直接构造原始SQL:

const userId = 129;
const tableName = Order_${userId % 16};
const orders = await prisma. q u e r y R a w U n s a f e ( ‘ S E L E C T ∗ F R O M " queryRawUnsafe(`SELECT * FROM " queryRawUnsafe(SELECTFROM"{tableName}"`);
Vona ORM
Vona ORM提供了两种模式:自动模式/手工模式

  1. 自动模式
    model/order.ts

import { EntityOrder } from ‘…/entity/order.ts’;

@Model({
entity: EntityOrder,
table(ctx: VonaContext, defaultTable: keyof ITableRecord) {
const user = ctx.app.bean.passport.getCurrentUser();
if (!user) return defaultTable;
return ${defaultTable}_${Number(user.id) % 16};
},
})
export class ModelOrder {}
defaultTable: 是在EntityOrder中定义的缺省表名,如:Order
service/order.ts

class ServiceOrder {
async findAll() {
return await this.scope.model.order.select();
}
}
2. 手工模式
service/order.ts

class ServiceOrder {
async findAll() {
const user = this.bean.passport.getCurrentUser();
const tableName = Order_${Number(user!.id) % 16};
const modelOrder = this.scope.model.order.newInstance(undefined, tableName as any);
return await modelOrder.select();
}
}
newInstance: 第一个参数可以传入数据源,从而实现分库能力。这里忽略,因此传入undefined

文章转自:[《GTAOL》佩里科夫岛前置任务技巧分享 ] (https://www.52mwyd.com/news/6151.html)

作者:游戏攻略,转载请注明原文链接:https://www.52mwyd.com/

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐