JavaRush /Blogue Java /Random-PT /Entrevista com desenvolvedor: análise de questões do banc...

Entrevista com desenvolvedor: análise de questões do banco de dados

Publicado no grupo Random-PT
Olá a todos! Estamos todos aqui trabalhando com um objetivo: nos tornarmos desenvolvedores Java . Talvez a etapa mais importante no caminho para se tornar um profissional seja a entrevista técnica. Via de regra, o entrevistador aborda os tópicos principais, fazendo algumas perguntas. Neste artigo, falaremos sobre um desses tópicos importantes: bancos de dados . Vejamos as perguntas mais frequentes e tentemos respondê-las sem nos aprofundarmos no material, pois neste caso o volume do livro não será suficiente para nós! Então vamos.Entrevista com desenvolvedor: análise de questões do banco de dados - 1

1. O que são bancos de dados? Em que tipos eles são divididos?

O que se entende por SGBD?

Entrevista com desenvolvedor: análise de questões do banco de dados - 2Um banco de dados (BD) é uma estrutura organizada projetada para armazenar, alterar e processar informações inter-relacionadas, principalmente grandes volumes. Em outras palavras, um banco de dados é um armazenamento estruturado de dados. Por exemplo, uma lista telefônica.

Tipos de banco de dados

  1. Um banco de dados relacional é uma coleção de dados com relacionamentos predefinidos entre eles. Os dados são armazenados como um conjunto de tabelas que consiste em colunas e linhas. As tabelas armazenam informações sobre os objetos representados no banco de dados. Cada coluna da tabela armazena um tipo de dados específico e cada célula armazena um valor de atributo.
  2. Sistemas não relacionais (NoSQL) são sistemas projetados para modelos de dados específicos com esquemas flexíveis. Em outras palavras, são bancos de dados que armazenam dados não na forma de esquemas tabulares, linhas e colunas, mas em outros formatos.
Você pode ler mais sobre bancos de dados não relacionais neste artigo: Um guia para NoSQL para desenvolvedores . Um sistema de gerenciamento de banco de dados (SGBD) é um conjunto de software com o qual o usuário pode criar bancos de dados (BDs) e realizar diversas operações neles: complementar, atualizar, excluir, selecionar, etc. armazenamento e permite conceder acesso à administração do banco de dados. Por exemplo, MySql é um SGBD que fornece acesso a um banco de dados relacional ou MongoDB para um banco de dados não relacional.

2. O que é normalização? Forma normalizada? Quantas formas de normalização existem? Cite os três primeiros.

Normalização é o processo de organização e estruturação de dados em um banco de dados, que proporciona maior flexibilidade ao banco de dados ao eliminar redundância e inconsistência de dependências. A forma normal é uma propriedade de uma tabela, considerada no contexto da normalização, que caracteriza a tabela em termos de simplicidade e correção da estrutura. A forma normal é definida como um conjunto de requisitos que uma tabela deve satisfazer. Existem seis formas normais no total, mas na prática não são utilizadas mais do que as três primeiras:
  1. Primeira forma normal:
    • Todos os atributos são simples (isto é, atômicos e indivisíveis);
    • Todos os dados são escalares (ou seja, positivos);
    • Não há linhas duplicadas (para isso, é criada uma chave primária para cada linha).
  2. Segunda forma normal:
    • As condições da primeira forma normal são atendidas;
    • Cada atributo não-chave faz referência a uma chave primária.
  3. Terceira forma normal:
    • As condições do segundo grupo normal são satisfeitas;
    • Os campos não-chave são independentes de outros campos não-chave: eles só podem ser associados a uma chave primária.

3. Desnormalização

A desnormalização é a redução ou violação deliberada das formas de normalização do banco de dados, geralmente para acelerar a leitura do banco de dados adicionando dados redundantes. Em geral, este é um processo inverso à normalização. Isso acontece porque a teoria das formas normais nem sempre é aplicável na prática. Por exemplo, valores não atômicos nem sempre são “maus”: às vezes até o contrário. Em alguns casos, são necessárias junções adicionais ao executar consultas, especialmente ao processar uma grande quantidade de informações. Em última análise, isso pode melhorar o desempenho. Os bancos de dados destinados à análise são frequentemente desnormalizados para acelerar a execução da consulta. Por exemplo, você frequentemente coletará amostras de alguns dados para relatórios em que colunas não-chave estarão relacionadas entre si. Você remove intencionalmente a terceira forma de normalização e combina tudo em uma tabela para facilitar a amostragem - para não precisar fazer consultas adicionais em outras tabelas.

4. Índices

Um índice é um conjunto classificado de valores associados a uma tabela ou visualização com uma coluna específica que acelera a recuperação de dados. Ou seja, é uma espécie de índice: como o alfabeto de uma lista telefônica, que nos auxilia na busca pelo sobrenome. Se usado corretamente, esse recurso pode melhorar bastante o desempenho ao trabalhar com bancos de dados grandes. Ou você pode diminuir bastante. Para agilizar a busca, essas chaves são armazenadas em uma estrutura de árvore balanceada por meio da qual a busca é realizada. Como regra, os índices precisam ser inseridos nos campos mais pesquisados. Você não deve pensar em criar um índice antes de ter pelo menos 10 mil registros. Caso contrário, você não verá um resultado perceptível, porque a otimização prematura é MAL . E como um índice pode afetar o desempenho do sistema, você pergunta? Quando novos dados são inseridos ou dados antigos são excluídos, a estrutura em árvore balanceada será recalculada. Na verdade, quanto mais dados e índices, mais árvores precisam ser contadas. Imagine a situação: você tem cerca de 20.000 registros e 7 índices nesta tabela. Ou seja, ao inserir dados, é necessário recalcular 7 árvores, cada uma com 20.000 registros. Estritamente falando, não é recomendado usar índices para tabelas nas quais os dados serão adicionados/excluídos com frequência. Por fim, gostaria de observar que os índices para colunas nas quais o valor é frequentemente encontrado nullnão serão tão eficazes, portanto, não vale a pena adicioná-los a essas colunas.

Qual é a diferença entre índices clusterizados e não clusterizados em SQL?

Agrupado:

  • Fornece ordem física para o campo selecionado;
  • Se uma tabela tiver um índice clusterizado, ela será considerada clusterizada;
  • Não é necessário mais do que um índice por tabela;
  • No MySQL, um índice clusterizado não é especificado explicitamente pelo usuário, porque se você não definir uma PRIMARY KEY em sua tabela, o MySQL encontra o primeiro índice UNIQUEonde estão todas as colunas-chave NOT NULLe o InnoDB o utiliza como índice clusterizado.

Não agrupado:

  • São possíveis até 999 índices não clusterizados por tabela;
  • Contém um ponteiro para linhas com dados reais na tabela;
  • Não fornece ordem física;
  • Para índices não clusterizados, existem tabelas separadas com dados ordenados, ou seja, uma tabela para uma coluna na qual o índice está localizado, portanto, ao solicitar dados que não fazem parte de um determinado campo, a consulta será realizada primeiro no campo nesta tabela e somente então a consulta adicional em uma linha na tabela original.
Criando um índice não clusterizado:
CREATE INDEX index_name ON table_name(column_name)

6. O que é um índice composto?

Índice composto - construído com envio para diversas colunas ao mesmo tempo. Em outras palavras, é um índice complexo composto por várias colunas. Esses índices são usados ​​quando mais de uma coluna aparece em uma consulta. Criando um índice composto:
CREATE INDEX index_name ON table_name(first_column_name, second_column_name, third_column_name)
Normalmente, esses índices são usados ​​quando os dados em múltiplas colunas estão logicamente relacionados.

7. O que é um índice de cobertura? Índice único?

Um índice de cobertura é um índice suficiente para responder a uma consulta sem acessar a própria tabela. Usando esse índice, você pode obter toda a linha de dados, mas na verdade isso simplesmente não é necessário. Como você não precisa ir diretamente para a tabela de origem e pode responder usando apenas o índice, os índices de cobertura são um pouco mais rápidos de usar. Ao mesmo tempo, não esqueça que quanto mais colunas, mais complicado e lento se torna o próprio índice. Então você não deve abusar disso. Acima falamos sobre índices clusterizados e não clusterizados, que podem ser únicos . Isso significa que não existem dois campos com o mesmo valor para a chave do índice. Caso contrário, o índice não será único, pois várias linhas podem conter o mesmo valor. Um exemplo de criação de um índice exclusivo não clusterizado:
CREATE UNIQUE INDEX index_name ON table_name(column_name)

8. O que é chave primária

A chave primária é um campo em uma tabela que identifica cada linha em uma tabela de banco de dados. Só pode haver um desses campos em uma tabela e todos os valores devem ser exclusivos. Não te lembra nada? Entrevista com desenvolvedor: análise de questões do banco de dados - 3Afinal, uma chave primária nada mais é do que um índice clusterizado exclusivo. Via de regra, as chaves primárias são criadas ao criar uma tabela:
CREATE TABLE table_name(
column_name int PRIMARY KEY,..)
Uma restrição será adicionada automaticamente a esta coluna - NOT NULL. Você também pode definir uma chave para uma tabela já criada:
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
Se uma chave primária for adicionada da maneira descrita acima, os valores dos campos especificados como chave primária ( column_name) serão verificados para garantir que não contenham valores nulos (uma restrição também será adicionada - NOT NULL).

O que é uma chave estrangeira?

Uma chave estrangeira é uma propriedade criada para fornecer um relacionamento entre tabelas. Normalmente, uma chave estrangeira é definida nas colunas de uma subtabela e aponta para uma das colunas da tabela principal. Pode ser especificado como ao criar uma tabela:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) }
Então, depois de criar a tabela:
ALTER TABLE table_name
ADD FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name));
Você pode definir o comportamento de uma chave estrangeira ao manipular o campo ao qual ela se refere. As manipulações podem ser dos seguintes ON DELETEtipos ON UPDATE: Possíveis opções de comportamento:
  • CASCADE— com esta propriedade, as linhas da tabela dependente serão automaticamente excluídas ou alteradas quando linhas relacionadas forem excluídas ou alteradas na tabela principal;
  • SET NULL— com esta propriedade, quando uma linha relacionada for excluída ou atualizada da tabela principal, NULLserá definido o valor da coluna de chave estrangeira;
  • NO ACTION— rejeita tentativas de excluir ou alterar linhas na tabela principal se houver linhas relacionadas na tabela dependente;
  • RESTRICT- equivalente a NO ACTION;
  • SET DEFAULT- com esta propriedade, quando uma linha relacionada for excluída ou atualizada da tabela principal, será definido o valor padrão (se houver) para a coluna de chave estrangeira.
Exemplo de uso:
CREATE TABLE table_name{
column_name int,..
FOREIGN KEY(column_name) REFERENCES another_table_name(another_table_column_name) ON UPDATE CASCADE ON DELETE CASCADE }
ON DELETESe o comportamento para e não estiver definido explicitamente ON UPDATE, o comportamento será definido como RESTRICT.

10. Tipos de conexões entre tabelas (Join)

A conexão entre tabelas é fornecida com base em dados comuns (campos). Isso acontece usando um operador JOIN, uma operação que combina linhas de uma tabela com linhas de outra. O mapeamento é feito de forma que as colunas de ambas as tabelas sejam adjacentes, embora possam ser obtidas em tabelas separadas. E se tivermos campos comuns para três tabelas, podemos exibir seus dados como uma tabela comum. Porém, vale a pena considerar que quanto menos tabelas forem unidas, mais rápida será a execução da consulta. Então, os tipos JOIN:
  • INNER JOIN- uma conexão que mostra apenas os dados da primeira tabela que correspondem a alguns dados da segunda tabela. O resto desce.Entrevista com desenvolvedor: análise de questões do banco de dados - 4
  • LEFT JOIN- uma conexão que mostra todos os dados da primeira tabela e os dados correspondentes da segunda, se houver. Se não houver dados correspondentes, os campos de dados da segunda tabela ficarão vazios.Entrevista com desenvolvedor: análise de questões do banco de dados - 5
  • RIGHT JOIN- uma conexão que mostra todos os dados da segunda tabela e os dados correspondentes da primeira, se houver. Se não houver dados correspondentes, os campos dos dados da primeira tabela ficarão vazios.Entrevista com desenvolvedor: análise de questões do banco de dados - 6
  • FULL JOIN- uma conexão que mostra todos os dados da primeira e da segunda tabelas. Se não houver dados relacionados na outra tabela, os campos desses dados estarão vazios.Entrevista com desenvolvedor: análise de questões do banco de dados - 7
  • CROSS JOIN- uma junção cruzada em que cada linha da primeira tabela é unida a cada linha da segunda tabela (cada uma para cada). Ou seja, se duas tabelas possuem 3 linhas cada, após essa junção obteremos um resultado de 9 linhas.Entrevista com desenvolvedor: análise de questões do banco de dados - 8
Exemplo Join(inner):
SELECT *
FROM first_table
INNER JOIN second_table ON first_table.some_column = second_table.some_column

11. O que é uma propriedade ACID em um banco de dados?

A - Atomicidade , garante que nenhuma transação seja parcialmente comprometida no sistema. Todas as suas suboperações são executadas ou nenhuma. Por exemplo, transferir dinheiro de um banco para outra conta envolve duas operações:
  1. Transfira dinheiro para uma conta bancária.
  2. Transferir dinheiro de uma conta bancária para uma conta específica.
Mas tudo pode acontecer. Por exemplo, eles irão ao banco, e então ocorrerá algum erro e a segunda operação não será concluída. Ou vice-versa: apenas a segunda operação será realizada. Portanto, essas ações são realizadas dentro de uma transação e o resultado é tudo ou nada. C - Consistência : Cada transação bem-sucedida sempre registra apenas resultados resolvíveis. Isso garante que todas as restrições sejam atendidas (por exemplo, NOT NULL), caso contrário a transação será revertida. E - isolamento : durante a execução de uma transação, as transações paralelas não devem afetar seu resultado. Isso nos dá a capacidade de ocultar estados de dados não finais de todos. Na verdade, é por isso que transações malsucedidas não podem quebrar nada. Um pouco mais abaixo conheceremos os níveis de isolamento das transações. D - Durabilidade : Se uma transação for concluída, você pode ter certeza de que as alterações feitas não serão canceladas devido a alguma falha.

12. Níveis de isolamento de transação

Cada nível de isolamento permite/proíbe determinadas ações (oportunidades):
  • leitura fantasma - dentro de uma mesma transação, a mesma solicitação de dados dá resultados diferentes, o que ocorre devido à adição de dados por outra transação (paralela).
  • leitura não repetitiva - dentro de uma mesma transação, a mesma solicitação de dados dá resultados diferentes, o que ocorre devido à alteração ou exclusão de dados por outra transação (paralela).
  • leitura "suja" - leitura de dados adicionados ou alterados por uma transação que não será posteriormente revertida;
  • atualização perdida - quando diferentes transações alteram o mesmo bloco de dados ao mesmo tempo, todas as alterações, exceto a última, são perdidas (semelhante a uma “condição de corrida” em multithreading).
Por conveniência, consideramos os níveis de isolamento e suas capacidades na tabela:
Níveis de isolamento Leitura fantasma Leitura não repetitiva leitura “suja” atualização perdida
SERIALIZÁVEL + + + +
REPEATABLE_READ - + + +
READ_COMMITTED - - + +
READ_UNCOMMITTED - - - +

13. O que é injeção SQL?

A injeção de SQL é um dos métodos de hackear um site, cuja essência é a injeção de algum código SQL nos dados por meio de GETconsultas POSTou Cookies. Se um site realizar tais injeções, é possível obter acesso ao banco de dados e hackear o aplicativo. Por exemplo, sabemos o nome de alguma variável. Digamos column_namecom type boolean. Se o sistema for suscetível a injeções, podemos adicionar OR column_name=truee escrever tudo o que precisamos no banco de dados. ORcriará uma condição OR, e nossa expressão depois dela sempre será true, o que nos levará mais longe. Um ataque a um site como a injeção de SQL é possível devido ao processamento inadequado de dados recebidos usados ​​em consultas SQL. Ao se conectar a um banco de dados usando JDBC , você usa vários arquivos Statements. Para aumentar a segurança, é necessário utilizar PreparedStatementem vez do usual Statement, pois quando utilizados, Statementas strings de consulta e os valores são simplesmente somados, possibilitando as injeções. Por sua vez, PreparedStatementexiste um modelo de solicitação específico, e nele os dados são inseridos com as aspas refletidas. Como resultado, as injeções de SQL serão percebidas apenas como uma representação de string de algum campo. Para se proteger contra injeções de SQL, você pode usar verificações baseadas em expressões regulares (você pode ler mais sobre expressões regulares neste artigo ). Entrevista com desenvolvedor: análise de questões do banco de dados - 9Outra opção é definir um limite para o número de caracteres dos parâmetros de entrada: por exemplo, se você receber um número não superior a 9.999, um limite de quatro caracteres de entrada será suficiente. Isso reduzirá o risco de hackers usando injeções SQL. Você pode aprender mais sobre segurança em Java no artigo “Segurança em Java: melhores práticas” .

14. O que são procedimentos armazenados? Funções armazenadas? Acionar?

Os procedimentos armazenados em SQL são uma entidade no banco de dados, que é um conjunto de instruções SQL compiladas uma vez e armazenadas no servidor. Em uma palavra, este é um análogo dos métodos em Java. Os procedimentos armazenados podem executar ações nos dados, tanto consultas normais quanto algumas ações que não estão disponíveis para consultas normais. Um procedimento é uma entidade SQL criada uma vez e depois chamada passando argumentos. A vantagem desta abordagem é que estas instruções podem ser reutilizadas mais de uma vez. Os procedimentos armazenados melhoram o desempenho, aprimoram os recursos de programação e oferecem suporte a recursos de segurança de dados. Vamos considerar a criação de um procedimento:
CREATE PROCEDURE procedure_name (first_param some_type, second_param some_type..)
 begin
……...
 end
Chamando o procedimento:
CALL procedure_name (first_param, second_param…..);
Uma função armazenada é um tipo de procedimento armazenado. A diferença entre uma função é que ela sempre retorna apenas um único valor, enquanto um procedimento retorna um conjunto de valores. Os procedimentos armazenados não podem ser misturados com o SQL normal, mas uma função armazenada pode - e esta é a sua vantagem. Por outro lado, as funções armazenadas têm muito mais limitações do que os procedimentos. Criando uma função armazenada:
CREATE FUNCTION function_name (first_param, second_param…..)
RETURNS some_type
 begin
……...
RETURN some_value;
end
Chamando uma função armazenada:
SELECT function_name(first_param, second_param…..);
Um gatilho é outro tipo de procedimento armazenado que não é chamado diretamente pelo usuário, mas é ativado quando os dados são modificados. Ou seja, este procedimento é ativado quando determinadas condições são atendidas, como, INSERTou DELETE, ou UPDATEdados em uma determinada coluna de uma determinada tabela. Quando um gatilho é acionado é determinado usando as palavras-chave BEFORE(o gatilho é acionado antes do evento associado) ou AFTER(após o evento).
CREATE TRIGGER trigger_name
ON table_name
AFTER INSERT
 begin
……...
 end

15. Pratique

Seja como for, a questão SQL mais comum em uma entrevista será prática - resolução de problemas. Não adianta tentar adivinhar quais tarefas você vai encontrar, pois tudo depende da sofisticação da imaginação de quem está à sua frente. Portanto, a única opção funcional seria melhorar as consultas SQL de complexidade variada. sql-ex.ru pode servir como um recurso para praticar várias tarefas . Após as primeiras vinte tarefas concluídas, será bastante difícil para o seu interlocutor assustá-lo com qualquer tarefa SQL. Entrevista com desenvolvedor: análise de questões do banco de dados - 11Por hoje é tudo: espero que depois de ler este artigo, dúvidas sobre bancos de dados não causem dificuldades ou problemas. Obrigado pela atenção e nos vemos novamente!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION