Executando verificação de segurança...
2

[Dúvida] Banco de dados com mais de 1000 itens?

Estou desenvolvendo um projeto multiplataforma (site, extensão e aplicativo), que recebe dados inseridos pelo usuário e realiza três verificações.

Edit. É uma aplicação que recebe um link do usuário e diz se ele é confiável de clicar, eu dividi em dois banco de dados, pois tem alguns que são mais frequente do usuário questionar.

Eu também tenho uma função que divide em pedaços menores o link, para reduzir o número de caracteres. Recorta o http e .com.

Obs1. Haverá um servidor para cada aplicação.

Obs2. Os dados inseridos são strings, não há números.

Minha dúvida é referente aos banco de dados que devo usar para cada verificação.

Contexto:

1
A primeira verificação é realizada no backend da aplicação, que compara o dado inserido pelo usuário com uma lista de quase 300 itens armazenada no servidor, cada item contém uma média de 42 caracteres por item. Penso em utilizar algum tipo de índice para essa tabela.

2
A segunda verificação também é realizada no servidor da aplicação, também é necessário um índice para ela, pois irá comparar o dado inserido pelo usuário com uma blacklist com 600 a 800 itens.

Então a primeira e segunda etapa de verificação usarão o mesmo banco de dados. Como preciso da melhor performance nessa parte, penso em usar o MongoDB e deixar em cache de servidor os dados da lista. O que acham?

3
A terceira verificação é realizada com uma api própria, hospedada em outro servidor e se utilizando de outro banco de dados, está ao receber os dados, irá comparar o dado enviado pelo usuário com uma lista de 2000 a 10.000 itens (os 2000 eu tenho certeza que vai ter, enquanto o 10.000 é uma estimativa para caso eu deseje ampliar o projeto).

Cada item tem uma média de 60 caracteres, e terão propriedades, 5 para cada item.

Ex. Ilustrativo:
Item: Cadeira
Propriedade 1: Madeira
Propriedade 2: Novo
Propriedade 3: Conforto
Propriedade 4: São Paulo

Minha idéia para garantir melhor performance:

O dado do usuário irá percorrer toda a lista até achar seu idêntico na tabela, retornando um valor para a aplicação. Para que não percorra milhares de itens toda vez, planejo dividir em várias pequenas tabelas que se iniciam com a letra do alfabeto, e sequência de dois caracteres, (A, B, C… AA, AB, AC...).

Penso em utilizar o MySQL para esse banco de dados, mas tenho ficado em dúvida sobre este ser o melhor, pois encontrei discussões falando que só se pode ter um índice dentro dele, e eu precisaria de vários, um para a sequência do alfabeto, e um para cada letra do alfabeto + uma segunda letra.

Pretendo programar usando Expo para as aplicações e Laravel para a api.

Carregando publicação patrocinada...
2

Acho que você está caindo na armadilha da otimização prematura.

Antes de otimizar, você precisa de métricas para identificar quais áreas do seu sistema estão precisando de aprimoramentos. Depois disso, você pode identificar quais são os aprimoramentos que realmente valem a pena implementar. Talvez você nem tenha problema algum de desempenho e vá adicionar complexidade desnecessária ao seu sistema. Talvez precise aumentar o desempenho, mas esteja focado no local errado. Por isso, primeiro precisamos das métricas de desempenho para depois poder aprimorar.

Pequena nota: quando você diz:

O dado do usuário irá percorrer toda a lista até achar seu idêntico na tabela, retornando um valor para a aplicação. Para que não percorra milhares de itens toda vez, planejo dividir em várias pequenas tabelas que se iniciam com a letra do alfabeto, e sequência de dois caracteres, (A, B, C… AA, AB, AC...).

Este método funcionaria caso a distribuição dos seus links seja normalizada. Caso contrário, você vai acabar sobrecarregando uma das tabelas. Por exemplo, se os valores tenderem a iniciar com a letra A, você terá uma tabela A muito maior do que as restantes e não ajudará em desempenho (pelo contrário, pode piorar). Existem maneiras de fazer particionamento no banco de dados mesmo. Alem do mains, indices já organizam dados em árvores balanceadas, outro motivo para não fazer este tipo de otimização. Caso realmente você precise, teria que calcular um hash balanceado para depois poder quebrar em outras tabelas.

2

1
A primeira verificação é realizada no backend da aplicação, que compara o dado inserido pelo usuário com uma lista de quase 300 itens armazenada no servidor, cada item contém uma média de 42 caracteres por item. Penso em utilizar algum tipo de índice para essa tabela.

Compara para fazer o que com o resultado da comparação?


2
A segunda verificação também é realizada no servidor da aplicação, também é necessário um índice para ela, pois irá comparar o dado inserido pelo usuário com uma blacklist com 600 a 800 itens.
Então a primeira e segunda etapa de verificação usarão o mesmo banco de dados. Como preciso da melhor performance nessa parte, penso em usar o MongoDB e deixar em cache de servidor os dados da lista. O que acham?

Pq você acha que MongoDB seria uma boa alternativa para isso?
Não tenho experiência com NoSQL, porém pelo que já estudei a respeito, se seus dados tem uma estrutura bem definida e você precisa de consistência e integridade os bancos relacionais atendem muito bem.


3
A terceira verificação é realizada com uma api própria, hospedada em outro servidor e se utilizando de outro banco de dados, está ao receber os dados, irá comparar o dado enviado pelo usuário com uma lista de 2000 a 10.000 itens (os 2000 eu tenho certeza que vai ter, enquanto o 10.000 é uma estimativa para caso eu deseje ampliar o projeto).

Mesma pergunta sobre o item 1, que comparação é essa? Vai fazer o que com o resultado?


Minha idéia para garantir melhor performance:
O dado do usuário irá percorrer toda a lista até achar seu idêntico na tabela, retornando um valor para a aplicação. Para que não percorra milhares de itens toda vez, planejo dividir em várias pequenas tabelas que se iniciam com a letra do alfabeto, e sequência de dois caracteres, (A, B, C… AA, AB, AC...).
Penso em utilizar o MySQL para esse banco de dados, mas tenho ficado em dúvida sobre este ser o melhor, pois encontrei discussões falando que só se pode ter um índice dentro dele, e eu precisaria de vários, um para a sequência do alfabeto, e um para cada letra do alfabeto + uma segunda letra.

Isso aqui pra mim é bem estranho, criar uma tabela por letra de alfabeto por conta de uma pequena quantidade de registros.
Trabalho com tabelas de milhões de registros, com uma boa estrutura de índices, queries bem trabalhadas, cache e etc. Não há problemas de performance.

10k de registros por tabela é quase nada para um SGBD tradicional.

1

Obrigado pela resposta.

É uma aplicação que recebe um link do usuário e diz se ele é confiável de clicar, eu dividi em dois banco de dados, pois tem alguns que são mais frequente do usuário questionar.

Eu também tenho uma função que divide em pedaços menores o link, para reduzir o número de caracteres. Recorta o http e .com.

Não sabia sobre a segunda parte, achava que 10.000 itens era bastante coisa.

2

O dado do usuário irá percorrer toda a lista até achar seu idêntico na tabela, retornando um valor para a aplicação. Para que não percorra milhares de itens toda vez, planejo dividir em várias pequenas tabelas que se iniciam com a letra do alfabeto, e sequência de dois caracteres, (A, B, C… AA, AB, AC...).

Confuso, esse trecho me fez pensar que você acha que um select vai percorrer todos os registros de suas tabelas até achar o valor solicitado. Mesmo sem indexação o sgbd tem maneiras eficientes para lidar com isso. Procure se atentar ao esquema do seu banco de dados, veja isso. E como o rapaz já falou, 10k de registros não é muita coisa para um mysql da vida. Outro ponto, já que seus links vão ocupar 60 bytes, no lugar de salvar os links "puros", vc pode salvar um hash, assim vai ter mais confiabilidade na hora de comparar. Por exemplo, você pode fazer isso

SELECT is_sec FROM tb1 WHERE link = user_link;
2

Sobre a quantidade de dados, relaxe... Agora sobre o banco de dados, como um cara comentou abaixo, se todos os dados são bem definidos, vá para um db relacional, um mongo da vida escreve novos documentos muito rápido, mas a leitura é muito mais lenta que qualquer outro db, se for só uma tabela pode até ser que não, mas se você for fazer agregations(até mesmo uma query) com varios lookups(joins), ele se torna exponencialmente mais lento, então se for usar, faça o esquema com mais itens dentro dele mesmo que fora, para evitar esses lookups.

Essa parte do banco de dados é por experiência própria, trabalho em uma empresa que o sistema cresceu muito, aí cada agregation tem uns 10 lookups, as vezes demora mais de 3 segundos para obter uma resposta.

Ah! Outra coisa, caso tenha realmente muitos itens, coisa de milhões e uma instância extremamente fraca, o db mesmo assim vai aguentar, só que elas vão demorar um pouco mais para entregar os dados.

1
1
1

Amigo, 10k de registros é nada no mundo de hj, tenho aplicações que só de subir elas já geram mais de 10k de dados para o setup inicial.

Em relação aos diferentes bancos de dados, acho que você está estruturando errado sua aplicação. Se você identificou que existem alguns links que são usados mais vezes vc deveria usar um cache como o redis ao invez de um banco de disco, e outra coisa, é recomendável que exista um algoritmo que seleciona oq ele vai fazer cache ou não, ao invez de um humano decidir os links mais usados.

O mysql também aceita indexamento de colunas de strings, logo o mais facil e resolveria seu problema para ate milhões de entradas seria criar uma tabela no mysql com a coluna string q tu qr buscar, e indexar por essa coluna. A complexidade dos indexes por btree no mysql é log2(n), para termos de comparação o log2(2^32) = 32, então mesmo q encha 4 bilhões de registros ainda vai ser bem rapido a busca, e se algum momento da sua vida vc precisa de mais desempenho, o mysql tmb implementa hash indexes que funcionam apenas para busca de ==, e tem complexidade média de O(1) (constante)

Resumo: não precisa reinventar a roda, os bancos de dados hoje são mt eficientes e dão conta fácil da sua necessidade. usa um sistema simples de redis+mysql até surgir a necessidade de algo mais performatico (posso garantir q não vai)