A incorporação de uma estrutura de dados em um campo pode funcionar para casos simples, mas impede que você aproveite os bancos de dados relacionais. Os bancos de dados relacionais são projetados para localizar, atualizar, excluir e proteger seus dados. Com um campo incorporado contendo seus próprios wad-o-data (array, JSON, xml etc), você acaba escrevendo todo o código para fazer isso sozinho.
Há casos em que o campo incorporado pode ser mais adequado, mas para esta questão como exemplo, usarei um caso que destaca as vantagens de uma abordagem de tabela relacionada.
Imagine um exemplo de usuário e postagem para um blog.
Para uma solução de postagem incorporada, você teria uma tabela assim (psuedocódigo - provavelmente não são ddl válidos):
create table Users {
id int auto_increment,
name varchar(200)
post text[][],
}
Com tabelas relacionadas, você faria algo como
create table Users {
id int auto_increment,
name varchar(200)
}
create table Posts {
id auto_increment,
user_id int,
content text
}
Ferramentas de mapeamento relacional de objetos (ORM) :Com a postagem incorporada, você escreverá o código manualmente para adicionar postagens a um usuário, navegar pelas postagens existentes, validá-las, excluí-las etc. estão usando) ferramentas para isso que devem manter seu código muito mais simples.
Flexibilidade :imagine que você deseja adicionar um campo de data à postagem. Você pode fazer isso com um campo incorporado, mas terá que escrever código para analisar seu array, validar os campos, atualizar os posts incorporados existentes etc. Com a tabela separada, isso é muito mais simples. Além disso, digamos que você queira adicionar um Editor ao seu sistema que aprove todas as postagens. Com o exemplo relacional isso é fácil. Como exemplo para encontrar todos os posts editados por 'Bob' com ActiveRecord, você só precisaria:
Editor.where(name: 'Bob').posts
Para o lado incorporado, você teria que escrever código para percorrer todos os usuários no banco de dados, analisar cada uma de suas postagens e procurar 'Bob' no campo do editor.
Desempenho :Imagine que você tenha 10.000 usuários com uma média de 100 posts cada. Agora você quer encontrar todas as postagens feitas em uma determinada data. Com o campo incorporado, você deve percorrer todos os registros, analisar toda a matriz de todas as postagens, extrair as datas e verificar a desejada. Isso consumirá tanto a CPU quanto o disco i/0. Para o banco de dados, você pode indexar facilmente o campo de data e extrair os registros exatos necessários sem analisar todas as postagens de todos os usuários.
Padrões :Usar uma estrutura de dados específica do fornecedor significa que mover seu aplicativo para outro banco de dados pode ser uma dor de cabeça. Postgres parece ter um rico conjunto de tipos de dados, mas eles não são os mesmos que MySQL, Oracle, SQL Server etc. Se você ficar com os tipos de dados padrão, você terá muito mais facilidade para trocar os backends.
Estas são as principais questões que vejo fora do topo. Eu cometi esse erro e paguei o preço por isso, então, a menos que haja uma razão super convincente para fazer o contrário, eu usaria a tabela separada.