Elimine a tabela de junção em relacionamentos HasMany no Rails
-
21-09-2019 - |
Pergunta
Estou pensando em maneiras de criar um sistema de controle de acesso baseado em funções no Rails.Também vi esses grandes projetos (entre outros):
Minha pergunta é: é realmente necessário ter uma tabela de junção para tudo?Se uma das tabelas no relacionamento tiver apenas alguns valores (digamos, menos de 100), não posso simplesmente mesclar a tabela de junção com aquela tabela pequena?) É isso que quero dizer...Aqui está o que eu preciso:
Modelos
- Do utilizador
- Grupo
- Papel
- Permissão
- UserRoles/RolesUsers
- Funções do grupo
- Associações (GroupUsers)
- Permissões de função
Algo parecido...
O caminho Requisito de Função funciona é criando um roles
mesa e um roles_users
juntar-se à mesa.Isso significa que se eu tiver um total de 20 funções possíveis em um aplicativo, tenho
- Tabela de funções com 20 linhas
- Tabela RolesUsers com n linhas.
O que significa que toda vez que quero encontrar um usuário por função, preciso fazer uma associação.Estou me perguntando, já que haverá apenas algumas funções em um aplicativo, por que não substituir esta migração:
create_table "roles", :force => true do |t|
t.string "name"
end
create_table "roles_users", :id => false, :force => true do |t|
t.integer "role_id"
t.integer "user_id"
end
com este...
create_table "roles", :force => true do |t|
t.string "name"
t.integer "user_id" # or some polymorphic form
end
Isso causaria duplicação (toneladas de funções chamadas "admin", por exemplo), mas como o espaço é barato, poderíamos criar um método como Role.unique
para encontrar todas as funções exclusivas (para se livrar daquela tabela de 20 linhas), por que as pessoas criam a tabela de junção?
A mesma coisa com permissões:Provavelmente terei apenas 4 permissões para iniciar: create read update delete
.Portanto, não preciso de uma tabela de permissões e de uma tabela role_permissions, poderia apenas duplicar as permissões CRUD e ter o role_id na tabela de permissões.O mesmo acontece com o Grupo, não preciso de funções de grupo se tiver colunas polimórficas em meu roles
mesa.
Qual é a maneira recomendada de fazer isso?
Aqui está um trecho da migração proposta.
Solução
Eu não sugeriria que você fizesse isso.O que você descreve é chamado desnormalização.
A desnormalização introduz problemas para muitas aplicações e só deve ser feita se você tiver uma ideia clara precisar por isso.Normalmente desnormalizo tabelas apenas para fins de relatórios.
Sua pergunta não mostra que você precisa desnormalizar.Em vez disso, mostra uma aversão equivocada a ter tabelas "extras" e a evitar uma simples junção.Ter dados duplicados custa mais do que apenas espaço, mas também custa desempenho (exclusivo não é um brinde).Os RDBMS modernos são bastante hábeis no tratamento de junções.
Eu sugiro pesquisar no Google e pesquisar no SO informações sobre desnormalização.Não existe uma regra de ouro, mas o seu caso não parece ter uma boa razão para isso.
Se você está procurando ganhos de desempenho, jogue o ActiveRecord no lixo.Existem muitas alternativas e você pode escrever a sua própria.