0

What I have right now: I have a Spring Boot back-end which provides my front-end with data from my MySQL database. The application is a tool for companies to manage their warehouse (WMS). At the time being, all of the data is in the same data source. I store the data with a JpaRepository.

The problem: To better understand the background: When company A makes a request to get all its articles, the back-end also has to iterate through the datasets from company B, C, D, ...

What I want to have: To change this behavior, every time a company account is created, I want to create a new data source (e.g. jdbc:mysql://81.123.456.789:3306/wms_{companyname}), depending on a passed parameter. Later on, when a request is made, I can pass the companies name as a parameter to access the right data source. Note that all of the data still will be on the same database, but on multiple schemas.

My question: How can I implement the described behavior, or are there other best practice solutions for this scenario?

I found this tutorial to access multiple data sources, but note that I want to access data sources dynamically and do not know the number or names of the data sources at the time I write this application.

Example controller:

@RestController
@RequestMapping("/articles")
public class ArticleController {

    private final ArticleService articleService;

    public ArticleController(ArticleService articleService) {
        this.articleService = articleService;
    }

    @GetMapping("/{articleNr}")
    ArticleInformation getArticleInformation(@PathVariable String articleNr) {
        return articleService.getArticleInformationByArticleNrAndLocation(articleNr,null);
    }

    @GetMapping
    List<Article> getCurrentArticles() {
        return articleService.findAllByCurrentUser();
    }

    @PostMapping
    Article create(@RequestBody Article newArticle) {
        return articleService.create(newArticle);
    }

    @PutMapping
    Article update(@RequestBody Article updatedArticle) {
        return articleService.update(updatedArticle);
    }

    @DeleteMapping("/{id}")
    Long id(@PathVariable Long id) {
        return articleService.deleteById(id);
    }

}

Example repository:

public interface ArticleRepository extends JpaRepository<Article, Long> {
    List<Article> findAllByCompany(Company company);
    Article findByArticleNrAndCompany(String articleNr, Company company);
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Pumpanickel
  • 91
  • 2
  • 10
  • 1
    _"the back-end also has to iterate through the datasets"_, if you correctly design your database and its indexes, your back-end doesn't have to 'iterate' through datasets from other companies. The query engine of your database should take care of that. – Mark Rotteveel Jan 02 '21 at 09:58
  • @MarkRotteveel you mean, that there is no real reason to change the behavior as it is right now? – Pumpanickel Jan 02 '21 at 10:03
  • I can't answer that for you, but if your real problem right now is that your back-end is iterating through datasets and that is slow, then you should stop doing that, and instead utilize the power of your database engine by defining proper queries, and maybe making changes that optimize those queries (proper indexes, maybe partitioning, materialized views, etc). That doesn't mean that sharding into a separate database or schema per company isn't a good solution, it is just not the only solution, and simple optimizations might be better/cheaper (at least in the short term). – Mark Rotteveel Jan 02 '21 at 10:07

0 Answers0