6
votes

Conception de la base de données: objets avec différents attributs

Je concevons une base de données de produits où les produits peuvent avoir des attributs très différents selon leur type, mais les attributs sont fixes pour chaque type et types ne sont pas gérables du tout. E.g.:

Magazine: strong> Titre, Numéro de norme, pages, copies, proximité_date, version_date de
web_site: strong> nom, bande passante, hits, date_from, date_to p>

Je souhaite utiliser InnoDB et appliquer l'intégrité de la base de données autant que le moteur le permet. Quelle est la façon recommandée de gérer cela? P>

Je déteste ces conceptions où des tables ont 100 colonnes et la plupart des valeurs sont NULL, donc j'ai pensé à quelque chose comme ceci: P>

product_type
============

product_type_id INT
product_type_name VARCHAR

product
=======

product_id INT
product_name VARCHAR
product_type_id INT -> Foreign key to product_type.product_type_id
valid_since DATETIME
valid_to DATETIME

magazine
========

magazine_id INT
title VARCHAR
product_id INT -> Foreign key to product.product_id
issue_number INT
pages INT
copies INT
close_date DATETIME
release_date DATETIME

web_site
========

web_site_id INT
name VARCHAR
product_id INT -> Foreign key to product.product_id
bandwidth INT
hits INT
date_from DATETIME
date_to DATETIME


0 commentaires

3 Réponses :


2
votes

Vous semblez être grossièrement sur la bonne voie, sauf que vous devrez peut-être envisager la différence entre «un produit» et ce qui s'appelait souvent «une unité de stockage» (SKU). Est-ce qu'une boîte à 25 unités de clips en papier (d'un certain type spécifique) le même "produit" comme une boîte de 50 unités de 50 unités? En termes de magasin, ou tout type de système d'inventaire, la distinction compte; Dans certains cas, en effet, une simple distinction dans l'emballage de ce qui est autrement la même quantité du même "produit" sous-jacent peut vous donner des skus distincts pour garder une trace de.

Vous devez décider où vous souhaitez suivre ce problème, si cela compte pour votre candidature (il se peut que vous puissiez avoir les produits disposés à mesure que vous le faites et gérer les emballages à des fins SKU dans d'autres tables, pour exemple, même si pour certaines applications qui pourraient être une légère surcharge).


0 commentaires

1
votes

Ceci en fait un moyen standard de "appliquer" une sorte de conception OO dans un SGDBR classique.

Tous les attributs "communs" vont sur la table principale (par exemple, s'il est manipulé au niveau de la table du produit, cela pourrait facilement faire partie de la table principale) tandis que les spécificités vont sur une sous-carte.

En théorie Si vous avez des sous-sous-types (par exemple, des magazines pourraient être sous-traités dans des journaux quotidiens et des périodiques à 4 couleurs, peut-être, avec des périodiques ayant un intervalle de date pour la durée de vie), vous pouvez également ajouter une ou plusieurs sublons. ..

C'est une conception assez courante (et éprouvée). La seule préoccupation est que la table principale sera toujours jointe avec au moins une sous-carte pour la plupart des opérations. Si vous avez des zillions d'articles, cela pourrait avoir des implications de performance.

D'autre part, des opérations communes telles que la suppression d'un élément (je suggérerais une suppression logique, définir un drapeau sur "True" sur la table principale) serait effectué une fois pour chaque type de sous-type.

Quoi qu'il en soit, allez-y. Et peut-être sur Google pour "objet orienté sur des mappages de RDBMS" ou somesuch pour une discussion complète < / strong> .


0 commentaires

6
votes

Il s'agit d'une conception de OO classique à une incidence sur les tables relationnelles. La conception de la table que vous avez décrite est appelée «table par sous-classe». Les trois modèles les plus courants sont tous des compromis par rapport à ce que vos objets ressemblent réellement dans votre application:

  1. table par classe de béton li>
  2. table par hiérarchie li>
  3. table par sous-classe li> ol>

    La conception que vous n'aimez pas - "Où les tables ont 100 colonnes et la plupart des valeurs sont NULL" - est 2. une table pour stocker toute la hiérarchie de spécialisation. Ceci est le moins flexible pour toutes sortes de raisons, y compris - si votre application nécessite une nouvelle sous-classe, vous devez ajouter des colonnes. La conception que vous décrivez les capacités Changez beaucoup mieux car vous pouvez l'ajouter en ajoutant un nouveau tableau de sous-classe décrit par une valeur de produit_type. P>

    L'option restante - 1. Table par classe de béton - est généralement indésirable En raison de la duplication impliquée dans la mise en œuvre de tous les champs courants de chaque tableau de spécialisation. Bien que les avantages soient que vous n'aurez pas besoin d'effectuer des jointures et que les tables de sous-classe peuvent même être sur différentes instances de DB dans un très grand système. P>

    La conception que vous avez décrite est parfaitement viable. La variation ci-dessous est la façon dont il pourrait ressembler si vous utilisiez un outil ORM pour effectuer vos opérations de CRUD. Notez comment l'ID dans chaque table de sous-classe est la valeur FK à la table des parents de la hiérarchie. Un bon orme gérera automatiquement le CRUD de table de sous-classe correct basé sur la valeur des valeurs discriminator dans le produit.Id et produit.Product_type_id seul. Si vous envisagez d'utiliser une orje ou non, consultez la documentation de sous-classe jointe de Hibernate, si seulement pour voir les décisions de conception, elles ont formulé. P>

    product
    =======
    
    id INT
    product_name VARCHAR
    product_type_id INT -> Foreign key to product_type.product_type_id
    valid_since DATETIME
    valid_to DATETIME
    
    magazine
    ========
    
    id INT -> Foreign key to product.product_id
    title VARCHAR
    ..
    
    web_site
    ========
    
    id INT -> Foreign key to product.product_id INT
    name VARCHAR
    ..
    


1 commentaires

Nice aperçu de trois designs possibles, merci. Toutes les réponses étaient excellentes mais je ne peux que choisir un <: -)