Estrutura do banco de dados SQL para API RESTful

11

Estou criando uma API RESTful. Estou lutando para decidir a melhor maneira de projetar minhas tabelas de banco de dados com base em meus recursos.

Inicialmente, pensei que uma tabela por recurso seria um bom caminho, mas agora estou preocupado que isso resulte em tabelas exponencialmente maiores à medida que você avança na cadeia de recursos.

Por exemplo, imagine que eu tenho três recursos - usuários, clientes, vendas. Usuários são assinantes da minha API, clientes são usuários e vendas são compras feitas por cada cliente na conta do usuário.

Um recurso de venda é acessado da seguinte maneira

GET /users/{userID}/clients/{clientID}/sales/{salesID}

Portanto, se houver 10 usuários, cada um com 10 clientes, e para cada cliente houver 10 vendas, o tamanho da tabela aumentará à medida que avançamos na cadeia de recursos.

Estou bastante confiante de que o SQL pode lidar com tabelas grandes, mas não tenho certeza de como a leitura e a gravação irão atrasar as coisas. O exemplo acima talvez não o ilustre, mas minha API terá gravações e leituras progressivamente mais aprofundadas na cadeia de recursos que percorrermos. Portanto, tenho o cenário em que as tabelas maiores do meu banco de dados serão lidas e gravadas mais vezes que as tabelas menores.

Também será necessário ingressar nas tabelas antes de executar as consultas. O motivo é que eu permito que cada usuário tenha um cliente com o mesmo nome. Para evitar a obtenção de dados incorretos do cliente, a tabela de usuários e as tabelas de clientes são unidas por {userID}. Este também é o caso das vendas. A junção de tabelas grandes e a execução de leituras e gravações desaceleram ainda mais?

Gaz_Edge
fonte

Respostas:

31

Estou lutando para decidir a melhor maneira de projetar minhas tabelas de banco de dados com base em meus recursos.

Não.

Projete sua API de acordo com os princípios RESTful , projete seu banco de dados de acordo com os princípios de normalização . Um não precisa impactar o outro.

Seu banco de dados não deve conter uma SaleResourcetabela, deve conter uma tabela Sale(ou compra / pedido). Essa tabela incluirá uma chave primária que identifica exclusivamente uma venda e chaves estrangeiras para tabelas relacionadas de usuário e cliente.

A API REST do REST converterá uma solicitação do recurso identificado por GET /users/{userID}/clients/{clientID}/sales/{salesID}na consulta de banco de dados apropriada, recuperará a linha, construirá o recurso que representa uma Venda e o retornará ao cliente.

Lembre-se de que você está atualmente expondo o que parece ser identificadores internos do banco de dados (ID do usuário / ID do cliente / ID da venda) para o mundo externo. Pode ser apropriado no seu caso, mas geralmente <entity>IDparece uma API RESTful.

Mark Storey-Smith
fonte
obrigado. Então, o que você está dizendo, basicamente, é que, enquanto eu normalizar minha bases de dados e de configuração apropriado indexação etc, não deve haver problemas de desempenho para o que eu quero alcançar
Gaz_Edge
3
Sim. Nada do que você mencionou sugere que seria necessário desviar de um esquema normalizado.
Mark-Storey-Smith
9

Bancos de dados relacionais (portanto, SQL) são realmente bons em localizar uma (ou poucas) linhas de uma tabela enorme. É para isso que servem os índices. Eles também são incríveis no manuseio de junções. Você realmente não tem uma pergunta . Entre as linhas, você está basicamente perguntando sobre como criar um design de banco de dados com vários inquilinos. Sugiro que você leia a Arquitetura de dados com vários locatários antes de fazer mais perguntas. Escolha um dos padrões (banco de dados separado, esquemas separados de banco de dados compartilhado, esquema compartilhado de banco de dados compartilhado) e, em seguida, discutiremos detalhes. No momento, você apenas visualiza o último padrão, mas não considera os prós e os contras. Leia.

Como uma observação lateral: você não precisa user/{userID}no URI. Você conhece o inquilino (ID do usuário) nas informações de autenticação.

Remus Rusanu
fonte
obrigado- Sim, eu preciso ler mais. Meus projetos até o momento tiveram muito pouco trabalho no banco de dados. Vou ler o recurso que você recomendou
Gaz_Edge
Eu acho que compartilhar compartilhado é o caminho a percorrer para mim. Meus 'usuários' não são 'inquilinos'. Eles não requerem dados isolados e nunca precisarão de acesso direto a nenhuma função de gerenciamento de banco de dados. Pelo que li, isso sugere que o compartilhamento compartilhado é melhor? O que você acha?
Gaz_Edge 18/02
2
compartilhado é o mais fácil. Você deve adicionar o user_idcomo uma chave a todas as tabelas e adicionar left.user_id = right.user_ida junções relevantes (geralmente, todas). Alguns ORMs oferecem suporte ao escopo do acesso. E não se engane, seus usuários são inquilinos, pois você não deseja que o usuário 'foo' veja / modifique as vendas da 'barra' do usuário.
Remus Rusanu
Obrigado. Estou começando a ver que os índices são essenciais para criar minha estrutura de banco de dados.
Gaz_Edge 18/02
0

Apenas para adicionar ao que já foi dito aqui - convém criar uma interface entre a API real e sua camada de banco de dados. Facilita a adição de tabelas de cache e de resumo abaixo da linha ...

Matt Koskela
fonte
1
alguns links ou explicação adicional seria útil
Gaz_Edge
Desculpe, não posso comentar ainda ..
Matt Koskela