2009-03-03 8 views
2

J'ai une question rapide - existe-t-il une meilleure pratique dans la conception de table SQL pour stocker des données «soit/ou»?Tables SQL - Motif pour/ou données

J'ai le problème suivant - J'ai besoin de stocker des données de modèle (définition de la structure de dossier) dans une table SQL. Un dossier donné peut avoir un nom statique (par exemple "Emails") ou il peut être généré dynamiquement pour chaque instance, en fonction des objets qui lui sont associés (par exemple, le nom de l'entreprise).

Lorsqu'un objet métier est instancié, les données de modèle sont utilisées pour créer la structure de dossiers réelle.

Je pense à stocker les données comme ceci:

 
CREATE TABLE folder 
(
    ID INT IDENTITY PRIMARY KEY, 
    FolderName NVARCHAR(50), 
    IsDynamic BIT NOT NULL DEFAULT 0, 
    DynamicFieldID INT FOREIGN KEY REFERENCES dynamicField, 
    ParentID INT FOREIGN KEY REFERENCES folder 
) 

Donc, si le champ isDynamic est défini sur true Je sais qu'il y aura une règle (définie sur la clé étrangère), mais sinon je utilisera la valeur stockée dans le nom du dossier.

Cependant, cela semble un peu compliqué pour moi - existe-t-il un modèle de "meilleure pratique" pour ce genre de scénario?

Répondre

7

Cela ne me semble pas trop mal.

Vous pouvez envisager de ne pas déranger avec le champ "IsDynamic" car cela peut être dérivé du fait que DynamicFieldID est null. Ensuite, dans votre SQL, vous pouvez LEFT JOIN et COALESCE les champs des tables dynamiques.

Mais je ne pense pas que le modèle ci-dessus est tout ce désordonné.

4
CREATE TABLE folder 
(
    ID INT IDENTITY PRIMARY KEY, 
    ParentID INT FOREIGN KEY REFERENCES folder 
) 

CREATE TABLE dynamic_folder (
    ID INT FOREIGN KEY REFERENCES folder (id), 
    DynamicFieldID INT FOREIGN KEY REFERENCES dynamicField 
) 

CREATE TABLE static_folder (
    ID INT FOREIGN KEY REFERENCES folder (id), 
    FolderName NVARCHAR(50) 
) 
+0

Salut Patrick - merci pour cela. J'envisageais cela, mais je me suis contenté de décider si c'était mieux ou moins bien que ça. Quelle est votre opinion sur la raison pour laquelle c'est mieux (ou que considérez-vous comme le pour et le contre)? – Chris

+0

Si vous avez eu plus de deux types de dossiers, ou plus de deux colonnes ont été affectées, cette approche pourrait s'avérer plus propre que d'essayer de tout garder dans une table. Cependant, dans l'état actuel, je pense que la suggestion de Christie's COALESE est plus pratique.J'accepterais sa réponse. :-) –

-1

Je ne suis pas sûr je comprends la question exactement, mais je pense que ce que vous dites est que vous avez un champ qui peut avoir soit une valeur statique ou qui doit être déterminé lors de l'exécution en fonction d'autres valeurs.

Je créerais votre propre schéma "variable" et le stockerais dans la base de données. Je ne sais pas quelle langue vous utilisez et donc je trouverais quelque chose basé sur cela (le rendre différent de votre langue) et j'utiliserais quelque chose qui entoure la valeur - début et fin. Ainsi, par exemple:

Valeur:/companyA/projeta/

ou

valeur/@ companyVariable @/@ projectVariable @/

alors il suffit d'écrire une routine à la recherche pour ouvrir et fermer @ signes et échangez-les avec les valeurs appropriées. C'est un peu plus de travail, mais je pense que ce serait le plus facile à comprendre à la fin et le plus flexible. Encore une fois, @ signes est juste ce que je pensais d'abord, utilisez les caractères les plus sensés pour vous.

+0

Quelqu'un veut-il commenter pourquoi j'ai été rejeté? Ma réponse était-elle incorrecte d'une manière ou d'une autre? Si c'est une mauvaise idée, prenez soin de mentionner pourquoi? –

1

Vous pouvez juste avoir NULL dans DynamicFieldID et requête comme ceci:

SELECT COALESCE(dynamicName, folderName) 
FROM folder 
LEFT JOIN dynamicField ON (dynamicField.ID = folder.DynamicFieldID)