Essa é uma maneira ridícula de estruturar um esquema de banco de dados, ou estou completamente perdendo alguma coisa?

61

Eu fiz um bom trabalho com bancos de dados relacionais e acho que entendo muito bem os conceitos básicos do bom design de esquema. Recentemente, fui encarregado de assumir um projeto em que o DB foi projetado por um consultor altamente remunerado. Por favor, deixe-me saber se minha intuição intimidar - "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 para 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 da seguinte forma:

Tabela de usuários:

UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department

Tabela de solicitações

RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table

Simples, certo?

O consultor projetou assim (com dados de amostra):

UsersTable

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

DepartmentsTable

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

O banco de dados inteiro é construído dessa forma, com cada parte dos dados encapsulados em sua própria tabela, com IDs numéricos ligando tudo juntos. Aparentemente, o consultor leu sobre o OLAP e queria a 'velocidade de pesquisas inteiras'

Ele também possui um grande número de procedimentos armazenados para fazer referência cruzada a todas essas tabelas.

Este design é válido para um SQL DB de tamanho pequeno a médio?

Obrigado por comentários / respostas ...

    
por Jim 29.09.2011 / 18:45
fonte

6 respostas

72

Faz todo o sentido para mim. É muito normalizado, o que dá muita flexibilidade que você não teria de outra forma. Dados desnormalizados são uma dor na bunda.

    
por 29.09.2011 / 18:52
fonte
48

Eu não acho que uma WTF seja garantida ou que o cara esteja fazendo algum tipo de design genial - é uma normalização de banco de dados bastante padrão.

A razão para a tabela de departamento é que, se você não colocar os departamentos em uma tabela separada, terá que lidar com os usuários em "Vendas", "vendas", "Vendedores", "Velas" e "Venda". "departamentos, a menos que você faça algo para evitar isso. E ter a tabela extra é (parte de) a melhor maneira que eu conheço para fazer isso.

Se deve haver uma tabela UserDepartment é uma chamada mais difícil, o que obviamente significa que nem a decisão está fora e é louca. Por um lado, é uma dor quando todo o design e a lógica da tabela assumiram um departamento por usuário e depois isso muda; por outro lado, fazer uma junção extra sem nenhuma razão por anos e anos é uma possibilidade real e também uma dor. / p>

Eu pessoalmente 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, assim você terá o pior dos dois mundos - uma junção extra sem nenhum motivo antes de precisar da tabela e código não funciona de qualquer maneira, mais de um departamento por usuário se torna permitido.

EDIT - Um dos principais impulsionadores de se o relacionamento muitos para muitos deve ser suportado é se as regras de negócios são claras. Se você não tem ideia de como um usuário em vários departamentos trabalharia, não há muito sentido em adicionar a tabela, já que seu código não pode manipular corretamente 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. Em seguida, 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 visão de escrever seu código de comissão de uma maneira que levasse isso em conta. Infelizmente, você adicionou as comissões de cada departamento para usuários em ambos. A gerência queria que você se baseasse na função de pessoas para cada venda. Então, quanto bem ter a mesa adiantada? E quanto às outras tabelas que você tinha "apenas no caso" que nunca são necessárias?

EDITAR MAIS TARDE - Outra razão pela qual o consultor pode ter desejado adicionar todas essas tabelas intermediárias é abordada em esta 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 refatorar o código, o que tenderia a empurrá-lo para o" put " em todas as tabelas que você pode precisar "abordagem".

    
por 29.09.2011 / 19:13
fonte
14

Se o requisito é ter vários departamentos por usuário, esse design faz sentido. A única reclamação sobre isso é a UserDepartmentTable ter uma chave substituta UserDepartmentID que não é necessária (basta criar a% UserId e DepartmentId uma chave primária composta).

Se um usuário pertencer apenas a um único departamento, seu design fará sentido (embora uma tabela de pesquisa de departamento ainda seja uma boa coisa).

    
por 29.09.2011 / 18:50
fonte
5

Alguns requisitos não estão claros em sua pergunta. A resposta correta depende do que seu cliente quer - Se eu fosse você, perguntaria ao cliente sobre isso:

0-Qual é a diferença entre um usuário e um funcionário?

1-Assumindo um funcionário = usuário, e se um funcionário mudar de departamento?

2-Pode um grupo de funcionários fazer 1 pedido?

3-Poderia um funcionário pertencer a mais de um departamento? E o CEO

4-Existe um subgrupo de funcionários autorizados a fazer solicitações?

5-O que acontece com a solicitação quando um registro de funcionário é excluído (se alguma vez)?

6-Você pode excluir uma solicitação? O que acontece quando a solicitação é eliminada (certifique-se de não excluir o registro de funcionário pelo RI)

7-O funcionário pode fazer a mesma solicitação mais de uma vez (defina o "mesmo")

8-Como lidar com solicitações de funcionários quando eles deixam a empresa (cancelar suas solicitações ou excluir as solicitações?)

Pode haver mais perguntas, mas meu ponto é que a solução depende de requisitos exatos e do escopo do projeto. Uma vez determinado, o esquema pode ser derivado diretamente. Assim, ambas as soluções apresentadas podem estar corretas.

    
por 30.09.2011 / 01:36
fonte
1

Gostaria de adicionar algumas anotações do formulário de ponto falando explicitamente sobre algumas das vantagens potenciais de usar uma tabela de associação da maneira que seu consultor altamente remunerado fez.

  • Corretamente indexado (por exemplo, se UserDepartmentTable indexar as duas chaves estrangeiras), há apenas uma pequena perda de desempenho de uma tabela de junção como essa, devido às chaves estrangeiras não serem exclusivas. Se as chaves estrangeiras são garantidas como únicas, pela pequena teoria de banco de dados que eu conheço, olhar para cima UserDepartmentTable.Department não é "mais difícil" do que procurar qualquer outra coluna na tabela User .
  • A tabela de junção oferece mais flexibilidade para configurar outras informações sobre a associação entre o usuário e o departamento (por exemplo, registros de data e hora na criação).
  • A tabela de junção permite que você "modifique" a associação com bastante facilidade (por exemplo, quando um usuário altera departamentos, aciona um sinalizador booleano de índice como UserDepartmentTable.Active para false e cria uma nova associação ativa). Também é possível ter versões de associação de departamento com o modelo de duas tabelas (apenas Usuário e Departamento), mas é mais difícil e precisa adicionar pelo menos mais uma coluna ou fazer acrobacias de banco de dados para evitar a duplicação de chaves primárias.
  • Permite que você atribua associações de um para muitos ou de muitos para um ou muitos para muitos com bastante facilidade.

Dito isto, há várias razões para NÃO fazer o que seu consultor altamente remunerado fez.

  • Todos os benefícios acima são todos antecipatórios de possíveis necessidades futuras, supercomplicando as coisas para os dias atuais. Não é compatível com YAGNI. É uma dificuldade trivial depois escrever uma migração que se move do modelo de duas tabelas para um modelo de tabela de junção. Você pode fazer isso quando a necessidade do negócio surgir. Fazer isso antes disso pode ser confuso.
  • Confunde outros desenvolvedores. Embora, sim, eu diria que a expectativa de um desenvolvedor web de sua estatura (onde você está revisando as decisões dos consultores) seria entender e reconhecer uma tabela de associação, ainda é mais complicada do que o necessário e considerando a falta de necessidade de negócios, isso causa confusão.
por 30.09.2011 / 16:04
fonte
0

Sem estrutura completa de informações necessárias, não posso dizer que é terrível ou não. Mas pelo menos a peça mostrada não é de desenhos "WTF". Parece apenas como a 3ª Forma Normal da estrutura de dados (bem, temos teoricamente também 4ª e 5ª também)

Algumas conversas podem ter lugar para UserDepartmentTable entre duas escolas de teclas "naturais" e "artificiais" na peça mostrada. Nada mais, como eu posso ver

A normalização é a regra do bom desenvolvedor de banco de dados / designer por várias razões, * de * normalizações são usadas às vezes no meio de desenvolvimentos para velocidade máxima principalmente

    
por 30.09.2011 / 15:12
fonte