Las bases de datos orientadas a documentos (particularmente RavenDB) me intrigan realmente, y estoy deseando jugar con ellas un poco. Sin embargo, como alguien que está muy acostumbrado al mapeo relacional, estaba tratando de pensar cómo modelar los datos correctamente en una base de datos documental.¿Cómo modelizaré los datos que son heirarchal y relacionales en un sistema de base de datos orientado a documentos como RavenDB?
Decir que tengo un CRM con las siguientes entidades en mi aplicación de C# (dejando de lado las propiedades que no sean necesarios):
public class Company
{
public int Id { get; set; }
public IList<Contact> Contacts { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Contact
{
public int Id { get; set; }
public Company Company { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Task
{
public int Id { get; set; }
public Company Company { get; set; }
public Contact Contact { get; set; }
}
Estaba pensando en poner todo esto en un documento Company
, los contactos o las tareas no tienen un propósito fuera de las empresas, y la mayoría de las veces la consulta de una tarea o contactos también mostrará información sobre la compañía asociada.
El problema viene con las entidades Task
. Supongamos que el negocio requiere que una tarea esté SIEMPRE asociada con una empresa pero opcionalmente asociada a una tarea.
En un modelo relacional esto es fácil, ya que sólo hay una mesa Tasks
y tienen la Company.Tasks
se refieren a todas las tareas de la empresa, mientras que Contact.Tasks
sólo muestra las tareas para la tarea específica.
Para modelar esto en una base de datos documental, pensé en los siguientes tres ideas:
Tareas modelo como un documento separado. Esto parece una especie de documento anti-documentos ya que la mayoría de las veces que miras a una empresa o contacto querrás ver la lista de tareas, por lo que debes realizar muchas más entregas de documentos.
Mantenga las tareas que no están asociadas con un contacto en la lista
Company.Tasks
y coloque las tareas asociadas con un contacto en la lista para cada contacto individual. Desafortunadamente, esto significa que si desea ver todas las tareas para una empresa (que probablemente será mucho), debe combinar todas las tareas para la empresa con todas las tareas para cada contacto individual. También veo que esto es complicado cuando desea desasociar una tarea de un contacto, ya que debe moverlo del contacto a la compañíaMantenga todas las tareas en la lista
Company.Tasks
, y cada contacto tiene una lista de identificación valores para las tareas a las que está asociado. Esto parece un buen enfoque, excepto para tener que tomar manualmente los valores de identificación y tener que hacer una sub-lista de entidadesTask
para un contacto.
¿Cuál es la forma recomendada de modelar estos datos en una base de datos orientada a documentos?
Ok, así que supongo que estaba tomando la desnormalización demasiado lejos, pero ¿dividirlas renunciar a las ventajas de un documento basado en db, ya que tendría que tener que hacer uniones entre documentos constantemente? – KallDrexx
no lo hará porque estos índices son muy rápidos y la carga db.Load ocurre en el servidor, por lo que el costo es mínimo. Debería considerar dónde están sus límites transaccionales y utilizar este método solo cuando realmente lo necesita, pero significa que puede obtener realmente los beneficios de ambos mundos. Olvidé mencionar que actualizar las referencias desnormalizadas (si el nombre cambia, por ejemplo) necesita ejecutar un parche para actualizar las referencias. De nuevo, esto es muy simple, pero es un proceso que debe administrar. Encuentro que este es un pequeño costo que es superado masivamente por los beneficios de un DB sin esquema :) –
iwayneo
Eso tiene sentido :). Me gusta mucho la idea de las bases de datos de documentos (y, lo que es más importante, sin esquemas). ¡Gracias! – KallDrexx