Meilleure façon de modéliser un singleton dans une base de données relationnelle

12

Lors de la conception d'un schéma de base de données relationnelle pour des applications Web, je trouve souvent un cas où je finis par créer une table juste pour contenir une ligne et une seule ligne. Il me semble que ce n'est pas la bonne façon de le concevoir, mais je ne peux rien trouver de mieux que ça, ou c'est évidemment "la bonne façon de le faire".

Un exemple récent est un site qui permet aux utilisateurs de contrôler manuellement le contenu de la page d'accueil. Eh bien, il n'y a qu'une seule page d'accueil. J'ai créé une table qui avait tous les champs nécessaires pour construire la page d'accueil, comme un champ de texte pour une zone contenant du texte descriptif. Un champ pour stocker le nom d'un gros fichier image. Certaines clés étrangères qui pointent vers des articles qui seront présentés sur la page d'accueil, etc.

Dans le passé, j'ai essayé de nombreux autres modèles, comme autoriser plusieurs lignes dans le tableau de la page d'accueil et en sélectionner une au hasard. J'ai essayé d'ajouter un champ booléen nommé "actif" et de sélectionner au hasard l'une des pages d'accueil actives. J'ai essayé de forcer une seule ligne à être active à un moment donné dans la logique d'application. J'ai essayé de ne même pas créer un tableau de page d'accueil et d'avoir tous les autres éléments, tels que des articles, pour avoir des champs booléens avec des noms comme en vedette sur la page d'accueil.

Dans la plupart des cas, j'ai pu créer la page d'accueil avec un tas de constantes dans un fichier de paramètres. Le principal problème avec le fichier de paramètres est qu'il est sous le contrôle du développeur. Parce que quelque chose comme le contenu de la page d'accueil doit être modifié par l'utilisateur, il doit aller dans la base de données.

Sur de nombreux sites, je n'ai pas ce problème car je peux créer des choses comme la page d'accueil avec une requête telle que la sélection des cinq derniers articles. Mais lorsque j'ai des pages gérées manuellement avec des exigences strictes, il devient difficile de les modéliser dans la base de données. Mais imaginez que vous avez une table photo et une table article. La condition requise est que la page d'accueil affiche exactement cinq photos, exactement trois articles et deux blocs de texte arbitraire contrôlés manuellement par l'utilisateur. Comment modélisez-vous cela dans la base de données de la bonne façon?

En outre, j'ai ce problème de modélisation dans de nombreux autres cas en plus des pages d'accueil. C'est juste l'exemple le plus simple et le plus généralement applicable que j'ai pu trouver.

Apreche
la source
Il n'est pas du tout clair quel problème le tableau à une seule ligne vous présente, sinon qu'il représente en quelque sorte un gaspillage de tableau. Êtes-vous sûr d'essayer de résoudre un problème dont vous souffrez réellement?
David Aldridge

Réponses:

10

Une approche simple consisterait à enregistrer les propriétés de la page d'accueil dans une table de propriétés (ou à l'appeler autrement) qui est constituée de colonnes Nom et Valeur.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

Ce n'est peut-être pas une solution idéale, mais c'est simple et flexible. Il élimine également la table avec un scénario à une ligne.

Walter
la source
1
Cette approche fonctionne à des fins multiples. Par exemple, je vais stocker des informations sur la version du schéma, des pointeurs de rotation pour les choses qui doivent être cyclées quotidiennement, etc. Les informations sur la version du schéma sont importantes lors du diagnostic de ce qui s'est mal passé. C'est un moyen raisonnable de s'assurer qu'un correctif a été appliqué pour un correctif de base de données uniquement.
Berin Loritsch
2
+1 - Il s'agit de la disposition exacte du tableau que notre architecte de données m'a donné dans un but similaire.
Ali
3
Le problème avec cette approche est que vous devez représenter différents types de variables sous forme de colonnes différentes et avoir une logique pour vous dire quelle colonne utiliser et lesquelles sont obligatoires. Vous ne pouvez pas définir qu'une valeur booléenne est booléenne, ou qu'une date est une date, ou qu'un attribut particulier ne peut pas être nul, ou doit tomber dans une plage particulière ou remplir une condition - toutes les choses qui sont trivialement simples avec une table à une rangée.
David Aldridge
3

Il n'est pas clair pour moi que vous avez un problème que vous devez résoudre.

Une table à une seule ligne n'est en aucun cas un problème pour la base de données elle-même et vous permet d'appliquer des types de données et des contraintes aux données.

Je ne suis pas sûr que vous essayiez de résoudre un vrai problème, pour être honnête.

David Aldridge
la source
2

Il me semble que vous utilisez une base de données pour quelque chose qui devrait en fait être stocké sous forme de fichier.

Votre description me rappelle beaucoup de pages Wiki, où les utilisateurs peuvent modifier le contenu. Dans les wikis, ou du moins dans les implémentations que j'ai vues, les pages sont conservées sous forme de fichiers.

Cela vous aide avec d'autres détails Web tels que permettre à vos utilisateurs de mettre en cache votre page d'accueil, ce qui est pratiquement gratuit si vous stockez les pages sous forme de fichiers, mais vous devrez implémenter manuellement la logique d'invalidation du cache si vous construisez le page sur chaque demande basée sur le contenu stocké dans la base de données.

Dans tous les cas, je veux juste préciser que même si la plupart des données persistantes d'une application sont stockées dans une base de données, cela ne signifie pas que nous devons tout y stocker. Les bases de données ne sont qu'un des outils de notre métier. Nous devons apprendre à utiliser autant d'outils différents que possible.

MichelHenrich
la source
2

Il n'y a absolument rien de mal avec un tableau à une rangée.

Si cela fait partie de votre conception, vous devez l'appliquer. Donnez à la table une colonne d'identité, donnez-lui une contrainte d'unicité, puis ajoutez une contrainte de colonne pour n'autoriser qu'une seule valeur. Cela garantira que personne ne pourra ajouter une deuxième ligne, ce qui pourrait être catastrophique si les instructions SQL qui lisent la table (naturellement) manquent d'une clause where.

Si vous commencez à obtenir un grand nombre de colonnes, vous pourriez être tenté de restreindre le tableau et d'avoir à la place une ligne par élément de configuration. Ce n'est pas la meilleure idée car vous perdez la sécurité et la validation du type. En outre, vous perdriez la compatibilité directe avec la mutualisation , ce qui pourrait être important pour vous. Une meilleure solution serait de repenser ce que sont réellement vos entités et d'avoir des tables séparées sur une seule ligne pour différentes entités.

Oui, je dis non seulement qu'un tableau à une seule rangée est OK, mais je suggère que vous pouvez en vouloir plus d'un.

John Wu
la source
1

Vous pouvez créer une table appelée STATIC_CONTENT et avoir des colonnes pour une clé ainsi que le contenu, les trackers actifs / inactifs, etc. Ensuite, créez une ligne avec une clé de "HomePage" et dans votre page d'accueil, chargez le contenu statique pour cette clé et l'afficher. De cette façon, lorsque vous avez d'autres contenus statiques (sur la page, la page de contact, etc.), vous pouvez ajouter des lignes à ce tableau.

RationalGeek
la source
1

Il n'y a rien de mal en soi à avoir une table avec une seule ligne. Si vous ne disposez que d'une seule instance d'une certaine entité, cela pourrait très bien être le moyen le plus naturel de représenter cela.

Mais sélectionner une ligne au hasard est mauvais et mauvais. Si votre logique de domaine n'attend qu'une seule ligne, c'est évidemment une erreur dans les données s'il y en a réellement plus. Vous devez donc déterminer qui ou quoi écrit des données non valides dans la base de données et les empêcher de le faire! Selon la base de données, vous pourriez probablement ajouter une contrainte à la table pour éviter que cela ne se produise en premier lieu, par exemple en n'autorisant qu'une valeur particulière comme clé primaire.

JacquesB
la source
0

Pour ajouter à Walter ..

La structure de la table des propriétés doit autoriser plusieurs types de données.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue
Crétins
la source
Avec cela, comment garantissez-vous qu'une seule valeur de propriété est définie par ligne? Il est assez facile de l'imposer dans l'application, mais que se passe-t-il si quelqu'un met à jour la base de données manuellement et y colle des données?
Apreche
0

Il me semble que vous auriez pu extraire un niveau de plus. Au final, une "HomePage" est une "Page". Vous pouvez avoir différents types de pages avec les propriétés dont vous avez besoin. Si vous aviez des sections sur votre site, vous auriez probablement besoin d'une "SectionHomePage", qui peut très bien fonctionner de la même manière qu'une "Page d'accueil".

La condition requise est que la page d'accueil affiche exactement cinq photos, exactement trois articles et deux blocs de texte arbitraire contrôlés manuellement par l'utilisateur. Comment modélisez-vous cela dans la base de données de la bonne façon?

Essayons comme ça. J'ajoute une table ArticlePage pour voir comment séparer les propriétés en conséquence.

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

Cela fonctionnerait bien pour moi, fonctionnerait même très bien pour un grand site.

Juan Carlos Eduardo Romaina Ac
la source