2009-07-01 19 views
14

Pensé que ya era hora de echar un vistazo a las bases de datos de OO y decidí usar db4o para mi próximo pequeño proyecto: una pequeña biblioteca.¿Cómo diseñar relaciones de muchos a muchos en una base de datos de objetos?

Considere los siguientes objetos: Libro, Categoría.

Un libro puede estar en 0-n categorías y una categoría puede ser aplicado a 0 m-Libros.

Mi primera idea es tener un objeto de unirse como BookCatecory pero después de un poco de google veo que esto no es apropiado para 'real OO'.

Así otro enfoque (recomendado por muchos) es tener una lista de los dos objetos: Book.categories y Category.books. Un lado maneja la relación: Book.addCategory agrega Category a Book.categories y Book to Category.books. ¿Cómo se manejan los commits y los retrocesos cuando se modifican 2 objetos dentro de una llamada a un método?

¿Cuáles son sus pensamientos? El segundo enfoque tiene ventajas obvias pero, al menos para mí, el primero 'se siente' bien (mejor normado).

Respuesta

5

Si utiliza la base de datos de objetos que no es necesario preocuparse de cómo se almacenan las relaciones en la base de datos. Usted define clases y relaciones entre ellos. Por favor, lea la referencia guiada a su base de datos. Ejemplos de relaciones:

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 
} 
1

Creo que estás un poco obsesionado con la forma de pensar de db relacional. Las listas en cada objeto son lo correcto de OO. Los commits y los rollbacks no son un problema, ocurren en una transacción que compromete todo o revierte todo.

1

En una base de datos OO pura como la piedra preciosa de los propios objetos tienen colecciones de referencias a otros objetos. Cuando se hace referencia al objeto desde la aplicación, OODBMS genera un proxy que envuelve el objeto. El esquema para esto es solo el objeto persistente y su colección de referencias a los objetos a los que hace referencia. El OODBMS no necesita necesariamente una entidad de enlace.

Con una capa de asignación O/R (asumiendo que es lo suficientemente inteligente como para hacer relaciones M: M) la relación M: M se manifiesta como una colección de referencias subsidiarias en el objeto mismo que el asignador O/R resuelve a vincular entidad detrás de las escenas. No todos los creadores de O/R hacen esto, por lo que puede tener un objeto de enlace por separado.

1

¿Tiene algún motivo en particular por el que desea utilizar un ODBMS? Para las estructuras de datos simples (como la categorización de libros), generalmente no encontrará ninguna ventaja en ODBMS sobre RDBMS, y de hecho le será más fácil trabajar en el mundo de RDBMS mucho más estandarizado. ODBMS tiene ventajas muy tangibles cuando se trabaja con tipos de datos complejos o persistencia/almacenamiento literal de objetos dinámicos. ODBMS también se cita como mucho más rápido y más escalable que RDBMS, aunque puedo ofrecerle poca información sobre esto. Aquí hay un par de páginas que tratan sobre RDBMS vs ODBMS, sin embargo:

Whatever Happened to Object-Oriented Databases

Object-Oriented Database vs. Object-Rleational Database (SO)

+0

Quería ver si podía evitar crear un dbschema, crear tablas, crear objetos, mapear tablas a objetos, etc. etc. Parece que un odbms podría cortar una gran cantidad del trabajo de burro ... – paul

+0

Podría cortar parte de ese trabajo, pero también lo haría una capa ORM decente. No digo que ODBMS sea la opción incorrecta, pero hay alternativas que pueden serle útiles o mejores. –

0

que evitaría la duplicación de datos, ya continuación, se encuentra con todo tipo de problemas con la fusión de las diferencias.

el truco para esto son las referencias.

el resultado es que tendría que cada objeto contiene una colección de referencias al otro tipo de objeto, así como tener una colección independiente de los otros objetos.

La tabla correspondiente es un concepto relacional, a menos que esa clase de conexión intermediaria pueda tener propiedades que no sean atribuibles a ninguno de los objetos. Está allí ya que permite escribir las consultas de una manera poderosa, ya que reduce la relación con 2 relaciones de uno a muchos y reduce en gran medida la duplicación de datos. Si hicieras esto en una base de datos de relaciones sin la tabla correspondiente, las cosas se pondrían mal rápidamente: ¿cómo funcionaría una actualización? Personalmente creo que la atracción de las bases de datos oo es alejarse de este

la forma en que vincularía todos los objetos es a través de eventos en el código a algún tipo de controlador de transacciones para permitir el almacenamiento en caché de los estados de los objetos. por lo tanto, en lugar de que los objetos manipulen las propiedades de los demás, solicitan un cambio a través del controlador y esperan el resultado en una devolución de llamada.

8

En realidad, solo hay dos maneras en que puedo pensar para resolver este problema, que usted mencionó. Personalmente, iría con el primer enfoque (creando un objeto de mapeo como una entidad OO). Esto le impide mantener información redundante y tener que sincronizar; también significa que si la asociación termina teniendo campos propios (la fecha en que el libro fue asignado a esa categoría, digamos), pueden incorporarse fácilmente. Usamos este enfoque para una variedad de asociaciones en nuestro sistema.

Las entidades OO se vería así:

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

Aquí usted tiene que mantener la relación de objeto y las dos colecciones en sincronía; sin embargo, las colecciones son opcionales en este caso. Normalmente, usted podría obtener la misma información con una consulta ORM, algo así como: seleccione b.book de BookCategory b donde b.category = MyCategory

La alternativa es tener una configuración como:

Book { 
Collection<Category> categories 
} 

Category { 
Collection<Books> books 
} 

Si su herramienta ORM/DB mantiene automáticamente las asociaciones, esto está bien; de lo contrario, estás atascado actualizando ambas colecciones. (En Hibernate, un lado tendrá la propiedad: Inverse = true en el mapeo; este lado no se actualiza, por lo que estrictamente no es necesario mantenerlo. Sin embargo, esto me parece una mala práctica)

Si normalmente solo accede a la relación de una manera (por ejemplo, obteniendo todos los libros en una categoría), puede eliminar la colección del otro lado; entonces creo que tendrías que trabajar con la herramienta ORM y usar una consulta nativa para acceder a la relación desde la otra dirección.

Usamos Hibernate (una herramienta de mapeo relacional de objetos basada en Java) en nuestro proyecto; los documentos de Hibernate son una buena referencia para OO/problemas de diseño relacional, aunque es posible que deba dedicar un poco de tiempo a aprender sobre Hibernate para que sean útiles: http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues

HTH!

+0

Debo mencionar que no estoy familiarizado con db40; esta respuesta se aplica en general al problema de ORM que está describiendo, espero =) – RMorrisey

+0

+1 gracias por la respuesta y los consejos de hibernación – paul

Cuestiones relacionadas