Sim, é uma péssima ideia.
Ao invés de ir:
SELECT Deal.Name, DealCategory.Name
FROM Deal
INNER JOIN
DealCategories ON Deal.DealID = DealCategories.DealID
INNER JOIN
DealCategory ON DealCategories.DealCategoryID = DealCategory.DealCategoryID
WHERE Deal.DealID = 1234
Agora você precisa ir:
SELECT Deal.ID, Deal.Name, DealCategories
FROM Deal
WHERE Deal.DealID = 1234
Em seguida, é necessário fazer algumas coisas no código do aplicativo para dividir a lista de vírgulas em números individuais e, em seguida, consultar o banco de dados separadamente:
SELECT DealCategory.Name
FROM DealCategory
WHERE DealCategory.DealCategoryID IN (<<that list from before>>)
Esse antipadrão de design deriva de um completo mal-entendido da modelagem relacional (você não precisa ter medo de tabelas. As tabelas são suas amigas. Use-as) ou uma crença estranhamente equivocada de que é mais rápido pegar uma lista separada por vírgula e dividi-la no código do aplicativo do que é adicionar uma tabela de links ( nunca é). A terceira opção é que eles não são confiantes / competentes o suficiente com o SQL para poder configurar chaves estrangeiras, mas se for esse o caso, eles não devem ter nada a ver com o design de um modelo relacional.
Antipatterns do SQL (Karwin, 2010) dedica um capítulo inteiro a esse antipattern (que ele chama de 'Jaywalking'), páginas 15-23. Além disso, o autor postou uma pergunta semelhante no SO . Os principais pontos que ele observa (conforme aplicado a este exemplo) são:
- A consulta a todas as transações em uma categoria específica é bastante complicada (a maneira mais fácil de resolver esse problema é uma expressão regular, mas uma expressão regular é um problema por si só).
- Você não pode impor integridade referencial sem relacionamentos de chave estrangeira. Se você excluir o DealCategory nr. # 26, você deve, no código do aplicativo, passar por cada transação procurando referências à categoria # 26 e excluí-las. Isso é algo que deve ser tratado na camada de dados, e ter que lidar com isso em seu aplicativo é uma coisa muito ruim .
- Consultas agregadas (
COUNT
, SUM
etc), mais uma vez, variam de 'complicado' para 'quase impossível'. Pergunte aos desenvolvedores como eles obteriam uma lista de todas as categorias com uma contagem do número de transações nessa categoria. Com um design adequado, são quatro linhas de SQL.
- As atualizações se tornam muito mais difíceis (ou seja, você tem um acordo em cinco categorias, mas deseja remover duas e adicionar outras três). São três linhas de SQL com um design adequado.
- Eventualmente, você terá
VARCHAR
limitações de tamanho da lista. Embora se você tiver uma lista separada por vírgulas com mais de 4000 caracteres, é provável que esteja analisando que o monstro será lento como o inferno de qualquer maneira.
- Retirar uma lista do banco de dados, dividi-la e depois retornar ao banco de dados para outra consulta é intrinsecamente mais lento que uma consulta.
TLDR: é um design fundamentalmente defeituoso, não aumenta com escala, introduz complexidade adicional até para as consultas mais simples e, logo após a instalação, torna o aplicativo mais lento.