{"id":21300914,"url":"https://github.com/kibae/typeorm-sharding-repository","last_synced_at":"2025-07-11T20:31:04.857Z","repository":{"id":49758565,"uuid":"517960584","full_name":"kibae/typeorm-sharding-repository","owner":"kibae","description":"TypeORM Sharding Repository: Enables TypeORM to be utilized in a distributed database environment.","archived":false,"fork":false,"pushed_at":"2024-07-17T07:09:08.000Z","size":143,"stargazers_count":15,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-04T08:41:28.402Z","etag":null,"topics":["decorator","distributed","distributed-database","nodejs","rangesharding","sharding","typeorm","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/typeorm-sharding-repository","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kibae.png","metadata":{"files":{"readme":"README.ko.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-26T07:37:29.000Z","updated_at":"2025-06-14T00:24:36.000Z","dependencies_parsed_at":"2022-08-30T11:32:22.429Z","dependency_job_id":null,"html_url":"https://github.com/kibae/typeorm-sharding-repository","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/kibae/typeorm-sharding-repository","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kibae%2Ftypeorm-sharding-repository","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kibae%2Ftypeorm-sharding-repository/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kibae%2Ftypeorm-sharding-repository/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kibae%2Ftypeorm-sharding-repository/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kibae","download_url":"https://codeload.github.com/kibae/typeorm-sharding-repository/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kibae%2Ftypeorm-sharding-repository/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264892074,"owners_count":23679220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorator","distributed","distributed-database","nodejs","rangesharding","sharding","typeorm","typescript"],"created_at":"2024-11-21T15:42:15.013Z","updated_at":"2025-07-11T20:31:02.025Z","avatar_url":"https://github.com/kibae.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypeORM Sharding Repository\n- TypeORM을 분산 데이터베이스 환경에서 활용할 수 있게 합니다.\n\n[![Node.js CI](https://github.com/kibae/typeorm-sharding-repository/actions/workflows/node.js.yml/badge.svg)](https://github.com/kibae/typeorm-sharding-repository/actions/workflows/node.js.yml)\n[![NPM Version](https://badge.fury.io/js/typeorm-sharding-repository.svg)](https://www.npmjs.com/package/typeorm-sharding-repository)\n[![License](https://img.shields.io/github/license/kibae/typeorm-sharding-repository)](https://github.com/kibae/typeorm-sharding-repository/blob/main/LICENSE)\n\n## Install\n- NPM\n```shell\n$ npm install typeorm-sharding-repository --save\n```\n\n- Yarn\n```shell\n$ yarn add typeorm-sharding-repository\n```\n\n----\n\n## Usage\n### 1. Prepare DataSources.\n- TypeORM DataSource 설정 대신 ShardingManager을 설정해 주세요. 대부분의 설정은 TypeORM과 동일합니다.\n- 이 예제의 User entity는 정수형의 키를 가지고 있습니다. 호환되는 키나 키의 범위 규칙에 따라 ShardingManager를 설정하는 것을 추천합니다.\n```typescript\nconst dbConf = {\n    host: 'localhost',\n    database: 'playground',\n    username: 'postgres',\n    password: 'postgrespw',\n    synchronize: true,\n    logging: 'all',\n};\n\nconst shardManager = await ShardingManager.init({\n    shardingType: ShardingType.RANGE,\n    // 이곳에 입력되는 공통 설정(TypeORM.BaseDataSourceOptions)은 모든 shard에 적용됩니다. \n    type: 'postgres',\n    entities: [User],\n    shards: [\n        // 개별 데이터베이스 shard의 설정을 합니다.\n        // minKey, maxKey는 다양한 타입을 가질수 있습니다. 멀티컬럼 PK를 가진 경우 튜플 형태로 구성할 수도 있습니다.\n        // onInitialize(typeorm.DataSource) callback 은 옵션입니다.\n        { ...dbConf, port: 55000, minKey: 0, maxKey: 1000, onInitialize: (dataSource) =\u003e {/* TypeORM.DataSource.initialize() 이후 실행됨 */} },\n        { ...dbConf, port: 55001, minKey: 1000, maxKey: 2000, onInitialize: (dataSource) =\u003e {/**/} },\n        { ...dbConf, port: 55002, minKey: 2000, maxKey: 3000, onInitialize: (dataSource) =\u003e {/**/} },\n    ],\n});\n```\n\n### 2. Apply to Entity\n1. **@Entity** decorator 대신 **@ShardingEntity** decorator를 사용하세요.\n2. **BaseEntity** 대신 **ShardingBaseEntity**를 상속받으세요.\n- 새로운 데이터가 추가된 shard에 쌓이기 시작합니다.\n```typescript\n@ShardingEntity\u003cUser, number\u003e({\n    // Modular sharding은 추후 지원 예정입니다.\n    type: ShardingType.RANGE,\n    \n    // Entity가 어떤 shard에서 처리될 지 알려줘야 합니다. 하나의 entity를 처리하기 위해 최대 shard 갯수만큼 호출됩니다.\n    // 새로운 entity가 추가될 때에는 키 값이 비어있습니다.\n    // 모든 shard에 대해 false가 리턴된 경우 마지막 샤드가 선택됩니다.\n    // minKey, maxKey는 ShardingManager에 정의된 값들이 전달됩니다.\n    // 여러 ShardingManager를 관리하고 싶지 않다면 이 함수에서 entity 간의 관계에 따라 minKey, maxKey를 기준으로만 삼고 데이터의 양을 조절할 수 있습니다.\n    findShard: (entity: User, minKey, maxKey) =\u003e entity.id \u0026\u0026 minKey \u003c= entity.id \u0026\u0026 entity.id \u003c maxKey,\n    \n    // findShard과 유사하지만 판정을 entity가 아닌 키 값을 기준으로 합니다.\n    // ID 값은 타입이 모호합니다. 이 예제에서는 number로 전달받았으나, 배열(멀티컬럼)이나 문자열 등 다양한 값이 전달되게 됩니다.\n    // repository.findByIds() 등이 호출될 때 전달받는 ID 들이 전달되므로, 어떤 구조의 entity냐에 따라 전달되는 값의 형태가 달라지기 때문입니다.\n    findShardById: (id: number, minKey, maxKey) =\u003e id \u0026\u0026 minKey \u003c= id \u0026\u0026 id \u003c maxKey,\n})\nexport class User extends ShardingBaseEntity {\n    @PrimaryGeneratedColumn() id: number;\n    @Column() firstName: string;\n    @Column() lastName: string;\n    @Column() age: number;\n}\n```\n\n### 3. RepositoryService (Abstract repository for TypeORM.BaseEntity and ShardingBaseEntity)\n- TypeORM.BaseEntity과 ShardingBaseEntity와 호횐되는 `RepositoryService`를 제공합니다.\n- 이 패턴을 활용할 경우 sharding 적용 여부를 변경하더라도 코드의 변경이 없습니다.\n- [Repository Interface](https://github.com/kibae/typeorm-sharding-repository/tree/main/src/repository-service/abstract-repository-service.ts)\n```typescript\n// 두 저장소 서비스는 동일한 인터페이스를 가지고 있습니다. \nconst typeormRepository = RepositoryService.of(MyEntityBasedOnTypeormBaseEntity);\nconst shardingRepository = RepositoryService.of(MyEntityBasedOnShardingBaseEntity);\n\ninterface AbstractRepositoryService\u003cEntity\u003e {\n    create(entityLike: DeepPartial\u003cEntity\u003e): Entity | Entity[];\n    create(entityLike: DeepPartial\u003cEntity\u003e): Entity | Entity[];\n    create(entityLike?: DeepPartial\u003cEntity\u003e | DeepPartial\u003cEntity\u003e[]): Entity | Entity[];\n\n    save(entities: DeepPartial\u003cEntity\u003e[], options?: SaveOptions): Promise\u003cEntity[]\u003e;\n    save(entity: DeepPartial\u003cEntity\u003e, options?: SaveOptions): Promise\u003cEntity\u003e;\n\n    remove(entities: Entity[], options?: RemoveOptions): Promise\u003cEntity[]\u003e;\n    remove(entity: Entity, options?: RemoveOptions): Promise\u003cEntity\u003e;\n\n    softRemove(entities: Entity[], options?: SaveOptions): Promise\u003cEntity[]\u003e;\n    softRemove(entity: Entity, options?: SaveOptions): Promise\u003cEntity\u003e;\n\n    update(\n        criteria: string | string[] | number | number[] | Date | Date[] | ObjectID | ObjectID[] | FindOptionsWhere\u003cEntity\u003e,\n        partialEntity: QueryDeepPartialEntity\u003cEntity\u003e\n    ): Promise\u003cUpdateResult\u003e;\n\n    delete(\n        criteria: string | string[] | number | number[] | Date | Date[] | ObjectID | ObjectID[] | FindOptionsWhere\u003cEntity\u003e\n    ): Promise\u003cDeleteResult\u003e;\n\n    count(options?: FindManyOptions\u003cEntity\u003e): Promise\u003cnumber\u003e;\n    countBy(where: FindOptionsWhere\u003cEntity\u003e): Promise\u003cnumber\u003e;\n\n    find(options?: FindManyOptions\u003cEntity\u003e): Promise\u003cEntity[]\u003e;\n    findBy(where: FindOptionsWhere\u003cEntity\u003e): Promise\u003cEntity[]\u003e;\n\n    findAndCount(options?: FindManyOptions\u003cEntity\u003e): Promise\u003c[Entity[], number]\u003e;\n    findAndCountBy(where: FindOptionsWhere\u003cEntity\u003e): Promise\u003c[Entity[], number]\u003e;\n\n    findOne(options: FindOneOptions\u003cEntity\u003e): Promise\u003cEntity | null | undefined\u003e;\n    findOneBy(where: FindOptionsWhere\u003cEntity\u003e): Promise\u003cEntity | null | undefined\u003e;\n    findOneById(id: string | number | Date | ObjectID): Promise\u003cEntity | null\u003e;\n    findByIds(ids: any[]): Promise\u003cEntity[]\u003e;\n}\n```\n\n### 4. Entity [static] method\n- [테스트 코드를 참조하세요.](https://github.com/kibae/typeorm-sharding-repository/blob/main/src/test/sharding-manager.spec.ts), [(Case1 Entity)](https://github.com/kibae/typeorm-sharding-repository/blob/main/src/test/entity/case1.ts)\n```typescript\n// TypeORM.BaseEntity와 거의 동일한 기능들을 제공합니다.\nconst entity = await Case1.save({\n    firstName: 'Typeorm',\n    lastName: 'Sharding',\n    age: 10,\n});\n\nawait entity.save();\nawait entity.remove();\nawait entity.softRemove();\nawait entity.recover();\nawait entity.reload();\n\n\n//      _______.___________.    ___   .___________. __    ______ \n//     /       |           |   /   \\  |           ||  |  /      |\n//    |   (----`---|  |----`  /  ^  \\ `---|  |----`|  | |  ,----'\n//     \\   \\       |  |      /  /_\\  \\    |  |     |  | |  |     \n// .----)   |      |  |     /  _____  \\   |  |     |  | |  `----.\n// |_______/       |__|    /__/     \\__\\  |__|     |__|  \\______|\n\n// Entity instance를 생성합니다.\nCase1.create();\nCase1.create({firstName: 'Typeorm', ...});\n\n// 모든 shard의 모든 entity를 반환합니다. 정렬 순서는 보장되지 않습니다.\nawait Case1.find();\n\n// 모든 shard에서 firstName이 Typeorm인 모든 entity를 반환합니다. 정렬 순서는 보장되지 않습니다.\nawait Case1.find({ where: {firstName: 'Typeorm'} });\n\n// 모든 shard를 검색해 firstName이 Typeorm인 하나의 entity를 반환합니다.\n// 여러 shard에서 발견된 경우 가장 오래된 shard의 entity가 반환됩니다.\nawait Case1.findOneBy({ firstName: 'Typeorm' });\n\n// ID로 검색하여 하나의 entity를 반환합니다.\nawait Case1.findOneById(1);\n\n// 모든 shard에서 firstName이 Typeorm인 모든 entity의 수를 반환합니다.\nawait Case1.count({ where: {firstName: 'Typeorm'} });\n\n// 여러 entity를 update합니다.\nawait Case1.update({ firstName: 'Typeorm' }, { lastName: 'Bob' });\n\n// Entity를 삭제합니다.\nawait Case1.remove(entity);\n\n\n//  __        ______   ____    __    ____     __       ___________    ____  _______  __      \n// |  |      /  __  \\  \\   \\  /  \\  /   /    |  |     |   ____\\   \\  /   / |   ____||  |     \n// |  |     |  |  |  |  \\   \\/    \\/   /     |  |     |  |__   \\   \\/   /  |  |__   |  |     \n// |  |     |  |  |  |   \\            /      |  |     |   __|   \\      /   |   __|  |  |     \n// |  `----.|  `--'  |    \\    /\\    /       |  `----.|  |____   \\    /    |  |____ |  `----.\n// |_______| \\______/      \\__/  \\__/        |_______||_______|   \\__/     |_______||_______|\n\n// 모든 TypeORM DataSource\nCase1.getAllDataSource();\n\n// 특정 entity를 담당하는 TypeORM DataSource\nCase1.getDataSource(entity);\n\n// 특정 ID를 담당하는 TypeORM DataSource\nCase1.getDataSourceById(ID_VALUE);\n\n// 모든 TypeORM Reposigory\nCase1.getAllRepository\u003cCase1\u003e();\n\n// 특정 entity를 담당하는 TypeORM Reposigory\nCase1.getRepository\u003cCase1\u003e(entity);\n\n// 특정 entity를 담당하는 TypeORM Manager\nCase1.getManager\u003cCase1\u003e(entity);\n```\n\n----\n\n## Contributors\n\u003ca href=\"https://github.com/kibae/typeorm-sharding-repository/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=kibae/typeorm-sharding-repository\" /\u003e\n\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkibae%2Ftypeorm-sharding-repository","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkibae%2Ftypeorm-sharding-repository","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkibae%2Ftypeorm-sharding-repository/lists"}