web-dev-qa-db-fra.com

Quand devrais-je utiliser une relation à un?

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

68

1 à 0..1

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

  • Un "1 à 0..1" peut être représenté dans une seule table avec la portion "0..1" couverte par des champs NULL. Toutefois, si la relation est généralement "1 à 0" avec seulement quelques lignes "1 à 1", la division de la partie "0..1" dans une table séparée peut économiser de la mémoire (et performances du cache) avantages. Certaines bases de données stockent des valeurs NULL plus économes que d’autres, de sorte qu’un point de rupture 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 les caches au niveau de la page, pas au niveau des champs individuels. Ainsi, même si vous ne sélectionnez que quelques champs dans une ligne, la page entière à laquelle appartient cette ligne sera 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 beaucoup d'informations dont vous n'avez pas réellement besoin. Dans une telle situation, il peut être utile de partitionner verticalement les données pour que uniquement la partie ou les lignes les plus étroites et les plus fréquemment utilisées soient mises en cache afin qu'un plus grand nombre d'entre elles puissent être insérées dans le cache, rendant ainsi le cache efficace "plus grand".

  • 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 des champs individuels, mais uniquement des lignes entières. En scindant la ligne, vous autorisez le verrouillage sur une seule de ses moitiés.

  • Les déclencheurs sont aussi généralement spécifiques à une table. Bien que vous puissiez 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 à ce qu'un déclencheur peut faire ou ne peut pas faire, ce qui pourrait rendre ceci impossible. Par exemple, Oracle ne vous permet pas de modifier la table en mutation - en ayant des tables séparées, une seule d'entre elles peut être en mutation, 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, vous devez donc envisager de fusionner les tableaux "1 à 1" en un seul tableau.

82

Si les données d'une table sont liées à, mais n'appartiennent pas à l'entité décrite par l'autre, il est alors possible de les séparer.

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

15
Sepster

Si vous placez deux tables un à un en une, il est probable que vous aurez un problème de sémantique. Par exemple, si chaque périphérique possède une télécommande, il ne semble pas très judicieux de placer le périphérique et la télécommande avec leurs caractéristiques dans un seul tableau. Vous devrez peut-être même passer du temps à déterminer si un certain attribut appartient au périphérique ou à la télécommande.

Il peut arriver que la moitié de vos colonnes reste vide ou ne soit jamais renseignée. Par exemple, une voiture peut avoir une remorque présentant de nombreuses caractéristiques ou n'en avoir aucune. Donc, vous aurez beaucoup d'attributs inutilisés.

Si votre table a 20 attributs et que seulement 4 d’entre eux sont utilisés occasionnellement, il est judicieux de diviser la table en 2 tables pour les problèmes de performances. 

Dans de tels cas, il n'est pas bon de tout avoir dans une seule table. De plus, ce n'est pas facile de traiter avec une table à 45 colonnes!

11
superM

Mes 2 centimes.

Je travaille dans un endroit où nous développons tous une grande application, et tout est un module. Par exemple, nous avons une table users, et nous avons un module qui ajoute les détails Facebook pour un utilisateur, un autre module qui ajoute les détails Twitter à un utilisateur. Nous pourrions décider de débrancher l'un de ces modules et de retirer toutes ses fonctionnalités de notre application. Dans ce cas, chaque module ajoute sa propre table avec des relations 1: 1 à la table globale users, comme ceci:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)
10
santiago arizti

Le moment le plus judicieux pour l'utiliser serait s'il y avait deux concepts distincts qui ne concerneraient jamais que de cette façon. Par exemple, une voiture ne peut avoir qu'un seul conducteur actuel, et le conducteur ne peut conduire qu'une voiture à la fois - la relation entre les concepts de voiture et de conducteur est donc de 1 à 1. J'accepte qu'il s'agit d'un exemple artificiel permettant de démontrer la point.

Une autre raison est que vous souhaitez spécialiser un concept de différentes manières. Si vous avez une table Personne et souhaitez ajouter le concept de différents types de Personne, tels que Employé, Client et Actionnaire, chacun d'entre eux nécessitera des ensembles de données différents. Les données similaires entre celles-ci se trouveraient dans la table Personne, les informations des spécialistes se trouveraient dans les tables spécifiques Client, Actionnaire, Employé.

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 il s'agit d'un cas assez particulier si vous partez de zéro - ces problèmes se manifesteront plus tard.

9
Fenton

pas très souvent.

vous pouvez trouver un avantage si vous devez implémenter une sécurité - ainsi, certains utilisateurs peuvent voir certaines des colonnes (table1) mais pas les autres (table2).

bien sûr, certaines bases de données (Oracle) vous permettent de faire ce type de sécurité dans la même table, mais d'autres non.

5
Randy

Vous faites référence à la normalisation de la base de données. Un exemple auquel je peux penser dans une application que je gère est Eléments. L’application permet à l’utilisateur de vendre de nombreux types d’articles différents (c’est-à-dire InventoryItems, NonInventoryItems, ServiceItems, etc.). Même si je pouvais stocker tous les champs requis par chaque article dans une seule table d’articles, il est beaucoup plus facile de conserver une table d’articles de base contenant des champs communs à tous les articles, puis des tableaux séparés pour chaque type d’article (par exemple, inventaire, non inventaire, etc ..) qui contiennent des champs spécifiques à ce type d'élément uniquement. Ensuite, la table d'éléments aurait une clé étrangère pour le type d'élément spécifique qu'elle représente. La relation entre les tables de postes spécifiques et la table de postes de base serait un à un.

Ci-dessous, un article sur la normalisation.

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

4
Grasshopper

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

Il y a peu de considérations: 

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

  • les champs de la table combinée qui ont des contraintes peuvent devenir difficiles à gérer avec le 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 soit affecté ou non. 

  • à quel point êtes-vous certain que la relation sera de 1: 1? Comme Cette question souligne, les choses peuvent devenir compliquées rapidement. 

3
Rob Allen

Un autre cas d'utilisation peut être le suivant: vous pouvez importer des données provenant d'une source et les mettre à jour quotidiennement, par exemple. 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.

3
Dirk

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

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

    • Entité personnelle, avec des entités distinctes pour le comptable, l'ingénieur et le vendeur au sein de la même entreprise.
    • Entité d'article, avec des entités séparées pour Widget, RawMaterial, FinishedGood, etc.
    • Entité automobile, avec entités distinctes pour camion, berline, etc.

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

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

2
Tripartio

À l'époque de ma programmation, je ne l'ai rencontré que dans un cas. C'est-à-dire lorsqu'il existe une relation 1-à-plusieurs et 1-à-1 entre les 2 mêmes entités ("Entité A" et "Entité B").

Lorsque "l'Entité A" a plusieurs "Entités B" et que "l'Entité B" a seulement 1 "Entité A" Et "L'entité A" n'a que 1 "Entité B" en cours et "l'Entité B" en a seulement 1 "Entité A".

Par exemple, une voiture ne peut avoir qu'un seul pilote actuel, et le pilote ne peut conduire qu'une voiture à la fois - la relation entre les concepts de voiture et de conducteur est donc de 1 à 1. - J'ai emprunté cet exemple à la réponse de Steve Fenton

Où un pilote peut conduire plusieurs voitures, mais pas au même moment. Ainsi, les entités voiture et conducteur sont un à plusieurs ou plusieurs à plusieurs. Mais si nous avons besoin de savoir qui est le pilote actuel, nous avons également besoin de la relation 1 à 1.

0
Jo Smo

Premièrement, je pense qu’il s’agit d’une question de modélisation et de définition de ce qui constitue une entité séparée. Supposons que vous ayez customers avec un et un seul address. Bien sûr, vous pouvez tout implémenter dans une seule table customer, mais si, à l’avenir, vous lui permettez d’avoir deux adresses ou plus, vous devrez alors le reformuler (pas un problème, mais prenez une décision consciente).

Je peux aussi penser à un cas intéressant, non mentionné dans d'autres réponses, où la scission du tableau pourrait être utile:

Imaginez, encore une fois, que vous avez customers avec un seul address chacun, mais cette fois, il est facultatif d’avoir une adresse. Bien sûr, vous pouvez implémenter cela comme un groupe de colonnes NULL- variable telles que Zip,state,street. Mais supposons que, étant donné que vous ayez 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 en une autre table et de rendre la foreign_key NULLable. De cette manière, votre modèle est beaucoup plus explicite en indiquant que entity address est optionnel et que Zip est un attribut optionnel de cette entité.

0
polvoazul

Un autre cas d'utilisation pourrait être si le nombre maximal de colonnes dans la table de base de données est dépassé. Ensuite, vous pourriez rejoindre une autre table en utilisant OneToOne

0
db303