2009-07-23 8 views
0

[noob warning!] J'ai besoin de stocker des données dans certaines tables où elles sont comme l'équivalent d'un tableau de pointeurs vers des objets polymorphes. Par exemple. (pseudo C++)Stockage des objets polymorphes dans la base de données SQL

struct MyData { string name; } 
struct MyDataA : MyData { int a,b,c; } 
struct MyDataB : MyData { string s; } 
MyData * data[100]; 

Je ne sais pas vraiment quelle recherche google pour entrer! Comment stockez-vous ces informations dans une base de données SQL?

Mes pensées au hasard:

  • je pouvais avoir une table avec une colonne qui est l'identificateur de struct et ont des colonnes redondantes, mais cela semble inutile.
  • Je peux avoir une table pour chaque type de structure. Ceux-ci auraient une clé étrangère de retour à la table de tableau principal. Mais, comment puis-je pointer vers les tables de struct?

Répondre

1

Une possibilité est un champ XML pour stocker les données, ce qui permet de rechercher et de récupérer tout en étant relativement facile à sérialiser. (La question dit SQL, mais ne spécifie pas une base de données fournisseur spécifique, donc XML peut ne pas fonctionner pour chaque solution DB.)

Modifier: Je vais mettre en garde parce que ce n'est pas tout à fait clair ce qui doit être stocké/récupéré/objet etc, donc XML peut être tout à fait inapproprié - je le jette dehors comme un provocateur de la pensée à la place.

+0

J'ai un flux de données en "temps réel" que je veux filtrer dans une base de données. La base de données est SQLite (ADO). XML serait trop lent (marshalling) et créerait des fichiers massifs (GB). XML était l'origine des données sources. – Nick

3

Ceci est un sujet complexe. Pour avoir une idée des stratégies impliquées, je vous suggère de lire la documentation Hibernate sur ce sujet:

http://docs.jboss.org/hibernate/stable/core/reference/en/html/inheritance.html

Même si vous ne l'utilisez Hibernate, les concepts de cartographie relationnelle sont toujours pertinentes. Notez qu'Hibernate ne dicte aucune stratégie, car aucune approche n'est meilleure que les autres.

2

Je fais le style "table-per-sublcass" à partir des docs Hibernate.

Vous créez une table Person avec tout ce que vous savez sur une personne, plus le PersonID. Ensuite, vous créez une table Customer, avec uniquement les données propres à un client (solde du compte, etc.). Placez le PersonID dans la table Customer. Un WebsiteUser peut contenir un CustomerID, et ainsi de suite dans la chaîne.

Relations un-à-un mappant les relations d'héritage IS-A.

1

Il y a vraiment deux façons principales pour résoudre ce:

  • table par type
  • table par hiérarchie

Chacun d'eux a ses avantages et ses inconvénients. Table-par-type vous donne plus de tables (une par type), qui stocke seulement le "delta" de la super classe immédiate. Dans le pire des cas, vous devez rassembler un certain nombre de tables pour finalement obtenir toutes les données ensemble pour une seule instance d'un type. Avantages: puisque vous ne stockez ce qui est vraiment pertinent pour ce type dans une table séparée, vous pouvez le faire comme définir NOT NULL restrictions etc. sur la table de base de données.La table par hiérarchie vous donne moins de tables, mais chaque table représente une hiérarchie entière, donc elle contient potentiellement beaucoup de colonnes qui ne sont pas remplies (dans les lignes représentant les types de classe de base). En outre, sur les colonnes supplémentaires qui composent les classes dérivées, vous ne pouvez pas définir des restrictions comme NOT NULL - toutes ces colonnes supplémentaires doivent être nullables, puisqu'elles n'existent pas réellement dans les classes de base, donc vous perdez un peu de sécurité ici.

Voyez vous-même - il y a deux articles très bons sur la façon de le faire (dans Entity Framework, mais les principes applicables à toute base de données et une technologie de cartographie de données):

Espérons que cela aide et vous donne quelques entrées!

Marc

+0

Merci, cela aide à modéliser les données. Maintenant, comment faire une requête quand j'ai une table par type et plusieurs types. Dois-je joindre toutes les tables avec la "base" et interroger chaque type? – Nick

+0

Comment envisagez-vous d'accéder à vos données? Tant l'Entity Framework, que les ORM plus performants tels que NHibernate, supporteront ce "out of the box" - vous demandez juste une "chose", et vous obtenez la bonne "chose" du OR-mapper. –

+0

Si vous avez besoin d'y accéder à partir de SQL, vous devez savoir (ou comprendre) de quel type vous avez besoin et faire plusieurs requêtes ou une requête jointe pour obtenir vos données. OU: vous pouvez créer une vue pour chaque type qui encapsulerait ce JOIN (ou ces plusieurs JOINS) et vous pouvez simplement sélectionner à partir de cette vue et obtenir tous vos e. étudiants ou tous vos étudiants en affaires etc. –

Questions connexes