Eu trabalhei bastante com bancos de dados relacionais e acho que entendo muito bem os conceitos básicos de bom design de esquema. Recentemente, fui encarregado de assumir um projeto em que o DB foi projetado por um consultor altamente pago. Por favor, deixe-me saber se meu intestino intacto - "WTF ??!?" - é garantido, ou esse cara é um gênio que está operando fora do meu reino?
O DB em questão é um aplicativo interno usado para inserir solicitações de funcionários. Apenas olhando uma pequena seção, você tem informações sobre os usuários e informações sobre a solicitação que está sendo feita. Eu projetaria isso assim:
Tabela do usuário:
UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department
Tabela de solicitação
RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table
Simples, certo?
O consultor o projetou assim (com dados de amostra):
UsersTable
UserID FirstName LastName
234 John Doe
516 Jane Doe
123 Foo Bar
Departamentos
DepartmentID Name
1 Sales
2 HR
3 IT
UserDepartmentTable
UserDepartmentID UserID Department
1 234 2
2 516 2
3 123 1
RequestTable
RequestID UserID <...>
1 516 blah
2 516 blah
3 234 blah
Todo o banco de dados é construído assim, com todos os dados encapsulados em sua própria tabela, com IDs numéricos vinculando tudo. Aparentemente, o consultor havia lido sobre OLAP e queria a "velocidade das pesquisas de números inteiros"
Ele também possui um grande número de procedimentos armazenados para fazer referência cruzada a todas essas tabelas.
Esse design é válido para um banco de dados SQL de pequeno a médio porte?
Obrigado por comentários / respostas ...
Respostas:
Faz todo o sentido para mim. É apenas muito normalizado, o que confere muita flexibilidade que você não teria de outra maneira. Dados não normalizados são uma dor no traseiro.
fonte
Eu não acho que um WTF seja garantido ou que o cara esteja desenvolvendo algum tipo de design genial - é uma normalização de banco de dados bastante padrão.
O motivo da tabela de departamentos é que, se você não colocar os departamentos em uma tabela separada, precisará lidar com os usuários nos departamentos "Vendas", "Vendas", "Vendedores", "Velas" e "Venda", a menos que você faça algo para evitá-lo. E ter uma mesa extra é (parte de) a melhor maneira que sei fazer isso.
Se deve haver uma tabela UserDepartment é uma decisão mais difícil, o que obviamente significa que nenhuma das decisões é exagerada. Por um lado, é uma dor quando todo o design e a lógica de sua mesa assumiram um departamento por usuário e isso muda, por outro lado, fazer uma junção extra sem motivo por anos e anos é uma possibilidade real e também uma dor.
Pessoalmente, eu concordo com você que a tabela UserDepartment provavelmente é um exagero. Mesmo se incluído, as chances são de que, com o tempo, as pessoas escrevam consultas que pressupõem que haja apenas um usuário por departamento, para que você acabe com o pior dos dois mundos - uma junção extra sem motivo antes de precisar da tabela, e código não funciona de qualquer maneira, uma vez que mais de um departamento por usuário é permitido.
EDIT - Um fator importante para saber se o relacionamento entre muitos e muitos deve ser suportado é se as regras de negócios são claras. Se você não tem idéia de como um usuário em vários departamentos funcionaria, não faz muito sentido adicionar a tabela, pois seu código não pode lidar corretamente com os casos em que um usuário está em vários departamentos.
Imagine que você permitiu muitos departamentos por usuário, apenas por precaução. Você implementou uma regra de negócios para atribuir comissões, com base no departamento. Em seguida, vários departamentos foram permitidos. Felizmente, você também teve a previsão de escrever seu código de comissão de uma maneira que levasse isso em consideração. Infelizmente, você adicionou as comissões de cada departamento para usuários de ambos. A gerência queria que você baseasse na função de pessoas para cada venda. Então, quanto de bom era ter a mesa com antecedência? E as outras tabelas que você tinha "apenas por precaução" que nunca são necessárias?
EDIÇÃO MAIS TARDE - Outro motivo pelo qual o consultor pode querer adicionar todas essas tabelas intermediárias é abordado nesta pergunta de acompanhamento , cujas respostas dão algumas razões pelas quais a refatoração de um banco de dados é geralmente mais difícil do que o código de refatoração, o que tenderia a empurrá-lo para a abordagem "coloque todas as tabelas que você possa precisar".
fonte
Se o requisito é ter vários departamentos por usuário, esse design faz sentido. A única reclamação sobre isso é
UserDepartmentTable
ter uma chave substitutaUserDepartmentID
que não é necessária (basta criar a chave primária compostaUserId
eDepartmentId
).Se um usuário pertencer apenas a um único departamento, seu design fará sentido (embora uma tabela de pesquisa de departamento ainda seja uma coisa boa).
fonte
Alguns requisitos não estão claros na sua pergunta. A resposta correta depende do que seu cliente deseja - se eu fosse você, perguntaria ao cliente sobre isso:
0-Qual é a diferença entre um usuário e um funcionário?
1-Supondo que um funcionário = usuário, e se um funcionário mudar de departamento?
2-Um grupo de funcionários pode fazer 1 solicitação?
3-Um funcionário poderia pertencer a mais de um departamento? E o CEO
4-Existe um subconjunto de funcionários com permissão para fazer solicitações?
5-O que acontece com a solicitação quando um registro de funcionário é excluído (se houver)?
6-Você pode excluir uma solicitação? O que acontece quando a solicitação é excluída (certifique-se de não excluir o registro do funcionário pelo RI)
7-O funcionário pode fazer o "mesmo" pedido mais de uma vez (definir o "mesmo")
8-Como lidar com solicitações de funcionários quando elas saem da empresa (cancelar suas solicitações ou excluir as solicitações?)
Pode haver mais perguntas, mas o que quero dizer é que a solução depende dos requisitos exatos e do escopo do projeto. Uma vez determinado, o esquema pode ser derivado diretamente. Por conseguinte, ambas as soluções apresentadas podem estar corretas.
fonte
Eu gostaria de acrescentar algumas notas do formulário falando explicitamente sobre algumas das vantagens potenciais de usar uma tabela de junção da maneira que seu consultor altamente pago fez.
UserDepartmentTable.Department
não é "mais difícil" do que procurar qualquer outra coluna naUser
tabela.UserDepartmentTable.Active
falso e cria uma nova associação que está ativa). Também é possível ter versões de associação de departamentos com o modelo de duas tabelas (apenas Usuário e Departamento), mas é mais difícil e requer a adição de pelo menos mais uma coluna ou acrobacias no banco de dados para evitar a duplicação de chaves primárias.Dito isto, há várias razões para NÃO fazer o que seu consultor altamente pago fez.
fonte
Sem a estrutura completa das informações necessárias, não posso dizer que seja terrível ou não. Mas pelo menos a peça mostrada não é do tipo "WTF". Parece que é a terceira forma normal de estrutura de dados (bem, teoricamente também temos a quarta e a quinta)
Algumas conversas podem ter lugar para UserDepartmentTable entre duas escolas de chaves "naturais" e "artificiais" na peça mostrada. Nada mais, como posso ver
A normalização é uma regra do bom desenvolvedor / desenvolvedor de banco de dados por várias razões, * de * normalizações são usadas algumas vezes no meio dos desenvolvimentos para ganhar velocidade principalmente
fonte