OK, creo que es necesario dividir esto en las "variedades" básicas.
Tiene dos "entidad" al estilo de los objetos:
Tienes un "mapeo" al estilo de objeto:
Usted tiene una "transaccional" objeto de estilo:
Paso 1: Entidad
Vamos a empezar con las más fáciles: User
& Campaign
. Estos son realmente dos objetos separados, ninguno de los dos depende realmente del otro para su existencia. Tampoco hay una jerarquía implícita entre los dos: los usuarios no pertenecen a las campañas, ni las campañas pertenecen a los usuarios.
Cuando tiene dos objetos de nivel superior como este, generalmente ganan su propia colección. Por lo tanto, querrá una colección Users
y una colección Camapaigns
.
Paso 2: cartografía
UserCampaign
se utiliza actualmente para representar un mapeo-N-a M. Ahora, en general, cuando tiene una asignación N-a-1, puede poner el N dentro de 1. Sin embargo, con la asignación N-a-M, generalmente debe "elegir un lado".
En teoría, se podría hacer una de las siguientes:
- Ponga una lista de
Campaign ID
s en el interior de cada User
- Ponga una lista de
Users ID
s en el interior de cada Campaign
Personalmente, haría el # 1. Probablemente tenga mucho más usuarios que hagan campañas, y probablemente quiera poner la matriz donde será más corta.
Paso 3: transaccional
clics es realmente una bestia completamente diferente. En términos de objeto, podría pensar lo siguiente: Clicks
"pertenecer a" un User
, Clicks
"pertenecer a" un Campaign
. Entonces, en teoría, usted podría simplemente almacenar los clics que son parte de cualquiera de estos objetos. Es fácil pensar que los clics pertenecen al bajo Usuarios o Campañas.
Pero si realmente profundizas más, la simplificación anterior es realmente defectuosa. En su sistema, Clicks
son realmente un objeto central. De hecho, es posible que incluso pueda decir que las campañas de los usuarios & están realmente "asociadas con" el clic.
Eche un vistazo a las preguntas/consultas que está haciendo. Todas esas preguntas en realidad se centran en los clics. Usuarios & Las campañas no son el objeto central en sus datos, los clics son.
Además, los clics serán los datos más abundantes en su sistema. Tendrás más clics que cualquier otra cosa.
Este es el problema más grande cuando se diseña un esquema para datos como este. A veces es necesario expulsar objetos "parentales" cuando no son lo más importante. Imagine construir un sistema simple de comercio electrónico. Está claro que orders
"pertenece" a users
, pero orders
es tan central para el sistema que va a ser un objeto de "nivel superior".
envolviéndolo
Usted probablemente querrá tres colecciones:
- usuario -> tiene lista de campaign._id
- Campaña
- Clicks -> contiene user._id , campaign._id
Esto debería satisfacer a todos ustedes ur consulta necesita:
ver la información de cada clic como IP, Referer, sistema operativo, etc
db.clicks.find()
ver cuántas veces los clics provienen de X IP, X Referer, X OS
db.clicks.group()
o ejecuta un Map-Reduce.
asociar cada clic en un usuario y una campaña
db.clicks.find({user_id : blah})
También es posible empujar clic en ID de los usuarios y de las campañas (si eso tiene sentido).
Tenga en cuenta que si tiene muchos clics, realmente tendrá que analizar las consultas que ejecuta más. No puede indexar en todos los campos, por lo que a menudo querrá ejecutar Map-Reduces para "acumular" los datos para estas consultas.
¡Gracias por la gran respuesta! Realmente me ayudó a entender en qué debería pensar al diseñar mis esquemas –
Esta es una gran explicación. Deberías moverlo a un blog :). Dicho esto, ¿qué tan bien funcionará esto en MongoDB si necesita leer los datos cada pocos segundos con los hallazgos anteriores? ¿Mongo es la mejor solución en tal situación o alguna otra base de datos lo manejará mejor? – retrobrain
Depende, ¿está leyendo las tres colecciones o solo * algunas * de las colecciones?¿Qué consultas estás realizando? –