La relation un à un est-elle normalisée?

12

Considérez que nous avons un grand ensemble de données statistiques pour un enregistrement; par exemple 20-30 INTcolonnes. Est-il préférable de conserver l'ensemble entier dans une table car ils appartiennent tous à un enregistrement OU de créer une autre table connectée avec une relation un-à-un.

L'avantage du premier est d'éviter JOINet d'avoir un accès rapide à toutes les données statistiques de l'enregistrement correspondant.

L'avantage de ce dernier est de garder la colonne bien rangée. La première colonne est intensive en lecture et la seconde en écriture. Bien sûr, je pense que cela n'a pas d'effet significatif sur les performances, car j'utilise InnoDB avec un blocage au niveau des lignes.

En général, je veux savoir s'il est pratique de séparer différents ensembles de données pour un seul enregistrement?

Googlebot
la source
2
«Normalisé» signifie la première forme normale (1NF) et est une exigence fondamentale du modèle relationnel. «Entièrement normalisé» signifie 5NF ou plus. Votre table de «relation un-à-un» proposée a de meilleures chances d'être dans une forme normale plus élevée (peut-être même en 6NF) que votre table actuelle car elle est décomposée! À quelles formes normales votre table existante satisfait-elle?
quand
@onedaywhen Comme beaucoup d'autres, je ne suis pas la normalisation pas à pas, car parfois la dénormalisation est également utile. En général, la base de données entière devrait avoir un niveau de normalisation entre 3NF - 5NF (j'ai toujours un problème avec 4NF!)
Googlebot

Réponses:

19

S'il s'inscrit dans les règles de normalisation, alors les relations 1: 1 peuvent être normalisées (par définition!) - En d'autres termes, rien dans les relations 1: 1 ne les empêche d'obéir aux formes normales.

Pour répondre à votre question sur l'aspect pratique des relations 1: 1, il y a des moments où il s'agit d'une construction parfaitement utile, comme lorsque vous avez des sous-types avec des prédicats distincts (colonnes).

Les raisons pour lesquelles vous utiliseriez des relations 1: 1 dépendent de votre point de vue. Les administrateurs de base de données ont tendance à considérer tout comme une décision de performance. Les modélisateurs et programmeurs de données ont tendance à considérer ces décisions comme étant orientées conception ou modèle. En fait, il y a beaucoup de chevauchement entre ces points de vue. Cela dépend de vos perspectives et priorités. Voici quelques exemples de motivations pour des relations 1: 1:

  • Vous disposez d'un sous-ensemble de colonnes très larges et vous souhaitez les séparer physiquement dans votre stockage pour des raisons de performances.

  • Vous avez un sous-ensemble de colonnes qui ne sont pas lues ou mises à jour fréquemment et vous souhaitez les garder à l'écart des colonnes fréquemment utilisées pour des raisons de performances.

  • Certaines colonnes sont facultatives en général, mais elles sont obligatoires lorsque vous savez que l'enregistrement est d'un certain type.

  • Vous avez des colonnes qui appartiennent logiquement ensemble pour un sous-type et vous souhaitez les modéliser pour qu'elles correspondent bien au modèle d'objet de votre code.

  • Certaines colonnes ne peuvent s'appliquer qu'à certains sous-types d'un super-type d'entité et vous souhaitez que votre schéma applique l'absence de ces données à d'autres sous-types.

  • Certaines colonnes appartiennent à une entité, mais vous devez protéger ces colonnes particulières à l'aide de règles d'accès plus restrictives (par exemple, le salaire sur une table des employés).

Ainsi, vous pouvez voir, parfois le pilote est la performance, parfois c'est la pureté du modèle, ou simplement le désir de tirer pleinement parti des règles de schéma déclaratif.

Joel Brown
la source
You have some subset of columns that are very wide and you want to segregate them physically in your storage for performance reasons.Comment leur séparation améliore-t-elle les performances (en supposant que les colonnes sont toujours accessibles à chaque fois que la table principale l'est)?
Gili
@Gili - Si votre hypothèse était vraie, ce cas ne s'appliquerait pas. La séparation des colonnes volumineuses et rarement nécessaires permet à davantage de lignes de tenir sur une page, permettant ainsi une récupération plus rapide des colonnes couramment utilisées. De toute évidence, la lecture des colonnes séparées avec les colonnes couramment utilisées serait plus lente car une jointure est nécessaire.
Joel Brown
Je veux séparer le long des colonnes couramment utilisées pour des raisons de conception (séparation des préoccupations, réutilisation accrue du code). Quelqu'un a-t-il publié une estimation du coût de ces jointures? Sont-ils négligeables ou quelque chose dont je devrais m'inquiéter à long terme?
Gili
@Gili-re: le coût des jointures: il n'y a pas de bonne réponse à cette question à part "ça dépend". Le coût de jointure est influencé par de nombreux facteurs. Qu'ils soient négligeables est encore plus difficile à répondre, car c'est finalement subjectif. La meilleure façon de répondre à votre question est de simuler des données de test et de faire des tests de volume. Essayez-le dans les deux sens et voyez si vous pouvez faire la différence en utilisant des volumes de données réels (quoi que cela implique pour votre application).
Joel Brown
Je l'ai fait et j'ai obtenu des résultats surprenants: dba.stackexchange.com/q/74693/4719 J'admets que ce n'est pas un exemple typique de normalisation, mais cela ne met pas en évidence que les JOIN sont (toujours) très chers.
Gili
4

Les principales raisons pour lesquelles vous utiliseriez un mappage un à un pour diviser une grande table en deux sont pour des raisons de performances, par exemple:

a) La table contient des données binaires / clob / blob dans une table fréquemment consultée, ce qui ralentit les performances car les grandes colonnes sont traitées différemment.

b) La table a de nombreuses colonnes accessibles par différentes requêtes, donc les performances sont dégradées, vous devez donc déplacer les colonnes associées dans une table distincte pour améliorer les performances d'accès

Cependant, le fait d'avoir de nombreuses colonnes entières ne justifie pas l'effort supplémentaire de diviser la table en tables distinctes et de devoir les interroger.

Stephen Senkomago Musoke
la source
très bon point pour clarifier la question!
Googlebot