Isso faria sentido para que o aplicativo reforçasse a integridade do banco de dados em vez de ter chaves estrangeiras, verificar restrições etc.?
Quanta melhoria de desempenho se pode esperar por não impor a integridade do banco de dados por meio de ferramentas internas de banco de dados?
Verdade seja dita, você não apenas não verá muita perda de desempenho por ter restrições de chave estrangeira no banco de dados, mas também verá aprimoramentos de desempenho. O otimizador de consulta do SQL Server é construído em torno do conceito de chaves primárias e estrangeiras, bem como outros tipos de restrições de dados. Se eles estiverem em vigor e aplicados, o otimizador poderá aproveitá-los para obter um melhor desempenho. Aqui está uma postagem no blog com um exemplo simples que mostra isso em ação.
Se você estiver em um caso extremo em que realmente tem mais inserções do que leituras (e as atualizações e exclusões exigem leituras, então elas geralmente acabam sendo adicionadas à contagem de leituras), pode fazer sentido remover as restrições dos dados para desempenho, talvez . Mas como a esmagadora maioria dos bancos de dados é orientada para leitura, você está sacrificando o desempenho, não o aprimorando.
E nada disso menciona o fato de que a integridade dos dados é melhor tratada no banco de dados, pois você só precisa criá-lo uma vez, como se fizesse todo o trabalho no código, talvez tenha que fazê-lo várias vezes para vários aplicativos (a menos que você projete sua camada de acesso a dados com cuidado e exija que todos os aplicativos acessem o banco de dados para passar por essa mesma camada).
Se você estiver usando um sistema de banco de dados relacional, eu digo, por que não usá-lo realmente? Se você não precisa de dados relacionais, vá com o Hadoop ou qualquer outra coisa.
Muitos desenvolvedores de aplicativos pensam assim.
Quando você se sentir tentado a delegar a integridade dos dados ao código do aplicativo, pense "Todo programador e todo aplicativo que acessa esse banco de dados de agora até o fim dos tempos deve acertar perfeitamente, sempre".
Quais são as hipóteses?
Mesmo que haja algum ganho de desempenho, ele é insignificante em comparação com o retorno da integridade referencial e da integridade generalizada dos dados.
Longe vão os dias em que um banco de dados é um armazenamento de dados burro. Aproveite o poder que o RDBMS oferece.
Os ganhos de desempenho não são tudo, especialmente em uma escala tão pequena como esta. Mas quando você descobre que tem um suposto relacionamento de chave estrangeira que seu aplicativo deve impor, e acontece que não é uma chave primária na tabela de referência, você se importará muito pouco com o ganho de desempenho (se houver, posso não falar sobre os detalhes disso).
É prática comum descartar restrições (chaves estrangeiras, CHECK, etc) e índices se você estiver fazendo uma carga de dados grande o suficiente e reativar/implementar as restrições e índices posteriormente. Essa validação tem um custo de tempo. Isso pressupõe que você não possa usar a sintaxe de carregamento em massa específica do banco de dados (incluindo a minimização do log).
É impossível dizer quanto de aumento de desempenho esperar - cada situação é única (tipos de dados, design etc.). A única maneira de realmente saber é testando.
Há algumas ocasiões em que as restrições atrapalham:
Quando você precisa usar Single Table Inheritance (STI). Imagine que você vende para indivíduos e organizações. Você precisará de uma única tabela "Partido" cuja linha seja um indivíduo ou uma organização. STI significa que você precisa de alguns campos anuláveis que não devem ser nulos. Herança de tabela de classe resolve isso, mas isso é mais difícil para alguns ORMs. O ActiveRecord do Ruby suporta apenas STI, por exemplo.
Quando você precisa oferecer suporte a versões de rascunho de uma entidade, isso pode não ser totalmente válido. Você pode armazenar um rascunho como json, mas é mais difícil reutilizar o mesmo identificador no cliente - imagine que ele foi salvo com id=5, editado para não ser válido e salvo automaticamente como draftid=99. Nesse caso, todos os seus campos provavelmente teriam que ser anuláveis.