Pergunta

Meu empregador, uma pequena empresa de material de escritório, é mudar de fornecedor e eu estou olhando através de seu conteúdo eletrônico para chegar a um esquema de banco de dados robusto; nosso esquema anterior foi praticamente apenas jogado juntos, sem qualquer pensamento em tudo, e é praticamente levou a um modelo de dados insuportável com informações corrupto, inconsistente.

dados do novo fornecedor é muito melhor do que o antigo 's, mas seus dados é o que eu chamaria hypernormalized . Por exemplo, a sua estrutura de categoria de produto tem 5 níveis: Departamento Mestre, Departamento, classe, subclasse, Bloco de Produto. Além disso, o conteúdo do bloco produto tem a descrição longa, termos de pesquisa e nomes de imagem para os produtos (a idéia é que um bloco de produto contém um produto e todas as variações - por exemplo, um determinado caneta pode vir a tinta preta, azul ou vermelho; todos estes itens são essencialmente a mesma coisa, então eles aplicam-se a um bloco único produto). Nos dados que me foi dada, isso é expresso como a tabela de produtos (eu digo "mesa", mas é um arquivo simples com os dados) com uma referência a identificação única do bloco produto.

Eu estou tentando vir acima com um esquema robusto para acomodar os dados Estou fornecida, desde que eu vou ter de carregá-lo em relativamente pouco tempo, e que os dados que eles me deram não parece corresponder ao tipo de dados que eles fornecem para demonstração em seu site amostra ( http://www.iteminfo.com ). Em qualquer caso, eu não estou olhando para reutilizar sua estrutura de apresentação por isso é um ponto discutível, mas eu estava navegando no site para obter algumas idéias de como estruturar as coisas.

O que eu estou inseguro de se é ou não devo guardar os dados nesse formato, ou, por exemplo consolidar Master / Departamento / Classe / Subclasse em um único "Categorias" tabela, usando uma relação de auto-referência, e ligação que a um bloco de produto (bloco de produto deve ser mantido separado, uma vez que não é uma "categoria", como tal, mas um grupo de produtos de uma determinada categoria). Atualmente, as referências blocos produtos Quadro de subclasse, então isso mudaria a "category_id" se eu consolidá-los juntos.

Eu estou indo provavelmente ser a criação de uma loja de e-commerce fazendo uso de dados com Ruby on Rails (ou que é o meu plano, de qualquer modo), então eu estou tentando evitar ficar preso mais tarde ou ter uma aplicação inchado - talvez eu estou dando-lhe muito pensamento, mas eu prefiro prevenir do que remediar; nossos dados anteriores foi uma verdadeira bagunça e custar dezenas de empresas de milhares de dólares em vendas perdidas devido a dados inconsistentes e imprecisos. Também vou romper com as convenções de Rails um pouco por ter certeza de que meu banco de dados é robusta e impõe restrições (Estou pensando em fazê-lo no nível do aplicativo, também), de modo que é algo que eu preciso considerar também.

Como você enfrentar uma situação como esta? Tenha em mente que eu tenho os dados já estar carregado em arquivos simples que a estrutura da tabela um mímico (Eu documentação dizendo que colunas são o que e quais referências são criadas); Eu estou tentando decidir se eu deveria mantê-los como normalizado, dado que actualmente são, ou se eu deveria olhar para consolidar; Eu preciso estar ciente de como cada método irá afectar a forma como eu programar o site usando Rails, pois se eu consolidar, haverá essencialmente 4 "níveis" de categorias em uma única tabela, mas que definitivamente parece mais manejável do que tabelas separadas para cada nível, uma vez que para além de subclasse (que liga diretamente aos blocos produtos) eles não do qualquer coisa, exceto mostram o próximo nível de categoria sob eles. Eu estou sempre uma perda para o "melhor" maneira de dados punho como este - Eu sei do dizendo "Normalize até doer, então denormalize até que ele funciona", mas eu realmente nunca tive a implementá-lo até agora.

Foi útil?

Solução

Eu preferia a abordagem "hypernormalized" sobre um modelo de dados denormal. A tabela de auto referenciação você mencionou pode reduzir o número de mesas para baixo e vida Simplifique em alguns aspectos, mas em geral este tipo de relacionamento pode ser complicado de lidar. consultas hierárquicas se tornar uma dor, como faz o mapeamento de um modelo de objeto para isso (se você decidir ir por esse caminho).

Um par de extra de junta não vai doer e vai manter a aplicação mais sustentável. A menos que degrada o desempenho, devido ao número excessivo de junta, eu iria optar por deixar as coisas como elas são. Como um bônus adicional se qualquer um desses níveis de tabelas necessárias funcionalidade adicional acrescentado, você não vai ter problemas porque você fundiu-los todos em auto tabela de referência.

Outras dicas

Eu discordo totalmente com as críticas sobre estruturas de tabela de auto-referência para hierarquias pai-filho. A estrutura lista ligada faz UI e camada de negócios a programação mais fácil e mais sustentável na maioria dos casos, uma vez que listas ligadas e árvores são o caminho natural para representar esses dados em idiomas que a interface do usuário e as camadas de negócios normalmente seria implementado em.

As críticas sobre a dificuldade de manter as restrições de integridade de dados sobre estas estruturas é perfeitamente válido, embora a solução simples é usar uma mesa de encerramento que hospeda a restrições de verificação mais difíceis. A tabela de fechamento é de fácil manutenção com gatilhos.

A desvantagem é um pouco de complexidade extra no DB (tabela encerramento e gatilhos) por muito menos complexidade na interface do usuário e camada de negócios de código.

Se bem entendi, você quer tomar suas mesas separadas e transformá-los em uma hierarquia que é mantido em uma única tabela com uma auto-referência FK.

Esta é geralmente uma abordagem mais flexível (por exemplo, se você quiser adicionar um quinto nível), mas os modelos de dados SQL e relacionais tendem a não funcionar bem com listas ligadas como este, mesmo com a nova sintaxe como MS SQL Servidores CTEs. Reconhecidamente, CTEs torná-lo muito melhor embora.

Pode ser difícil e caro para impor coisas, como que um produto deve ser sempre no quarto nível da hierarquia, etc.

Se você decidir fazê-lo desta maneira, então definitivamente verificar para fora de Joe Celko SQL para Smarties , que eu acredito que tem uma seção ou dois na modelagem e trabalhar com hierarquias no SQL ou melhor ainda obter seu livro que é dedicado ao assunto ( Joe Celko árvores e hierarquias no SQL para Smarties ).

Normalization implica a integridade dos dados, ou seja:. Cada forma normal reduz o número de situações onde dados são inconsistentes

Como regra geral, denormalization tem uma meta de querying mais rápido, mas leva ao aumento do espaço, o aumento do tempo DML, e, por último mas não menos importante, o aumento dos esforços para tornar consistente de dados.

Um normalmente escreve código mais rápido (escreve mais rápido, não o código mais rápido) e o código é menos propenso a erros, se os dados são normalized.

Auto tabelas que fazem referência quase sempre acabam por ser muito pior para consulta e desempenho pior do que tabelas normalizadas. Não fazê-lo. Pode olhar para você ser mais elegante, mas não é e é uma técnica de design de banco de dados muito pobre. Pessoalmente a estrutura que você descreveu sons muito bem para mim não hypernormalized. Um banco de dados devidamente normalizada (com restrições de chave estrangeira, bem como os valores padrão, gatilhos (se necessários para regras complexas) e restrições de validação de dados) é também muito mais probabilidade de ter dados consistentes e precisas. Concordo em ter o banco de dados cumprir as regras, provavelmente, isso é parte da razão pela qual a última aplicação teve dados ruins porque as regras não foram aplicadas no lugar apropriado e as pessoas foram capazes de chegar facilmente ao seu redor. Não que a aplicação não deve verificar bem (nenhum ponto sequer enviar uma data inválida, por exemplo, para o datbase a falhar na inserção). Desde youa redesenho, gostaria de colocar mais tempo e esforço em projetar as restrições necessárias e escolhendo os tipos de dados corretos (não armazenar datas como dados de cadeia, por exemplo), do que na tentativa de fazer o olhar estrutura normalizada perfeitamente normal mais elegante.

Gostaria de trazê-lo tão perto do seu modelo como possível (e, se possível, gostaria de obter os arquivos que combinam com seu esquema - não uma versão achatada). Se você levar os dados diretamente em seu modelo, o que acontece se os dados que enviam começa a quebrar os pressupostos em que a transformação do modelo do seu aplicativo interno?

Melhor para trazer seus dados em, checagens executadas e verificar que os pressupostos não são violados. Então se você tem um modelo específico do aplicativo, transformá-lo em que para uma utilização optimizada pela sua aplicação.

Do not desnormalizar. Tentando para conseguir um bom design esquema por desnormalizar é como tentar chegar a San Francisco por condução de distância de Nova Iorque. Não lhe dizer qual caminho seguir.

Na sua situação, você quer descobrir o que um esquema normalizado gostaria. Você pode basear que em grande parte do esquema de origem, mas você precisa saber o que as dependências funcionais (FD) nos dados são. Nem o esquema de origem nem o achatada arquivos são garantidos para revelar todas as DFs para você.

Depois de saber que um esquema normalizado seria parecido, agora você precisa descobrir como criar um esquema que atenda às suas necessidades. É esse esquema é um pouco menos do que totalmente normalizada, que assim seja. Mas esteja preparado para as dificuldades na programação da transformação entre os dados nos arquivos achatados e os dados no seu esquema desgined.

Você disse que esquemas anteriores de seus milhões de custos da empresa devido a inconsistências e imprecisões. Quanto mais normalizada seu esquema é, mais protegido você é inconsistência interna. Isto deixa-o livre para ser mais vigilantes sobre imprecisão. dados consistentes que consistentemente errado pode ser tão enganosa como dados inconsistentes.

é sua loja (ou seja o que for que você está construindo, não muito claro sobre isso) sempre vai estar usando dados a partir deste fornecedor? pode você mudar fornecedores ou adicionar fornecedores adicionais diferentes?

Se for assim, projetar um esquema geral que atenda seus necessidades e mapear os dados de fornecedores para ele. Pessoalmente eu prefiro sofrer a (incrivelmente menor) 'dor' de uma tabela Categoria da auto-referência (hierárquica) do que manter quatro (aparentemente semi-inútil) níveis de Categoria variantes e, em seguida, no próximo ano descobrir eles adicionaram um quinto, ou introduziu uma linha de produtos com apenas três ...

Para mim, a verdadeira questão é:? o que se encaixa no modelo melhor

É como comparar um Tuple e uma lista.

  1. Tuples são um tamanho fixo e são heterogêneos - eles são "hypernormalized"
  2. .
  3. As listas são um tamanho arbitrarty e são homogêneos.

Eu uso um Tuple quando preciso de um Tuple e uma lista quando eu preciso de uma lista; eles servidor fundamentalmente diferentes fins.

Neste caso, uma vez que o estrutura do produto já está bem definido (e eu não assumir propensos a mudança), então eu iria ficar com a "abordagem Tuple". O verdadeiro poder / utilização de uma lista (ou padrão da tabela recursiva) é quando você precisa dele para expanda a uma profundidade arbitrária, como para uma lista de materiais ou uma árvore genealógica.

Eu uso ambas as abordagens em alguns dos meu banco de dados, dependendo da necessidade. No entanto, há também o "custo oculto" de um padrão recursiva que é que nem todos os ORMs (não tenho certeza sobre AR) apoiá-lo bem. Muitos bancos de dados modernos têm suporte para "Junte-se-through" (Oracle), IDs de hierarquia (SQL Server) ou outros padrões recursiva. Outra abordagem é a utilização de uma hierarquia de base de conjunto (o que geralmente se baseia em gatilhos / manutenção). Em qualquer caso, se o ORM utilizado não suporta consultas recursivas bem, então pode haver o "custo" extra de usar o para o DB apresenta diretamente - quer em termos de manual de consulta geração / fotografia ou de gestão, tais como gatilhos. Se você não usar um ORM funky, ou simplesmente usar um separador de lógica, como iBatis, em seguida, esta questão não pode mesmo aplicar.

Tanto quanto o desempenho, em novo Oracle ou SQL Server (e provavelmente outros) RDBMS, que deveria ser muito comparáveis ??de modo que seria a menor das minhas preocupações, mas confira as soluções disponíveis para as suas preocupações RDBMS e portabilidade.

Todo mundo que recomenda que você não tem uma hierarquia introduzido na base de dados, considerando-se apenas a opção de ter uma tabela de auto-referenciado. Esta não é a única maneira de modelar a hierarquia no banco de dados. Você pode usar uma abordagem diferente, que lhe proporciona mais fácil e rápida consulta sem o uso de consultas recursivas. Vamos dizer que você tem um grande conjunto de nós (categorias) na sua hierarquia:

Set1 = (Node1 Node2 Node3 ...)

Qualquer nó neste conjunto também pode ser outro conjunto por si só, que contém outros nós ou conjuntos aninhados:

= Nó1 (Nó2 Node3 = (node4 Node5 = (Node6) Node7))

Agora, como podemos modelar isso? Vamos ter cada nó ter dois atributos, que definem os limites dos nós que ele contém:

Node = {Id: int, Min: int, Max: int}

Para modelar nossa hierarquia, nós apenas atribuir esses valores min / max de acordo:

Node1 = {ID = 1, Min = 1, Max = 10}
Node2 = {Id = 2, Min = 2, Max = 2}
Node3 = {ID = 3, Min = 3, Max = 9}
Node4 = {ID = 4, Min = 4, Max = 4}
Node5 = {Id = 5, Min = 5, Max = 7}
Node6 = {Id = 6, Min = 6, Max = 6}
Node7 = {Id = 7, Min = 8, Max = 8}

Agora, para consultar todos os nós sob a Set / Node5:

selecione n. * From Nodes como n, Nodes como s
onde s.Id = 5 e s.Min

A única operação que consome recursos seria se você deseja inserir um novo nó, ou mover algum nó na hierarquia, como muitos registros serão afetados, mas isso é bom, como a hierarquia em si não muda muito frequentemente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top