Je pensais l'autre jour à la normalisation, et il m'est venu à l'esprit que je ne peux pas penser à un moment où il devrait y avoir une relation 1: 1 dans une base de données.
Name:SSN
? Je les aurais dans la même table.PersonID:AddressID
? Encore une fois, même tableau.
Je peux proposer des millions d'exemples de 1: beaucoup ou beaucoup: beaucoup (avec des tables intermédiaires appropriées), mais jamais un 1: 1.
Est-ce que je rate quelque chose d'évident?
Réponses:
Une relation 1: 1 indique généralement que vous avez partitionné une entité plus grande pour une raison quelconque. Cela est souvent dû à des raisons de performances dans le schéma physique, mais cela peut également se produire du côté logique si une grande partie des données est censée être "inconnue" en même temps (auquel cas vous avez un 1: 0 ou 1: 1, mais pas plus).
À titre d'exemple de partition logique: vous avez des données sur un employé, mais il y a un plus grand ensemble de données qui doit être collecté, si et seulement si ils choisissent d'avoir une couverture santé. Je conserverais les données démographiques concernant la couverture santé dans un tableau différent à la fois pour faciliter le partitionnement de la sécurité et pour éviter de transporter ces données dans des requêtes sans rapport avec l'assurance.
Un exemple de partition physique serait les mêmes données hébergées sur plusieurs serveurs. Je peux conserver les données démographiques de la couverture santé dans un autre état (où se trouve le bureau des ressources humaines, par exemple) et la base de données principale ne peut y être liée que via un serveur lié ... en évitant de répliquer des données sensibles vers d'autres emplacements, tout en les rendant disponibles pour (en supposant ici rares) les requêtes qui en ont besoin.
Le partitionnement physique peut être utile chaque fois que vous avez des requêtes qui nécessitent des sous-ensembles cohérents d'une entité plus grande.
la source
L'une des raisons est l'efficacité de la base de données. Avoir une relation 1: 1 vous permet de fractionner les champs qui seront affectés lors d'un verrouillage de ligne / table. Si la table A a une tonne de mises à jour et la table b a une tonne de lectures (ou a une tonne de mises à jour d'une autre application), alors le verrouillage de la table A n'affectera pas ce qui se passe dans la table B.
D'autres soulèvent un bon point. La sécurité peut également être une bonne raison en fonction de la façon dont les applications, etc. arrivent sur le système. J'aurais tendance à adopter une approche différente, mais cela peut être un moyen facile de restreindre l'accès à certaines données. Il est vraiment facile de refuser l'accès à une certaine table à la rigueur.
Mon article de blog à ce sujet.
la source
La parcimonie. La relation de données peut être techniquement 1: 1, mais les lignes correspondantes ne doivent pas nécessairement exister pour chaque ligne. Ainsi, si vous avez vingt millions de lignes et qu'il existe un ensemble de valeurs qui n'existe que pour 0,5% d'entre elles, les économies d'espace sont considérables si vous poussez ces colonnes dans une table qui peut être peu peuplée.
la source
La plupart des réponses les mieux classées donnent des raisons de réglage et d'optimisation de base de données très utiles pour les relations 1: 1, mais je ne veux me concentrer que sur des exemples «dans la nature» où les relations 1: 1 se produisent naturellement.
Veuillez noter une caractéristique importante de la mise en œuvre de la base de données de la plupart de ces exemples: aucune information historique n'est conservée sur la relation 1: 1. Autrement dit, ces relations sont 1: 1 à un moment donné. Si le concepteur de la base de données souhaite enregistrer les modifications des participants de la relation au fil du temps, les relations deviennent 1: M ou M: M; ils perdent leur nature 1: 1. Avec cela compris, voici:
Relations "Is-A" ou supertype / sous-type ou héritage / classification: Cette catégorie se produit lorsqu'une entité est un type spécifique d'une autre entité. Par exemple, il pourrait y avoir une entité Employé avec des attributs qui s'appliquent à tous les employés, puis différentes entités pour indiquer des types spécifiques d'employés avec des attributs uniques à ce type d'employé, par exemple Docteur, Comptable, Pilote, etc. Cette conception évite plusieurs valeurs nulles puisque de nombreux employés n'auraient pas les attributs spécialisés d'un sous-type spécifique. D'autres exemples dans cette catégorie pourraient être Produit en tant que supertype et FabricationProduit et MaintenanceSupply en tant que sous-types; Animal comme supertype et chien et chat comme sous-types; etc. Notez que chaque fois que vous essayez de mapper une hiérarchie d'héritage orientée objet dans une base de données relationnelle (comme dans un modèle relationnel objet), c'est le type de relation qui représente de tels scénarios.
Les relations de «patron» , telles que le directeur, le président, le président, etc., où une unité organisationnelle ne peut avoir qu'un seul patron et une personne ne peut être le patron que d'une unité organisationnelle. Si ces règles s'appliquent, alors vous avez une relation 1: 1, comme un responsable d'un département, un PDG d'une entreprise, etc. Les relations «patron» ne s'appliquent pas seulement aux personnes. Le même type de relation se produit s'il n'y a qu'un seul magasin comme siège d'une entreprise, ou si une seule ville est la capitale d'un pays, par exemple.
Certains types d'allocation de ressources rares , par exemple, un employé ne peut se voir attribuer qu'une seule voiture de société à la fois (par exemple, un camion par camionneur, un taxi par chauffeur de taxi, etc.). Un collègue m'a donné cet exemple récemment.
Mariage (au moins dans les juridictions légales où la polygamie est illégale): une personne ne peut être mariée qu'à une seule autre personne à la fois. J'ai tiré cet exemple d'un manuel qui l'utilisait comme exemple d'une relation unaire 1: 1 lorsqu'une entreprise enregistre les mariages entre ses employés.
Réservations correspondantes : lorsqu'une réservation unique est effectuée puis exécutée en tant que deux entités distinctes Par exemple, un système de location de voitures peut enregistrer une réservation dans une entité, puis une location réelle dans une entité distincte. Bien qu'une telle situation puisse également être conçue comme une seule entité, il pourrait être judicieux de séparer les entités car toutes les réserves ne sont pas satisfaites et toutes les locations ne nécessitent pas de réservations, et les deux situations sont très courantes.
Je répète la mise en garde que j'ai faite précédemment, à savoir que la plupart de ces relations sont des relations 1: 1 uniquement si aucune information historique n'est enregistrée. Ainsi, si un employé change de rôle dans une organisation, ou si un gestionnaire prend la responsabilité d'un autre service, ou si un employé se voit réaffecter un véhicule, ou si quelqu'un est veuf et se remarie, les participants à la relation peuvent changer. Si la base de données ne stocke aucun historique sur ces relations 1: 1, elles restent des relations 1: 1 légitimes. Mais si la base de données enregistre des informations historiques (telles que l'ajout de dates de début et de fin pour chaque relation), elles se transforment presque toutes en relations M: M.
Il existe deux exceptions notables à la note historique: Premièrement, certaines relations changent si rarement que les informations historiques ne seraient normalement pas stockées. Par exemple, la plupart des relations IS-A (par exemple, type de produit) sont immuables; c'est-à-dire qu'ils ne peuvent jamais changer. Ainsi, le point d'enregistrement historique est sans objet; ceux-ci seraient toujours mis en œuvre sous forme de relations naturelles 1: 1. Deuxièmement, la relation réservation-location stocke les dates séparément, puisque la réservation et la location sont des événements indépendants, chacun avec ses propres dates. Étant donné que les entités ont leurs propres dates, plutôt que la relation 1: 1 elle-même ayant une date de début, celles-ci resteraient en tant que relations 1: 1 même si les informations historiques sont stockées.
la source
Votre question peut être interprétée de plusieurs façons, en raison de la façon dont vous l'avez formulée. Les réponses le montrent.
Il peut certainement y avoir des relations 1: 1 entre les éléments de données dans le monde réel. Aucune question à ce sujet. La relation «est un» est généralement un à un. Une voiture est un véhicule. Une voiture est un véhicule. Un véhicule peut être une voiture. Certains véhicules sont des camions, auquel cas un véhicule n'est pas une voiture. Plusieurs réponses abordent cette interprétation.
Mais je pense que ce que vous demandez vraiment, c'est ... quand des relations 1: 1 existent, les tables devraient-elles être divisées? En d'autres termes, devriez-vous avoir deux tables contenant exactement les mêmes clés? En pratique, la plupart d'entre nous n'analysent que les clés primaires, et non les autres clés candidates, mais cette question est légèrement différente.
Les règles de normalisation pour 1NF, 2NF et 3NF ne nécessitent jamais de décomposer (fractionner) une table en deux tables avec la même clé primaire. Je n'ai pas déterminé si mettre un schéma dans BCNF, 4NF ou 5NF peut jamais aboutir à deux tables avec les mêmes clés. Du haut de ma tête, je vais deviner que la réponse est non.
Il existe un niveau de normalisation appelé 6NF. La règle de normalisation pour 6NF peut certainement résulter en deux tables avec la même clé primaire. 6NF a l'avantage par rapport au 5NF que NULLS peut être complètement évité. Ceci est important pour certains concepteurs de bases de données, mais pas tous. Je n'ai jamais pris la peine de mettre un schéma dans 6NF.
Dans 6NF, les données manquantes peuvent être représentées par une ligne omise, au lieu d'une ligne avec un NULL dans une colonne.
Il existe des raisons autres que la normalisation pour la division des tables. Parfois, les tables fractionnées améliorent les performances. Avec certains moteurs de base de données, vous pouvez obtenir les mêmes avantages en termes de performances en partitionnant la table au lieu de la fractionner. Cela peut avoir l'avantage de garder la conception logique facile à comprendre, tout en donnant au moteur de base de données les outils nécessaires pour accélérer les choses.
la source
Je les utilise principalement pour plusieurs raisons. L'un est une différence significative dans le taux de changement des données. Certaines de mes tables peuvent avoir des pistes d'audit dans lesquelles je traque les versions précédentes des enregistrements, si je souhaite uniquement suivre les versions précédentes de 5 colonnes sur 10, diviser ces 5 colonnes sur une table séparée avec un mécanisme de piste d'audit est plus efficace. En outre, je peux avoir des enregistrements (par exemple pour une application de comptabilité) qui sont uniquement en écriture. Vous ne pouvez pas modifier les montants en dollars, ou le compte pour lequel ils étaient, si vous avez fait une erreur, vous devez créer un enregistrement correspondant pour radier l'ajustement de l'enregistrement incorrect, puis créer une écriture de correction. J'ai des contraintes sur la table qui renforcent le fait qu'elles ne peuvent pas être mises à jour ou supprimées, mais je peux avoir quelques attributs pour cet objet qui sont malléables, ceux-ci sont conservés dans un tableau séparé sans restriction de modification. Une autre fois, je fais cela dans les demandes de dossier médical. Il existe des données relatives à une visite qui ne peuvent pas être modifiées une fois qu'elle est déconnectée, et d'autres données liées à une visite qui peuvent être modifiées après la validation. Dans ce cas, je diviserai les données et placerai un déclencheur sur la table verrouillée rejetant les mises à jour de la table verrouillée une fois déconnectée, mais autorisant les mises à jour des données que le médecin ne valide pas.
Une autre affiche a commenté le 1: 1 n'étant pas normalisé, je ne serais pas d'accord avec cela dans certaines situations, en particulier le sous-typage. Disons que j'ai une table d'employés et que la clé primaire est leur SSN (c'est un exemple, sauvegardons le débat sur la question de savoir si c'est une bonne clé ou non pour un autre thread). Les employés peuvent être de différents types, par exemple temporaires ou permanents et s'ils sont permanents, ils ont plus de champs à remplir, comme le numéro de téléphone du bureau, qui ne devrait être nul que si le type = 'Permanent'. Dans une base de données de 3e forme normale, la colonne ne doit dépendre que de la clé, c'est-à-dire de l'employé, mais elle dépend en fait de l'employé et du type, donc une relation 1: 1 est parfaitement normale et souhaitable dans ce cas. Cela évite également les tableaux trop clairsemés, si j'ai 10 colonnes qui sont normalement remplies,
la source
Le scénario le plus courant auquel je puisse penser est celui où vous avez des BLOB. Supposons que vous souhaitiez stocker de grandes images dans une base de données (généralement, ce n'est pas la meilleure façon de les stocker, mais parfois les contraintes le rendent plus pratique). Vous souhaiterez généralement que l'objet blob se trouve dans une table distincte pour améliorer les recherches des données non blob.
la source
En termes de science pure, oui, ils sont inutiles.
Dans les bases de données réelles, il est parfois utile de conserver un champ rarement utilisé dans une table séparée: pour accélérer les requêtes en utilisant ce champ et uniquement ce champ; pour éviter les verrous, etc.
la source
Plutôt que d'utiliser des vues pour restreindre l'accès aux champs, il est parfois judicieux de conserver les champs restreints dans une table séparée à laquelle seuls certains utilisateurs ont accès.
la source
Je peux également penser à des situations où vous avez un modèle OO dans lequel vous utilisez l'héritage, et l'arbre d'héritage doit être conservé dans la base de données.
Par exemple, vous avez une classe Bird et Fish qui héritent tous deux d'Animal. Dans votre base de données, vous pouvez avoir une table `` Animal '', qui contient les champs communs de la classe Animal, et la table Animal a une relation un à un avec la table Bird et une relation un à un avec le poisson table.
Dans ce cas, vous n'avez pas besoin d'avoir une table Animal qui contient beaucoup de colonnes Nullable pour contenir les propriétés Bird et Fish, où toutes les colonnes contenant Fish-data sont définies sur NULL lorsque l'enregistrement représente un oiseau.
Au lieu de cela, vous avez un enregistrement dans la table Birds qui a une relation un à un avec l'enregistrement dans la table Animal.
la source
Les relations 1-1 sont également nécessaires si vous avez trop d'informations. Il existe une limite de taille d'enregistrement pour chaque enregistrement du tableau. Parfois, les tables sont divisées en deux (avec les informations les plus fréquemment demandées dans la table principale) juste pour que la taille de l'enregistrement ne soit pas trop grande. Les bases de données sont également plus efficaces pour interroger si les tables sont étroites.
la source
C'est aussi un moyen d'étendre une table qui est déjà en production avec moins de risque (perçu) qu'un changement de base de données "réel". Voir une relation 1: 1 dans un ancien système est souvent un bon indicateur que des champs ont été ajoutés après la conception initiale.
la source
En SQL, il est impossible d'imposer une relation 1: 1 entre deux tables qui est obligatoire des deux côtés (sauf si les tables sont en lecture seule). Dans la plupart des cas, une relation «1: 1» en SQL signifie en réalité 1: 0 | 1.
L'incapacité à prendre en charge la cardinalité obligatoire dans les contraintes référentielles est l'une des sérieuses limitations de SQL. Les contraintes «reportables» ne comptent pas vraiment parce qu'elles ne sont qu'une façon de dire que la contrainte n'est pas appliquée de temps en temps.
la source
Si vous utilisez les données avec l'un des ORM populaires, vous souhaiterez peut-être diviser une table en plusieurs tables pour correspondre à votre hiérarchie d'objets.
la source
J'ai découvert que lorsque je fais une relation 1: 1, c'est totalement pour une raison systémique, pas une raison relationnelle.
Par exemple, j'ai trouvé que mettre les aspects réservés d'un utilisateur dans une table et placer les champs modifiables par l'utilisateur dans une table différente permet d'écrire logiquement ces règles sur les autorisations sur ces champs beaucoup plus facilement.
Mais vous avez raison, en théorie, les relations 1: 1 sont complètement artificielles et sont presque un phénomène. Cependant, logiquement, cela permet aux programmes et aux optimisations d'abstraire la base de données plus facilement.
la source
La plupart du temps, on pense que les dessins sont 1: 1 jusqu'à ce que quelqu'un demande «bien, pourquoi ne peut-il pas être 1: plusieurs»? Le divorce prématuré des concepts les uns des autres se fait en prévision de ce scénario commun. Personne et adresse ne sont pas si étroitement liés. Beaucoup de gens ont plusieurs adresses. Etc...
Habituellement, deux espaces objets séparés impliquent que l'un ou les deux peuvent être multipliés (x: plusieurs). Si deux objets étaient vraiment, vraiment 1: 1, même philosophiquement, alors c'est plus une relation est. Ces deux "objets" sont en fait des parties d'un objet entier.
la source
informations étendues qui ne sont nécessaires que dans certains scénarios. dans les applications héritées et les langages de programmation (tels que RPG) où les programmes sont compilés sur les tables (donc si la table change, vous devez recompiler le ou les programmes). Les fichiers de balises peuvent également être utiles dans les cas où vous devez vous soucier de la taille de la table.
la source
Le plus souvent, il s'agit plus d'une construction physique que logique. Il est couramment utilisé pour partitionner verticalement une table pour tirer parti de la division des E / S sur des périphériques physiques ou d'autres optimisations de requête associées à la séparation des données moins fréquemment consultées ou des données qui doivent être conservées plus sécurisées que le reste des attributs sur le même objet (SSN, salaire, etc.).
La seule considération logique qui prescrit une relation 1-1 est lorsque certains attributs ne s'appliquent qu'à certaines des entités. Cependant, dans la plupart des cas, il existe un moyen meilleur / plus normalisé de modéliser les données via l'extraction d'entités.
la source
La meilleure raison que je peux voir pour une relation 1: 1 est un sous-type SuperType de conception de base de données. J'ai créé une structure de données Real Estate MLS basée sur ce modèle. Il y avait cinq flux de données différents; Résidentiel, commercial, multifamilial, hôtels et terrains.
J'ai créé une propriété appelée SuperType qui contenait des données communes à chacun des cinq flux de données distincts. Cela a permis des recherches "simples" très rapides dans tous les types de données.
Je crée cinq sous-types distincts qui stockent les éléments de données uniques pour chacun des cinq flux de données. Chaque enregistrement SuperType avait une relation 1: 1 avec l'enregistrement SubType approprié.
Si un client souhaitait une recherche détaillée, il devait sélectionner un type Super-Sub, par exemple PropertyResidential.
la source
À mon avis, une relation 1: 1 mappe un héritage de classe sur un SGBDR. Il existe une table A qui contient les attributs communs, c'est-à-dire le statut de classe partent. Chaque statut de classe hérité est mappé sur le SGBDR avec une table B avec une relation 1: 1 avec la table A, contenant les attributs spécialisés. La table nommée A contient également un champ "type" qui représente la fonctionnalité "casting"
Au revoir Mario
la source
Vous pouvez créer une table de relations un à un s'il existe un avantage significatif en termes de performances. Vous pouvez placer les champs rarement utilisés dans une table séparée.
la source
Les relations 1: 1 n'ont pas vraiment de sens si vous êtes dans la normalisation, car tout ce qui serait 1: 1 serait conservé dans le même tableau.
Dans le monde réel cependant, c'est souvent différent. Vous voudrez peut-être diviser vos données pour qu'elles correspondent à l'interface de vos applications.
la source
Peut-être si vous avez une sorte d'objets typés dans votre base de données.
Disons que dans un tableau, T1, vous avez les colonnes C1, C2, C3… avec une relation un à un. C'est bon, c'est sous forme normalisée. Maintenant, disons dans un tableau T2, vous avez les colonnes C1, C2, C3,… (les noms peuvent différer, mais disons que les types et le rôle sont les mêmes) avec une relation un à un aussi. C'est OK pour T2 pour les mêmes raisons qu'avec T1.
Dans ce cas cependant, je vois un ajustement pour une table séparée T3, tenant C1, C2, C3… et une relation un à un de T1 à T3 et de T2 à T3. Je vois encore plus un ajustement s'il existe une autre table, avec laquelle il existe déjà un à plusieurs C1, C2, C3 ... disons de la table A à plusieurs lignes dans la table B. Ensuite, au lieu de T3, vous utilisez B, et avez une relation un à un de T1 à B, la même chose de T2 à B, et toujours la même relation un à multiple de A à B.
Je pense que la normalisation n'est pas d'accord avec cela, et cela peut être une idée en dehors de cela: identifier les types d'objet et déplacer des objets du même type vers leur propre pool de stockage, en utilisant une relation un à un de certaines tables et une un à plusieurs relation de quelques autres tables.
la source
C'est inutile pour des raisons de sécurité, mais il existe de meilleures façons d'effectuer des contrôles de sécurité. Imaginez, vous créez une clé qui ne peut ouvrir qu'une seule porte. Si la clé peut ouvrir une autre porte, vous devez sonner l'alarme. En substance, vous pouvez avoir "CitizenTable" et "VotingTable". Le citoyen un vote pour le candidat un qui est stocké dans la table de vote. Si le citoyen un apparaît à nouveau dans la table de vote, alors leur devrait être une alarme. Soyez avisé, c'est une relation un à un car on ne se réfère pas au champ candidat, on se réfère à la table de vote et à la table citoyenne.
Exemple:
Ensuite, si nous voyons la table de vote comme telle:
On pourrait dire que le citoyen numéro 3 est un menteur en pantalon en feu qui a trompé Bern Nie. Juste un exemple.
la source
Lorsque vous avez affaire à une base de données d'un produit tiers, vous ne souhaitez probablement pas modifier leur base de données afin d'éviter un couplage étroit. mais vous pouvez avoir des données qui correspondent 1: 1 avec leurs données
la source
Partout où deux entités entièrement indépendantes partagent une relation univoque. Il doit y avoir beaucoup d'exemples:
personne <-> dentiste (c'est 1: N, donc c'est faux!)
personne <-> médecin (c'est 1: N, donc c'est aussi faux!)
personne <-> conjoint (c'est 1: 0 | 1, donc c'est généralement faux!)
EDIT: Oui, ce sont de très mauvais exemples, en particulier si je cherchais toujours un 1: 1, pas un 0 ou un 1 de chaque côté. Je suppose que mon cerveau a mal tiré :-)
Alors, je vais essayer à nouveau. Il s'avère, après un peu de réflexion, que la seule façon dont vous pouvez avoir deux entités distinctes qui doivent (en ce qui concerne le logiciel) être ensemble tout le temps est qu'elles existent ensemble dans une catégorisation supérieure. Ensuite, si et seulement si vous tombez dans une décomposition inférieure, les choses sont et doivent être séparées, mais au niveau supérieur, elles ne peuvent pas vivre l'une sans l'autre. Le contexte est donc la clé.
Pour une base de données médicale, vous souhaiterez peut-être stocker différentes informations sur des régions spécifiques du corps, en les conservant comme une entité distincte. Dans ce cas, un patient n'a qu'une seule tête et il en a besoin, sinon il ne s'agit pas d'un patient. (Ils ont également un cœur et un certain nombre d'autres organes uniques nécessaires). Si vous êtes intéressé par le suivi des chirurgies, par exemple, chaque région doit être une entité distincte unique.
Dans un système de production / inventaire, si vous suivez l'assemblage des véhicules, vous voulez certainement voir le moteur progresser différemment de la carrosserie, mais il existe une relation un à un. Un soin doit avoir un moteur, et un seul (sinon ce ne serait plus une «voiture»). Un moteur appartient à une seule voiture.
Dans chaque cas, vous pouvez produire les entités séparées comme un seul gros enregistrement, mais étant donné le niveau de décomposition, ce serait faux. Ce sont, dans ces contextes spécifiques, des entités véritablement indépendantes, bien qu'elles puissent ne pas apparaître ainsi à un niveau supérieur.
Paul.
la source