database - français - Quand dois-je utiliser une relation un à un?



database-design relational-database (8)

Désolé pour cette question noob mais y a-t-il un besoin réel d'utiliser une relation one-to-one avec les tables de votre base de données? Vous pouvez implémenter tous les champs nécessaires dans une table. Même si les données deviennent très volumineuses, vous pouvez énumérer les noms de colonnes dont vous avez besoin dans l' SELECT au lieu d'utiliser SELECT * . Quand avez-vous vraiment besoin de cette séparation?

https://ffff65535.com


1 à 0..1

  • Le "1 à 0..1" entre super et sous-classes est utilisé comme une partie de la stratégie "toutes les classes dans des tables séparées" pour l' implémentation de l'héritage .

  • Un "1 à 0..1" peut être représenté dans une seule table avec la partie "0..1" couverte par des champs NULL-able. Toutefois, si la relation est principalement "1 à 0" avec seulement quelques lignes "1 à 1", la division de la partie "0..1" en une table séparée peut économiser des avantages de stockage (et de performances du cache). Certaines bases de données sont plus économes en stockage de valeurs nulles que d'autres, de sorte qu'un «point de coupure» où cette stratégie devient viable peut varier considérablement.

1 à 1

  • Le vrai "1 à 1" partitionne verticalement les données, ce qui peut avoir des implications pour la mise en cache. Les bases de données implémentent généralement des caches au niveau de la page, et non au niveau des champs individuels. Ainsi, même si vous ne sélectionnez que quelques champs d'une ligne, la page entière de cette ligne sera généralement mise en cache. Si une ligne est très large et que les champs sélectionnés sont relativement étroits, vous finirez par mettre en cache de nombreuses informations dont vous n'avez pas réellement besoin. Dans une situation comme celle-ci, il peut être utile de partitionner verticalement les données, de sorte que seules les portions plus étroites et plus fréquemment utilisées sont mises en cache, de sorte que plus d'entre elles peuvent entrer dans le cache.

  • Une autre utilisation du partitionnement vertical consiste à modifier le comportement de verrouillage: les bases de données ne peuvent généralement pas se verrouiller au niveau de champs individuels, uniquement les lignes entières. En divisant la ligne, vous permettez à un verrou d'avoir lieu sur une seule de ses moitiés.

  • Les déclencheurs sont généralement spécifiques à une table. Alors que vous pouvez théoriquement avoir une seule table et que le déclencheur ignore la "mauvaise moitié" de la ligne, certaines bases de données peuvent imposer des limites supplémentaires sur ce qu'un déclencheur peut et ne peut pas faire qui pourrait rendre cela impossible. Par exemple, Oracle ne vous permet pas de modifier la table de mutation - en ayant des tables séparées, une seule d'entre elles peut être en train de muter de sorte que vous pouvez toujours modifier l'autre à partir de votre déclencheur.

  • Des tables séparées peuvent permettre une sécurité plus granulaire.

Ces considérations ne sont pas pertinentes dans la plupart des cas. Dans la plupart des cas, vous devriez envisager de fusionner les tables "1 à 1" en une seule table.


Comme pour toutes les questions de conception, la réponse est "ça dépend".

Il y a peu de considérations:

  • quelle sera la taille de la table (à la fois en termes de champs et de lignes)? Il peut être gênant d'héberger le nom de votre utilisateur, mot de passe avec d'autres données moins couramment utilisées du point de vue de la maintenance et de la programmation.

  • les champs de la table combinée qui ont des contraintes pourraient devenir encombrants à gérer au fil du temps. Par exemple, si un déclencheur doit être activé pour un champ spécifique, cela se produira pour chaque mise à jour de la table, que ce champ ait été affecté ou non.

  • À quel point êtes-vous certain que la relation sera 1: 1? Comme This question le souligne, les choses peuvent se compliquer rapidement.


Je rencontre normalement deux types généraux de relation 1: 1 en pratique:

  1. Relations IS-A, également appelées relations supertype / sous-type. C'est quand un type d'entité est en réalité un type d'une autre entité (EntityA IS A EntityB). Exemples:

    • Entité personne, avec des entités distinctes pour comptable, ingénieur, commercial, au sein de la même entreprise.
    • Entité item, avec des entités séparées pour Widget, RawMaterial, FinishedGood, etc.
    • Entité de voiture, avec des entités séparées pour le camion, la berline, etc.

    Dans toutes ces situations, l'entité supertype (par exemple Personne, Article ou Voiture) aurait les attributs communs à tous les sous-types, et les entités du sous-type auraient des attributs uniques à chaque sous-type. La clé primaire du sous-type serait la même que celle du supertype.

  2. Relations "Boss". C'est quand une personne est le patron unique ou le gestionnaire ou le superviseur d'une unité organisationnelle (département, entreprise, etc.). Lorsqu'il n'y a qu'un seul patron autorisé pour une unité organisationnelle, il existe une relation 1: 1 entre l'entité personne qui représente le boss et l'entité unité organisationnelle.


Le moment le plus sensé pour utiliser ceci serait s'il y avait deux concepts séparés qui ne se rapporteraient jamais de cette manière. Par exemple, une voiture ne peut avoir qu'un seul conducteur actuel, et le conducteur ne peut conduire qu'une voiture à la fois - donc la relation entre les concepts de voiture et de conducteur serait de 1 à 1. Je reconnais que c'est un exemple inventé pour démontrer le point.

Une autre raison est que vous voulez spécialiser un concept de différentes manières. Si vous avez une table Person et que vous souhaitez ajouter le concept de différents types de personnes, tels que Employee, Customer, Shareholder, chacun d'entre eux nécessiterait différents ensembles de données. Les données qui sont similaires entre eux seraient sur la table Person, les informations spécialisées seraient sur les tables spécifiques pour Customer, Shareholder, Employee.

Certains moteurs de base de données ont du mal à ajouter efficacement une nouvelle colonne à une très grande table (plusieurs lignes) et j'ai vu des tables d'extension utilisées pour contenir la nouvelle colonne, plutôt que la nouvelle colonne ajoutée à la table d'origine. C'est l'une des utilisations les plus suspectes des tables supplémentaires.

Vous pouvez également décider de diviser les données d'un même concept entre deux tables différentes pour des problèmes de performance ou de lisibilité, mais ceci est un cas relativement spécial si vous partez de rien - ces problèmes apparaîtront plus tard.


Premièrement, je pense qu'il s'agit de modéliser et de définir ce que constitue une entité distincte. Supposons que vous ayez des customers avec une seule et unique address . Bien sûr, vous pouvez tout implémenter dans un seul customer , mais si, à l'avenir, vous lui permettez d'avoir 2 adresses ou plus, vous devrez le refactoriser (pas de problème, mais prenez une décision consciente).

Je peux aussi penser à un cas intéressant qui n'est pas mentionné dans d'autres réponses où le fractionnement de la table pourrait être utile:

Imaginez, encore une fois, que vous ayez des customers avec une seule address chacun, mais cette fois-ci, il est facultatif d'avoir une adresse. Bien sûr, vous pouvez l'implémenter comme un tas de colonnes NULL -able telles que ZIP,state,street . Mais supposons que, étant donné que vous avez une adresse, l'état n'est pas facultatif, mais le ZIP est. Comment modéliser cela dans une seule table? Vous pouvez utiliser une contrainte sur la table customer , mais il est beaucoup plus facile de la diviser dans une autre table et de rendre le paramètre foreign_key NULLable. Ainsi, votre modèle est beaucoup plus explicite en disant que l' address l' entité est facultative et que le ZIP est un attribut optionnel de cette entité.


Si les données d'une table sont liées à l'entité décrite par l'autre, mais ne «appartiennent» pas à celle-ci, il est possible de la conserver séparément.

Cela pourrait fournir des avantages à l'avenir, si les données séparées doivent également être liées à une autre entité.


Un autre cas d'utilisation peut être le suivant: vous pouvez importer des données d'une source et les mettre à jour quotidiennement, par exemple des informations sur les livres. Ensuite, vous ajoutez vous-même des données sur certains livres. Il est alors logique de placer les données importées dans une autre table que vos propres données.


Vous parlez de la normalisation de la base de données. Un exemple que je peux penser dans une application que je maintiens est des articles. L'application permet à l'utilisateur de vendre différents types d'articles (InventoryItems, NonInventoryItems, ServiceItems, etc ...). Bien que je puisse stocker tous les champs requis par chaque élément dans une table Items, il est beaucoup plus facile à maintenir d'avoir une table Item de base qui contient des champs communs à tous les items et des tables séparées pour chaque type d'item (Inventory, NonInventory, etc ..) qui contiennent des champs spécifiques à ce seul type d'élément. Ensuite, la table d'éléments aurait une clé étrangère au type d'élément spécifique qu'elle représente. La relation entre les tables d'éléments spécifiques et la table d'éléments de base serait un à un.

Ci-dessous, un article sur la normalisation.

http://support.microsoft.com/kb/283878





relational-database