Quand devrais-je utiliser une relation individuelle?

92

Désolé pour cette question noob, mais y a-t-il un réel besoin 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 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' SELECTinstruction au lieu d'utiliser SELECT *. Quand avez-vous vraiment besoin de cette séparation?

Pavel Shchegolevatykh
la source

Réponses:

105

1 à 0..1

  • Le "1 à 0..1" entre les super et sous-classes est utilisé dans le cadre 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 une partie "0..1" couverte par des champs NULL. Cependant, si la relation est principalement "1 à 0" avec seulement quelques lignes "1 à 1", la division de la partie "0..1" dans une table séparée peut économiser certains avantages de stockage (et de performances du cache). Certaines bases de données sont plus économes en stockage de NULL que d'autres, donc 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, pas au niveau des champs individuels, donc même si vous ne sélectionnez que quelques champs d'une ligne, la page entière à laquelle appartient la ligne sera généralement mise en cache. Si une ligne est très large et les champs sélectionnés relativement étroits, vous finirez par mettre en cache beaucoup d'informations dont vous n'avez pas réellement besoin. Dans une situation comme celle-là, il peut être utile de partitionner verticalement les données, de sorte que seule la partie ou les lignes les plus étroites et les plus fréquemment utilisées soient mises en cache, afin que davantage d'entre elles puissent tenir dans le cache, ce qui rend le cache effectivement "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, uniquement les lignes entières. En divisant la rangée, vous autorisez un verrouillage sur une seule de ses moitiés.

  • Les déclencheurs sont également généralement spécifiques à la table. Bien que vous ne puissiez théoriquement avoir qu'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 irréalisable. 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 afin que vous puissiez toujours modifier l'autre à partir de votre déclencheur.

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

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

Branko Dimitrijevic
la source
20

Si les données d'une table sont liées à, mais n'appartiennent pas à l'entité décrite par l'autre, alors c'est un candidat pour les garder séparées.

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

Sepster
la source
19

Si vous placez deux tables un-à-un dans une, il est probable que vous ayez un problème de sémantique. Par exemple, si chaque appareil a une télécommande, il ne semble pas très bon de placer l'appareil 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 à l'appareil ou à la télécommande.

Il peut y avoir des cas où la moitié de vos colonnes resteront vides pendant un long moment ou ne seront jamais remplies. Par exemple, une voiture peut avoir une remorque avec un ensemble de caractéristiques ou n'en avoir aucune. Vous aurez donc de nombreux attributs inutilisés.

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

Dans de tels cas, il n'est pas bon d'avoir tout dans une seule table. De plus, il n'est pas facile de gérer un tableau de 45 colonnes!

superM
la source
17

Mes 2 cents.

Je travaille dans un endroit où nous développons tous dans une grande application, et tout est un module. Par exemple, nous avons une userstable, et nous avons un module qui ajoute des détails facebook pour un utilisateur, un autre module qui ajoute des détails Twitter à un utilisateur. Nous pourrions décider de débrancher l'un de ces modules et de supprimer toutes ses fonctionnalités de notre application. Dans ce cas, chaque module ajoute sa propre table avec des relations 1: 1 à la userstable globale , 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 ...)
santiago arizti
la source
13

Le moment le plus judicieux pour l'utiliser serait s'il y avait deux concepts distincts qui ne seraient jamais liés que de cette manière. Par exemple, une voiture ne peut avoir qu'un seul conducteur actuel, et le conducteur ne peut conduire qu'une seule voiture à la fois - la relation entre les concepts de voiture et de conducteur serait donc de 1 à 1. J'accepte que cet exemple soit artificiel pour démontrer le point.

Une autre raison est que vous souhaitez spécialiser un concept de différentes manières. Si vous avez une table Personne et que vous souhaitez ajouter le concept de différents types de personne, tels que Employé, Client, Actionnaire - chacun d'entre eux nécessiterait différents ensembles de données. Les données similaires entre eux seraient sur la table Personne, les informations spécialisées seraient sur les tables spécifiques pour le client, l'actionnaire, l'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 étant 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 performances ou de lisibilité, mais c'est un cas raisonnablement spécial si vous partez de zéro - ces problèmes se manifesteront plus tard.

Fenton
la source
5

pas très souvent.

vous pouvez trouver un avantage si vous devez implémenter une certaine sécurité - ainsi certains utilisateurs peuvent voir certaines des colonnes (table1) mais pas d'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.

Excité
la source
5

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 Items. L'application permet à l'utilisateur de vendre de nombreux types d'articles différents (ie InventoryItems, NonInventoryItems, ServiceItems, etc ...). Bien que je puisse stocker tous les champs requis par chaque article dans une table Articles, il est beaucoup plus facile de maintenir une table Item de base qui contient des champs communs à tous les articles, puis des tables séparées pour chaque type d'article (c.-à-d. Inventaire, Non Inventaire, etc.) qui contiennent des champs spécifiques uniquement à ce type d'élément. Ensuite, la table d'éléments aurait une clé étrangère vers le 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

Sauterelle
la source
3

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

Il y a quelques 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 et le mot de passe de vos utilisateurs avec d'autres données moins couramment utilisées à la fois du point de vue de la maintenance et 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 se déclencher pour un champ spécifique, cela se produira pour chaque mise à jour de la table, que ce champ ait été affecté ou non.

  • Dans quelle mesure êtes-vous certain que la relation sera 1: 1? Comme le souligne cette question, les choses peuvent se compliquer rapidement.

Rob Allen
la source
3

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

Poignard
la source
2

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

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

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

    Dans toutes ces situations, l'entité de supertype (par exemple, personne, article ou voiture) aurait les attributs communs à tous les sous-types, et les entités de 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 «patron». C'est lorsqu'une personne est l'unique patron ou gestionnaire ou superviseur d'une unité organisationnelle (service, 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 patron et l'entité d'unité organisationnelle.

Tripartio
la source
1
J'aime le deuxième exemple. Vous pouvez avoir l'entité «Service» et l'entité «Employé». Dans un service, vous avez de nombreux employés et un employé ne peut travailler que dans un seul service. C'est 1: n. Un employé peut être superviseur d'un département - d'un seul département, et le département n'a qu'un seul superviseur. Vous vous retrouvez donc avec deux tables connectées avec deux relations - 1: n et 1: 1.
cezar
2

Premièrement, je pense que c'est une question de modélisation et de définition de ce qui consiste en une entité distincte. Supposons que vous ayez customersun seul et unique address. Bien sûr, vous pouvez tout mettre en œuvre dans une seule table customer, mais si, à l'avenir, vous lui permettez d'avoir 2 adresses ou plus, vous devrez alors refactoriser cela (pas de problème, mais prendre une décision consciente).

Je peux également penser à un cas intéressant non mentionné dans d'autres réponses où le fractionnement du tableau pourrait être utile:

Imaginez, encore une fois, que vous en ayez customersavec un seul addresschacun, mais cette fois, il est facultatif d'avoir une adresse. Bien sûr, vous pouvez l'implémenter sous forme de NULLcolonnes -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 l'est. Comment modéliser cela dans un seul tableau? Vous pouvez utiliser une contrainte sur la customertable, mais il est beaucoup plus facile de la diviser dans une autre table et de rendre la clé étrangère NULLable. De cette façon, votre modèle est beaucoup plus explicite en disant que l' entité address est facultative et que le ZIPest un attribut facultatif de cette entité.

polvoazul
la source
0

Pendant mon temps de programmation, je n'ai rencontré cela que dans une situation. C'est-à-dire lorsqu'il existe une relation 1 à plusieurs et une relation 1 à 1 entre les deux mêmes entités («Entité A» et «Entité B»).

Lorsque "Entité A" a plusieurs "Entité B" et "Entité B" a seulement 1 "Entité A" et "Entité A" a seulement 1 "Entité B" actuelle et "Entité B" a seulement 1 "Entité A".

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 serait donc de 1 à 1. - J'ai emprunté cet exemple à la réponse de @Steve Fenton

Où un conducteur peut conduire plusieurs voitures, mais pas en même temps. Les entités Car et Driver sont donc 1-à-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.

Jo Smo
la source
0

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

db303
la source