Problème de design

J'ai un problème lors de la création d'un schéma de database pour le scénario suivant:

(Je ne crée pas un site de rencontre mais juste en utilisant ceci comme exemple)

Un user se connecte à un site de rencontres et reçoit une sélection multiple pour la couleur de cheveux qu'ils aimeraient avoir:

C'est assez facile à modéliser avec les trois arrays ci-dessous:

Les tables:

Utilisateur {key}

HairColour {key}

UserHairColour {UserKey} {HairColourKey}

Cependant, l'user a également la possibilité de sélectionner «tout», ce qui signifie qu'il ne se soucie pas de la couleur des cheveux et que toute la couleur des cheveux doit être incluse dans la sélection.

Comment puis-je donner à l'user l'option 'any'?

Je pourrais évidemment sélectionner toutes les colors de cheveux et les mettre dans 'UserHairColour' mais si je dois append une nouvelle couleur de cheveux à l'avenir?

L'absence d'loggings pour cet user particulier dans la table UserHairColour indique qu'ils ne se soucient pas de la couleur des cheveux.

L'absence de décision indique qu'ils n'ont aucune preference. Évidemment, cela ne peut pas signifier qu'ils veulent que leur date n'ait aucune couleur de cheveux du tout.

Je ne vois pas ici le besoin d'une valeur séparée ou d'une design de table supplémentaire. Ce que vous avez vous permet d'atteindre votre objective de manière simple.


EDIT: Comme réaction à une solution proposée avec n'importe quelle valeur supplémentaire.

L'idée de "ANY" interférera conceptuellement avec les autres sélections. Nous parlons de présenter à l'user une multitude de choix, n'importe lequel étant l'un d'entre eux, et leur permettant d'en sélectionner plusieurs. Ainsi, l'user peut techniquement sélectionner TOUT avec les autres options, ce qui rend peu clair ce qui a priorité – TOUT ou des options spécifiques. Je crois que l'approche avec simplement aucun logging comme indicateur de ANY est plus claire – elle ne peut être interprétée que dans un sens. Aucun logging – aucune valeur préférée. Vous ne pouvez évidemment pas l'interpréter dans l'autre sens – aucune valeur préférée – l'user ne veut pas que cette valeur soit présente – ceci rendra la couleur de cheveux transparente qui n'a aucun sens. Vous pouvez dire que cela ne veut rien dire du tout, mais je suggérerais d'avoir une option distincte ou une question distincte pour cela.

Compte tenu de l'exemple ci-dessus, je voudrais simplement append «Any» ou «No Preference» comme une sélection et le traiter comme une couleur de cheveux spécifique. Cela fonctionnerait le mieux parce que si vous voulez append des colors de cheveux plus spécifiques. En général, lorsque je crée de nouveaux templates relationnels, j'ai tendance à append un -1 pour la première input key et à conserver les valeurs de cette ligne par défaut. Ce serait une meilleure pratique que de simplement le simuler avec une table temporaire ou une requête à mon avis.

Cela devrait être simple à réaliser. Si l'user choisit "Tout", vous le gérez simplement sur la requête:

select * from User left join UserHairColour on UserHairColour.UserId=User.UserId where (@hairpreference = 'Any' OR UserHairColour.HairColourId=@hairpreference) 

Si vous pouvez définir l'input var @hairpreference sur null au lieu de 'Any', alors cela devient plus facile:

 where (UserHairColour.HairColourId=COALESCE(@hairpreference, UserHairColour.HairColourId)) 

Déclarez une table temporaire, remplissez-la avec les valeurs de couleur et interrogez comme ceci:

 SELECT * FROM UserHairColor JOIN User ON User.id = UserHairColor.UserID WHERE HairColorKey IN ( SELECT ColorKey FROM @mytable ) UNION ALL SELECT * FROM UserHairColor JOIN User ON User.id = UserHairColor.UserID AND NOT EXISTS ( SELECT NULL FROM @mytable ) 

Cela sélectionnera tous les users avec les colors de cheveux demandées, de tous les users du tout si la table est vide.

Si les users peuvent sélectionner n'importe quel nombre de HairColours, je pense, pour la cohérence, il serait utile de faire un logging dans UserHairColours pour chaque couleur. Si les users ne peuvent en sélectionner qu'un seul, dont l'un est "any", alors je privilégie la solution New in town.

Mettez (PersonID, HairColorPreference) dans une table qui lui est propre. Si quelqu'un n'a aucune preference, n'enregistrez pas de ligne dans cette table.

Utilisez les vues pour rassembler les personnes avec preference avec juste cette preference, et les personnes sans preference avec toutes les colors de cheveux.

BTW, qu'allez-vous faire avec les gens dont la preference est "tout sauf pourpre"?

Comme vous n'allez pas build un site de rencontres, vous pouvez clairement indiquer que les autres réponses répondent à vos besoins ou non. Mais ma suggestion est de créer une autre table pour dire si un user a sélectionné n'importe quelle couleur de cheveux sans couleur de cheveux (sonne un non-sens dans votre exemple mais peut avoir un sens dans une autre situation). En ayant des tables suivantes dans votre database, vous pouvez accomplir cela.

  1. Utilisateurs
  2. Couleur de cheveux
  3. TypeOfColorSelection (1: Sélectionné, 2: Tous, 3: Exclure, …)
  4. UserColorSelectionProfile (UserID, TypeOfColorSelection)
  5. UserPreferredColor (UserID, HairColor)

Si vous souhaitez que l'option de coloration des cheveux soit obligatoire, l'option sans choix (set vide) ne fonctionne pas.

Cela me callbackle les publicités TV britanniques classiques pour la nourriture pour chats Whiskas. Le strapline était à l'origine,

Huit propriétaires sur dix disent que leur chat préfère

Plus tard, il a été changé en

Huit propriétaires sur dix qui ont exprimé une preference disent que leur chat préfère

[Les italiques sont à moi.]

De toute évidence, les résultats sont faussés quand on ne montre pas la différence entre implicitement explicitement ne pas avoir de preference, sinon pourquoi changer un strapline parfaitement bon pour celui qui ne balaye pas tout aussi bien? QED;)

Ma preference serait d'utiliser des arrays séparés pour modéliser ceux qui ont exprimé une preference (avec la ou les colors qu'ils ont choisies), ceux qui ont exprimé leur preference et ceux qui n'ont exprimé aucune preference.

Pour un exemple travaillé, voir Comment gérer les informations manquantes sans utiliser NULL par Hugh Darwen.