Supertipo / subtipo que decide entre categoria: sobreposição total disjunta ou incompleta

11

Estou criando um banco de dados de inventário que armazena hardware de TI, como computadores desktop, laptops, comutadores, roteadores, telefones celulares, etc. Estou usando um padrão de supertipo / subtipo, onde todos os dispositivos são armazenados em uma única tabela e informações específicas é colocado em tabelas de subtipos. Meu dilema é escolher entre os dois modelos a seguir:

insira a descrição da imagem aqui

No diagrama superior, todos os dispositivos compartilham subtipos comuns. Por exemplo, computadores desktop e laptops teriam registros nas seguintes tabelas: Device, NetworkDevice. Um switch teria registros em: Device, NetworkDevice. Um roteador teria registros em: Device, NetworkDevice, WANDevice. Qualquer dispositivo para o qual rastreamos a localização terá um registro em Localização. Alguns prós e contras que eu pensei para esta configuração:

  • Pro: é mais fácil selecionar registros com base em um campo comum, como Hostname ou LocationID.
  • Pro: sem campos nulos.
  • Contras: As tabelas que devem ser incluídas nas operações CRUD para um dispositivo específico não são óbvias e podem confundir futuros DBAs.

No diagrama inferior, todos os dispositivos têm seu próprio subtipo (há mais classes de dispositivos que não são mostradas aqui). Nessa situação, é óbvio quais registros de tabelas são inseridos ou selecionados. Computadores de mesa e laptops entram em Computador, etc. Alguns prós e contras que eu pensei sobre esta configuração:

  • Pro: é imediatamente óbvio quais tabelas usar para operações CRUD para subtipos.
  • Pro: Somente é necessário usar uma tabela para operações CRUD.
  • Con: A seleção de registros com base em campos de subtipos comuns exige que todas as tabelas sejam combinadas, por exemplo, pesquisando por Nome do host ou ID da localização.

Nas duas situações, o campo ClassDiscriminator é colocado em tabelas de subtipos para uso com uma restrição CHECK para controlar quais tipos podem ser inseridos.

Existem recomendações para qual design é melhor ou é completamente uma questão de opinião e depende da finalidade do banco de dados?

Edição: Uma pergunta específica que tenho diz respeito à natureza sobreposta da tabela "NetworkDevice". Esta tabela deve conter informações de rede para qualquer dispositivo com um nome de host e / ou endereço IP, seja um computador, comutador ou roteador. A natureza sobreposta dessa tabela é algo que pode causar problemas ou é bom implementá-la dessa maneira?

Agradecemos antecipadamente por qualquer contribuição fornecida. Por favor, pergunte se alguma informação adicional é necessária.

TheSecretSquad
fonte
Veja dba.stackexchange.com/questions/15199/... para uma pergunta semelhante que foi respondido
Stephen Senkomago Musoke

Respostas:

15

A implementação física de subtipagem em um banco de dados é um problema complexo. A menos que você tenha uma situação em que ela ofereça vantagens atraentes (veja um ou dois exemplos abaixo), ela adiciona complexidade à implementação e fornece relativamente pouco valor.

Tendo feito isso com uma subtipagem realmente complexa (aplicativos e sentenças em um sistema de gerenciamento de processos judiciais, estruturas díspares de contratos de seguro comercial de risco combinado), acho que tenho algumas observações sobre isso. Alguns casos de canto significativos são:

  • Se o número total de campos do banco de dados nos subtipos for relativamente baixo (digamos: menor que 100) ou se houver uma semelhança significativa entre os subtipos, a divisão dos subtipos em tabelas físicas separadas provavelmente terá pouco valor. Isso adicionará uma sobrecarga significativa ao relatório de consultas e pesquisas. Na maioria dos casos, é melhor ter uma única tabela e gerenciar sua subtipagem no aplicativo. (Provavelmente o mais próximo do seu problema)

  • Se a sua subtipagem for muito disjunta e diferentes subtipos tiverem estruturas de dados dependentes do tipo penduradas nelas (por exemplo, tabelas filho ou estruturas mais complexas), as tabelas de subtipos farão sentido. Nesse caso, cada subtipo provavelmente possui relativamente pouca semelhança dentro do aplicativo (ou seja, provavelmente existe um subsistema inteiro dentro do aplicativo dedicado a esse subtipo). A maioria dos relatórios e consultas provavelmente ocorrerá dentro de um determinado subtipo, com consultas entre tipos principalmente restritas a um punhado de campos comuns. (Sistema de gestão de processos judiciais)

  • Se você tiver um grande número de subtipos com atributos díspares e / ou um requisito para tornar isso configurável, uma estrutura genérica e metadados suplementares podem ser mais apropriados. Veja esta publicação do SO para obter um resumo de algumas abordagens possíveis. (Sistema de administração da apólice de seguro)

  • Se você tiver um número muito grande de campos com pouca semelhança entre seus subtipos e pouco requisito para consultar tabelas de subtipos (ou seja, nada como junções externas de várias vias com suas tabelas de subtipos), sub- tabelas de tipos podem ajudar a gerenciar a expansão da coluna. (Versão patologicamente complexa do seu problema)

  • Alguns mapeadores de O / R podem suportar apenas uma abordagem específica para gerenciar subclasses.

Na maioria dos casos, as tabelas de subtipo físico em um esquema de banco de dados são uma solução para procurar um problema, pois elas podem ter efeitos colaterais indesejáveis.

No seu caso, suponho que você tenha um número relativamente modesto de subtipos e um número gerenciável de atributos. Seu diagrama e sua pergunta não indicam nenhuma intenção de suspender tabelas filho dos registros. Eu sugiro que você considere ir com a primeira opção sugerida acima e manter uma tabela e gerenciar a sub-digitação no seu aplicativo.

ConcernedOfTunbridgeWells
fonte
Obrigado pela sua resposta detalhada. Originalmente, eu queria manter tudo em uma tabela, mas determinados campos para dispositivos não se aplicam a outros e eu acabaria com vários campos nulos. Por exemplo, todos os registros de inventário teriam campos para o tipo de circuito e o provedor de serviços específicos dos roteadores. Todos os registros também teriam um campo de número de telefone que não faria sentido, a menos que o dispositivo fosse um telefone. Alguma sugestão sobre como lidar com isso?
TheSecretSquad
2
@reallythecrash - A sobrecarga para campos anuláveis ​​é de cerca de um byte por campo, portanto, em termos de uso de recursos, é muito menos sobrecarga do que a junção em tabelas de subclasses. Realmente, a única desvantagem é que a tabela ficará um pouco confusa com muitos valores nulos.
ConcernedOfTunbridgeWells
3
@reallythecrash - Se você realmente deseja (e seu DBMS o suporta - você não especificou o que está usando), pode configurar restrições de verificação com base no discriminador de tipos que aplica nulo / não nulo nos campos apropriados para o classe.
ConcernedOfTunbridgeWells
3

Considere primeiro desenvolver um modelo de dados lógicos sólido usando as regras de hierarquia de classificação de modelagem de dados encontradas no Enterprise Model Patterns , um livro de David Hay. Ao criar uma hierarquia de classificação, cada ocorrência (linha) deve ser de um e apenas um subtipo. Isso significa que os subtipos são mutuamente exclusivos. A classificação deve ser baseada em uma característica única, fundamental e imutável. O uso desta regra básica fornecerá muita clareza ao seu modelo. No modelo que você possui, a única característica a ser classificada é a finalidade do dispositivo - um telefone, um comutador de rede, um computador, um roteador etc. Cada dispositivo deve ser de um e apenas um desses tipos. Por exemplo, a localização não seria um subtipo. Atributos como endereço IP pertencem ao supertipo.

Acho que você descobrirá que o número de tipos de dispositivos será grande o suficiente para garantir um padrão EAV, como mencionado em outra resposta. O livro de David Hay a que me refiro cobre esse padrão com muita eficácia. No entanto, se o número de subtipos for pequeno, você pode usar uma regra geral para decidir implementar apenas uma tabela de supertipos com muitas colunas anuláveis, apenas tabelas de subtipos com colunas duplicadas ou ambas. Se cada subtipo variar muito em seus atributos e não tiver relacionamentos no nível supertipo, você poderá usar apenas tabelas de subtipo. Se o oposto for verdadeiro, você poderá usar apenas tabelas de supertipo. Se houver uma mistura, implemente as duas.

Finalmente, observe que você sempre pode implementar um padrão EAV como um esquema de tabela base e, em seguida, criar uma camada de abstração de exibição que apresenta os dados para o aplicativo como tabelas de super e subtipo. Isso oferece flexibilidade na camada de armazenamento, mas é compreensível na camada de visualização do aplicativo.

Todd Everett
fonte
Obrigado pela informação Todd. Uma das perguntas que tenho é sobre a tabela "Dispositivo de rede". Essa tabela destina-se a manter registros para qualquer dispositivo que tenha um nome de host e um endereço IP. Isso significa que todos os comutadores, computadores e roteadores teriam seus dados relacionados à rede armazenados nessa tabela. Pelo que tenho lido, isso é chamado de subtipo sobreposto, onde a tabela de subtipos contém dados relacionados para mais de um tipo. Você sabe se isso é algo que deve ser evitado ou se eu estou bem implementando dessa maneira?
TheSecretSquad:
Todd, em relação à sua afirmação "crie uma camada de abstração de exibição que apresente os dados para o aplicativo ...". Parece uma ótima ideia. Pensei em usar visualizações exatamente como você descreveu, mas tinha algumas perguntas sobre isso. Sei que não há problema em usar visualizações para consultar e exibir os dados no meu aplicativo, mas é prática comum usar visualizações para inserções e atualizações? Eu sei que existem algumas restrições sobre como suas consultas devem ser estruturadas (sem ordem por cláusula etc.) para inserir / atualizar usando uma exibição. Se a consulta estiver estruturada corretamente, é aconselhável usar a exibição para inserções e atualizações?
TheSecretSquad:
Na minha experiência, os subtipos sobrepostos confundem as coisas em um nível lógico, e é por isso que eu recomendo voltar a desenvolver um modelo lógico completo primeiro. Você pode usar o LDM para esclarecer o escopo e o entendimento antes de lidar com o armazenamento. No modelo atual apresentado, existe alguma confusão de entendimento entre a natureza fundamental de uma coisa - um dispositivo - e onde esse dispositivo vive no espaço. Esclareça isso no LDM. Evite também o subtipo sobreposto no banco de dados físico, a menos que você o esteja usando para particionar verticalmente as colunas, caso em que não está digitando nada.
21412 Todd Everett
Em relação à camada de abstração, você pode usar um gatilho "em vez de" para tornar uma visualização atualizável. As restrições que você menciona (sem ordem de entrada) são restrições na própria visualização do SQL e não no seu uso. Para inserir / atualizar, não há pedidos de qualquer maneira. Outras opções que você tem são escrever um módulo para lidar com os detalhes da inserção / atualização ou escrever um procedimento armazenado para lidar com isso. Não vejo problema em usar qualquer um desses métodos, pois o desempenho é aceitável. Para gravações de tipo singleton, tudo bem. Atualizações em massa podem ser um problema.
21412 Todd Everett
2

Um produto não é inventário. Inventário e produtos são distintos.

Um produto é realmente uma especificação de um produto, não uma coisa física.

O aspecto físico é um ativo que a empresa possui (ou armazena). Você pode ter ativos que você monitora por número de série (ativos discretos) ou ativos que você monitora apenas por quantidade (ativos de inventário).

Eu examinaria o Livro de Recursos do Modelo de Dados Vol. 1 de Silverston. Ele tem um bom esquema para orgulho, recursos, preços, estoque. Isso economizará muito tempo.

Neil McGuigan
fonte
1
+1 ponto por mencionar o Data Model Resource Book de Silverston. Deu uma olhada e foi esclarecedor. Ansioso para ler mais detalhadamente, como acho que qualquer pessoa com perguntas sobre modelagem de dados deveria. Obrigado.
TheSecretSquad
0

Uma das perguntas que eu faria é por que você está acompanhando os vários atributos de seus itens de inventário? - Ou, mais especificamente, o que você está fazendo com essas informações de atributo?

Se você possui muitos relatórios ou formulários que fazem sentido específico de atributos específicos, precisará usar a abordagem recomendada pelo ConcernedOfTunbridgeWell. Se, por outro lado, esses atributos estiverem sendo registrados com o objetivo de listá-los ou possivelmente compará-los com atributos semelhantes de dispositivos similares, você poderá realmente ter uma boa (rara) desculpa para usar o EAV. Sei que "o EAV é puro mal" por muitas razões, exceto em casos muito raros, em que essas razões não importam para um aplicativo específico. O seu pode ser esse aplicativo.

Dê uma olhada nesta resposta sobre o design de um sistema de inventário de dispositivos e esta resposta sobre o design de um sistema de catálogo de produtos para ver como uma abordagem EAV pode simplificar seu aplicativo, juntamente com uma discussão sobre exatamente quais são os riscos do EAV e como julgue se esses riscos podem não se aplicar ao seu aplicativo específico.

Joel Brown
fonte
Obrigdo por sua contribuição. Eu considerei o EAV, mas achei que poderia conseguir um modelo bom o suficiente sem precisar recorrer às complexidades envolvidas no EAV.
TheSecretSquad