Comment concevoir des relations plusieurs-à-plusieurs dans une base de données d'objets ?

StackOverflow https://stackoverflow.com/questions/1069187

Question

J'ai pensé qu'il était temps de jeter un œil aux bases de données OO et j'ai décidé d'utiliser db4o pour mon prochain petit projet : une petite bibliothèque.

Considérez les objets suivants :Livre, catégorie.

Un livre peut appartenir à 0 à n catégories et une catégorie peut être appliquée à 0 à m livres.

Ma première pensée est d'avoir un objet de jointure tel que BookCatecory, mais après quelques recherches sur Google, je vois que ce n'est pas approprié pour "Real OO".

Ainsi, une autre approche (recommandée par beaucoup) consiste à avoir une liste dans les deux objets :Livre.catégories et Catégorie.livres.Un côté gère la relation :Book.addCategory ajoute Category à Book.categories et Book à Category.books.Comment gérer les validations et les annulations lorsque 2 objets ont été modifiés au cours d'un seul appel de méthode ?

Quelles sont vos pensées?La deuxième approche présente des avantages évidents mais, du moins pour moi, la première « semble » correcte (mieux normée).

Était-ce utile?

La solution

Si vous utilisez la base de données d'objets que vous n'avez pas besoin de prendre soin comment les relations sont stockées dans la base de données. Vous définissez les classes et les relations entre eux. S'il vous plaît lire la référence guidée à votre base de données. Des exemples de relations:

n:n attribute, referencing from the parent
------------------------------------------------------------------
class Person{
List addresses;
}

class Address{
}


n:n attribute, referencing from the child
------------------------------------------------------------------
class Person{
}

class Address{
List persons
}

n:n attribute, bidirectional references
------------------------------------------------------------------
class Person{
List addresses;
}

class Address{
List persons
}

Autres conseils

Je ne peux penser qu'à deux façons de résoudre ce problème, que vous avez mentionnées toutes les deux.Personnellement, j'opterais pour la première approche (créer un objet de mappage en tant qu'entité OO).Cela vous évite de conserver des informations redondantes et de devoir les synchroniser ;cela signifie également que si l'association finit par avoir ses propres champs (la date à laquelle le livre a été attribué à cette catégorie, disons), ils peuvent être facilement incorporés.Nous utilisons cette approche pour diverses associations de notre système.

Les entités OO ressembleraient à :

BookCategory {
 Book book
 Category category
}
Book {
 Collection <BookCategory> categories
}
Category {
 Collection <BookCategory> categories
}

Ici, vous devez garder l'objet relation et les deux collections synchronisés ;cependant, les collectes sont facultatives dans ce cas.En règle générale, vous pouvez obtenir les mêmes informations avec une requête ORM, quelque chose comme :sélectionnez b.book dans BookCategory b où b.category = MyCategory

L'alternative est d'avoir une configuration comme :

Book {
 Collection<Category> categories
}

Category {
 Collection<Books> books
}

Si votre outil ORM/DB maintient automatiquement les associations, c'est très bien ;sinon, vous êtes obligé de mettre à jour les deux collections.(Dans Hibernate, un côté aura la propriété :inverse=true sur le mappage ;ce côté n'est pas mis à jour, donc à proprement parler il n'a pas besoin d'être maintenu.Cela me semble cependant être une mauvaise pratique.)

Si vous n'accédez généralement à la relation que dans un sens (par exemple, en obtenant tous les livres d'une catégorie), vous pourriez éliminer la collection de l'autre côté ;alors je pense que vous devrez contourner l'outil ORM et utiliser une requête native afin d'accéder à la relation dans l'autre sens.

Nous utilisons Hibernate (un outil de mappage relationnel objet basé sur Java) sur notre projet ;la documentation Hibernate est une bonne référence pour les problèmes de conception OO/relationnelle, même si vous devrez peut-être passer un peu de temps à apprendre Hibernate pour les rendre utiles :http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues

HTH!

Je pense que vous êtes un peu accroché sur la façon db relationnelle de la pensée. Listes dans chaque objet est la bonne chose à faire OO. Validations et annulations sont pas de problème, ils se produisent dans une transaction qui engage tout ou annule tout.

Dans une base de données pure OO tels que GemStone les objets eux-mêmes ont des collections de références à d'autres objets. Lorsque l'objet est référencé à partir de l'application du SGBDOO génère un proxy qui enveloppe l'objet. Le schéma de c'est juste l'objet persiste et sa collection de références aux objets qu'il fait référence. Le SGBDOO ne doit pas nécessairement une entité lien.

Avec une couche de mappage O / R (en supposant qu'il est suffisamment intelligent pour faire M: relations M) M: rapport de M se manifeste comme une collection de références subsidiaires sur l'objet lui-même qui l'O / R mapper a pour le lien entité dans les coulisses. Pas tous les O / R cartographes faire, alors vous pouvez avoir un objet lien séparé.

Avez-vous une raison particulière que vous vouliez utiliser un ODBMS? Pour de simples structures de données (telles que catégoriser les livres) vous généralement ne trouverez aucun avantage ODBMS sur SGBDR, et en fait sera un temps plus facile de travailler dans le monde beaucoup plus-normalisé de SGBDR. ODBMS a des avantages très tangibles lorsque vous travaillez avec des types de données complexes ou la persistance / stockage littérale des objets dynamiques. ODBMS est également cité comme étant beaucoup plus rapide et plus évolutive que SGBDR, bien que je peux offrir à petit aperçu de moi-même. Voici quelques pages qui traitent de SGBDR contre ODBMS cependant:

Whatever Happened to Bases de données orientée objet

base de données orientée objet par rapport à la base de données objet-Rleational (SO)

Je voudrais éviter la duplication des données, car alors vous exécutez dans toutes sortes de problèmes avec la fusion des différences.

L'astuce pour c'est des références.

le résultat est que j'aurais chaque objet contient une collection de références à l'autre type d'objet ainsi que d'avoir une collection indépendante des autres objets.

Le tableau de correspondance est un concept relationnel, à moins que la classe intermédiaire de connexion peut avoir des propriétés qui ne sont pas imputables à l'un des objets. Il est là car elle permet des requêtes à écrire d'une manière puissante, car elle réduit la relation 2 un à plusieurs relations et réduit considérablement la duplication des données. Si vous avez fait cela dans une base de données relationnelle sans la table de correspondance alors les choses iraient mal très rapidement - comment une mise à jour fonctionnerait? Personnellement, je trouve l'attraction des bases de données oo être de vous éloigner de cette

la façon dont je voudrais attacher tous les objets ensemble est par les événements dans le code à une sorte de gestionnaire de transactions pour permettre la mise en cache des états des objets. Ainsi, plutôt que de manipuler des objets chacun des autres propriétés qu'ils demandent un changement par l'intermédiaire du gestionnaire et attendent le résultat d'une fonction de rappel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top