¿Es MongoDB la elección correcta en mi caso? [cerrado]

9

Voy a construir mi primer proyecto real en Rails que consiste en una aplicación web compuesta de 3 partes principales:

  • La parte estática donde no se utiliza ninguna base de datos.
  • La parte de registro de usuario que requerirá una base de datos y puedo usar MySQL ya que la fila de cada usuario tendrá los mismos campos
  • La "aplicación" donde los usuarios podrán crear, organizar, editar ... elementos en colecciones y compartirlos con otros usuarios

Habrá varios tipos de elementos y cada uno tendrá diferentes opciones, por ejemplo, puedo tener elementos de "video" con las siguientes opciones:

  • carné de identidad
  • ID_usuario
  • colección_id
  • título
  • plataforma (si está integrada)
  • url (si está incrustado)
  • nombre de archivo (si está alojado en mi aplicación)
  • tamaño de archivo (ID alojado en mi aplicación)

y elementos de "mapa":

  • carné de identidad
  • ID_usuario
  • colección_id
  • título
  • plataforma (google maps, bing maps ...)
  • ubicación
  • url
  • Tamaño de mapa

Como puede, mientras que para los usuarios puedo usar MySQL para los elementos, la flexibilidad de MongoDB puede ser útil ya que cada elemento puede necesitar diferentes opciones que otro elemento

Hasta ahora siempre he usado PHP y MySQL (siempre en hosting compartido para pequeños proyectos) y la escalabilidad es una palabra totalmente nueva para mí.

Tengo tiempo para aprender, pero me gustaría poder hacer algo concreto en algo así como 1 mes.

He leído mucho sobre MongoDB y NoSQL vs RDMS y MySQL y después de probarlo tengo que decir que me gusta cómo funciona MongoDB: sin tablas, sin filas y sus documentos JSON así:

  • En mi situación, ¿qué le recomendarías? ¿por qué?
  • ¿Sobre la escalabilidad puede haber problemas con MongoDB? En caso afirmativo, ¿cuándo (en términos de tamaño de base de datos) y estos problemas pueden ralentizar mi aplicación considerablemente?

Editar: cómo funcionará la aplicación

Como muchos preguntaron, así es como me gustaría que funcionara la aplicación:

  1. Un usuario se registra
  2. Ha iniciado sesión
  3. Creó su primera colección junto con la cual puede crear infinitos artículos.
  4. Los elementos son de varios tipos y cada tipo necesita datos diferentes para guardarse en la base de datos y el tipo de elementos puede agregarse o modificarse

Los usuarios pueden crear otras colecciones y artículos dentro de él.

Entonces tenemos CRUD para colecciones y artículos dentro de ellos y cada colección / artículo se refiere a un usuario específico

El principal problema con MySQL es que no tiene un esquema flexible, ¿hay alguna forma de resolver esto (una solución?)?

Pensando en NoSQL, la única duda que tengo es acerca de unirse, por ejemplo, dada una cierta colección, quiero recuperar datos relacionados con el usuario con el campo id = user_id en la colección

EDITAR: idea para seguir usando MySQL

Cree un campo en la tabla de "elementos" con configuraciones opcionales, cada configuración dividida por un | u otro símbolo

Luego guardaré en algún lugar una estructura de la configuración opcional de cada elemento, por ejemplo, el tipo de elemento "notes" necesita dos configuraciones opcionales "color" y "strange_setting", cuando obtenga los datos de MySQL dividiré el campo para configuraciones opcionales en un matriz sabiendo que el primer elemento de la matriz es para "color" y así sucesivamente.

¿Qué piensas? ¿Hay algún problema con esa solución? tienes otras ideas

Matteo Pagliazzi
fuente
44
Las preguntas de Matteo sobre recomendaciones tecnológicas están fuera de tema, a menos que nos presente un problema específico que está tratando de resolver. Deberá darnos un poco más de información sobre su proyecto y sobre por qué cree que necesita usar cualquier otra base de datos que no sea MySQL (que es con la que está familiarizado). Por ejemplo: ¿Hay problemas de escalabilidad y cuánto tiempo tiene para investigar nuevas tecnologías? Considere la posibilidad de revisar su pregunta y, si lo hace, márquela con atención moderada para que podamos revisar sus ediciones.
Yannis

Respuestas:

10

Es posible que no podamos ayudarlo hasta que nos diga qué piensa hacer con la aplicación. Las bases de datos relacionales son buenas para ciertas cosas, y las bases de datos NoSQL son buenas para otras.

Como alguien me dijo una vez aquí sobre SO:

la parte relacional de una base de datos relacional está mucho más optimizada que otras partes

Significa que también puede usar una base de datos relacional si parece encajar con sus casos de uso. No siga adelante con MongoDB debido a su flexibilidad / escalabilidad. Esta es la primera línea sobre MongoDB en Wikipedia:

MongoDB (de "humongous") es un sistema de base de datos NoSQL orientado a documentos de código abierto.

¿Realmente tiene la intención de utilizar una base de datos orientada a documentos? Si hay algo de grafismo en sus casos de uso, entonces puede ir a una base de datos de grafos como Neo4j. O bien, puede usar lo mejor de SQL y NoSQL juntos, como lo hacen algunas personas.

Por cierto, también estoy haciendo un proyecto en el que utilizo las mejores partes de SQL y NoSQL.

EDITAR: digo una vez más:

Consulte la sección Neo4j vs Hadoop en este artículo. Dice:

En principio, Hadoop y otras tiendas Key-Value se ocupan principalmente de estructuras de datos relativamente planas . Es decir, son extremadamente rápidos y escalables con respecto a la recuperación de objetos simples, como valores, documentos o incluso objetos.

Refiriéndose al mismo artículo, ¿realmente necesita una estructura de datos plana para la que va a utilizar MongoDB? Esto eventualmente depende de sus casos de uso detallados, cómo se llevarán a cabo los pasos 3 y 4.

Además, es posible que desee consultar estas preguntas:

/programming/2124274/mongodb-what-to-know-before-using

/programming/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems

( Echa un vistazo a la respuesta superior / seleccionada de la segunda pregunta con seguridad. Estás en ese dilema que esto podría resolver ) .

Supongo que estas preguntas tienen toda la información que querías saber. Al final, es usted quien tendrá que decidir si es MongoDb o algo más, solo podemos recomendarlo. Las únicas personas que conocen sus casos de uso detallados son usted y su equipo.

EDITAR DE NUEVO (para la parte de MySQL): tal como lo he entendido, está planeando almacenar algo en la base de datos y separarlos a través de un separador. Esto presenta 2 problemas:

  1. Además, debe manejar cualquier entrada que tenga el separador.
  2. La parte de almacenamiento relacional de una base de datos relacional está mucho más optimizada que la parte de coincidencia de cadenas. No elegiría un esquema en el que deba hacer una coincidencia de cadenas en una base de datos para obtener un resultado específico. Nuevamente estoy estresando:

    La parte relacional de una base de datos relacional está mucho más optimizada que otras partes (por ejemplo, la coincidencia de cadenas)

  3. No use atributos multivalor. La gente generalmente los teme.
c0da
fuente
principalmente iba a usar MongoDB por su esquema flexible, pero tengo algunas dudas ya que no tiene unirse. De todos modos, en mi aplicación tendré una base de datos para usuarios y luego una creda básica donde cada elemento está asociado a un usuario y una colección de elementos
Matteo Pagliazzi
No necesitará unirse a mongo, pero deberá planificar su esquema. Piensa en términos de objetos en lugar de tablas si usas mongo. Luego piense cómo accederá a sus objetos.
ltfishie
8

Veo mucho esta pregunta. Siempre parece ser considerado como o / o. MongoDB es una gran herramienta nueva. También a veces parece ser la herramienta brillante para todo y eso puede ser una mala elección en mi experiencia.

Creo que la mejor combinación es definitivamente AMBAS y me gustaría felicitarlo por su enfoque de usar mylsql para algunas partes, como los usuarios, pero use MongoDB para otras partes, ya que siento que la autenticación y la autorización se hacen mejor con mySQL y hay Un montón de ejemplos y módulos que hacen esto realmente bien.

Para la pieza 'gran número de elementos', es allí donde debería considerar usar mongoDB si su volumen es alto, y / o se trata principalmente de lecturas y / o datos no estructurados.

Aconsejaría no basar su decisión en la flexibilidad sin esquema de Mongo. Los esquemas SQL y sql surgieron de la necesidad de tener datos estructurados y poder realizar cálculos y transformaciones que solo son posibles con dicha estructura. Aprendí esto después de 5 años de trabajar en un rol de almacén de datos. Solo miraría a MongoBD por el problema de rendimiento. Si espera o espera un gran volumen de usuarios y solicitudes, digamos 100,000 usuarios y 20 solicitudes por segundo, usaría mongoDB, de lo contrario, trataría de permanecer con sql. En muchos casos, usaría mySQL para un volumen bajo y luego, como volumen, ingresos e infraestructura lo soportan, cambiaría a Oracle, antes de mezclarlo en mongoDB. Estoy de acuerdo en que no debe tratar con los problemas de volumen antes de experimentarlos, sin embargo, si tiene una idea justa de hacia dónde se dirige y no No quiero volver a escribir las cosas a mitad de camino, tiene mucho sentido elegir las tecnologías correctas desde el principio. Solo recuerde que si realmente tiene ese alto volumen, hay una gran cantidad de opciones y tecnologías en todos los niveles de la pila que buscará usar.

Hay inconvenientes para los datos estructurados libremente. Yo uso la analogía del estacionamiento aquí. no hay líneas divisorias es genial para los primeros 3 autos que ingresan, pero a medida que ingresan más autos, comienza a ocurrir una gran desorganización e intentar estacionarse o contar fácilmente los autos y mantener los carriles libres se convierte en una pesadilla. Organizar esto requiere trabajo por adelantado, marcando líneas y divisores y flujos de tráfico, etc. pero vale la pena. A veces las cosas cambian, por supuesto (los autos se hacen más grandes) y usted tiene que hacer algunos cambios: repintar las líneas. Además, solo tiempo de inactividad estándar para reparaciones y mantenimiento anuales.

El aspecto del diseño del esquema probablemente será el mayor obstáculo para los usuarios tradicionales de mysql. Creo que la página de MongoDb sobre diseño de esquemas ayuda con eso. Mi punto final es que cada tecnología que agregue a la mezcla agrega complejidad. A menudo hay grandes defensores de cualquier pieza que diga que "tienes" que usarla, pero he descubierto que un factor realmente importante es cuántas piezas hay. Implica más posibles puntos de falla y, sobre todo, más de una base de conocimiento necesaria para que cualquier otra persona tenga que saber para trabajar en ella.

fyi Rick Obsorne tiene un diagrama de comparación bastante sorprendente que es bastante único.

Michael Durrant
fuente
ese es mi primer proyecto real en rieles: es un hobby y por ahora no sé si será un éxito o un fracaso, mi primer objetivo aquí es ser conocido con rieles para que no pueda hablar de tráfico. Las lecturas no serán primarias, también tendré muchos datos nuevos y uno actualizado ...
Matteo Pagliazzi
1
Lo bueno de mongodb es que no hay un esquema fijo, por lo que para un proyecto de pasatiempo hay menos trabajo de configuración. El esquema puede evolucionar con el tiempo y no tiene que dar el paso adicional de actualizar las tablas SQL.
Kevin
no estoy seguro acerca de mi -1 o por qué 0 malos consejos o no estoy de acuerdo?
Michael Durrant
De todos modos, si este es su primer proyecto en rails, me quedaría con mySQL. Hay MUCHO que aprender en los rieles, mucho más de 1 mes una vez que comienzas a bajar las cortinas.
Michael Durrant
@michael mira mi última actualización
Matteo Pagliazzi el
3

Veo muchos argumentos válidos aquí para NoSQL vs MySQL. Sin embargo, falta un enlace sobre la escala: si realmente desea escalar y desea hacerlo con una base de datos interna, necesitará MUCHO conocimiento sobre las bases de datos. Hay demasiadas historias de terror por ahí donde las personas han fallado al tratar de implementar un sistema que escalará infinitamente.

Si realmente elige ir a la ruta NoSQL (y está listo para asumir los costos que conlleva, como no unirse), considere AWS DynamoDB (http://aws.amazon.com/dynamodb/). Aquí puede olvidarse de la parte completa de la escala de la base de datos y concentrarse en su aplicación. Buena suerte.

Descargo de responsabilidad: soy desarrollador del equipo de AWS DynamoDB, pero realmente creo en nuestro producto. Pruébalo :)

Subu Sankara Subramanian
fuente
1

Entonces, su diseño puede guardar en su base de datos dos tipos diferentes de objetos:

  • Objeto de usuario (que siempre tiene los campos).
  • Objetos de aplicaciones (que pueden tener diferentes campos). Una aplicación pertenecerá a un solo usuario.

Una colección podría o no hacerse como un objeto diferente, ya que es solo una etiqueta para agrupar diferentes aplicaciones. En aras de la discusión, digamos que no hay colecciones y los usuarios solo tienen una lista de aplicaciones.

Si bien creo que se puede lograr en MySQL, en MongoDB tendrá una mayor flexibilidad en términos de la estructura de los objetos de la aplicación, y probablemente mapeará de forma más natural su representación en la base de datos, simplificando el código.

En MySQL tendrás problemas para manejar diferentes formatos para diferentes aplicaciones, pero es posible. Algunas ideas:

  • Puede crear una tabla intermedia con toda la información común entre todos los objetos (id, user_id, title, etc.), luego el tipo, para que pueda buscarla en otra tabla con solo los campos no comunes para ese formato (p. Ej. nombre_archivo y tamaño_archivo para archivos). Deberá crear una tabla diferente para cada formato diferente. Si ambas tablas están indexadas por app_id (Clave primaria), será lo suficientemente rápido, ya que acceder a una tabla por un valor indexado es rápido.
  • Puede codificar los datos en algún formato y almacenarlos estandarizados. Por ejemplo, codifique los datos no comunes en JSON como una cadena y almacénelos en un campo VARCHAR. Tenga cuidado con el tamaño de ese campo para no quedarse sin espacio. El formato puede ser complejo (JSON) o simple (solo valores separados por comas)
  • Puede crear diferentes campos "genéricos", algo así como int1, int2, str1, str2, y definir que str1 para un tipo de aplicación es "nombre_archivo", mientras que para un tipo diferente podría ser "ubicación".

En MongoDB, podría ser tan simple como usar dos colecciones de MongoDB, una para los usuarios y otra para las aplicaciones. Suponiendo algún tipo de límite (que no es el caso, como lo describió, sino solo por decir), incluso podría almacenar las aplicaciones dentro del objeto de usuario, como una lista. Almacenar y recuperar los datos es más natural, ya que puede almacenar cualquier tipo de objeto, sin importar cuáles sean los campos. Puede buscar por user_id para obtener todas las aplicaciones que pertenecen a un usuario. En MongoDB pierdes de todos modos la posibilidad de hacer consultas de combinación, pero en este caso creo que las consultas básicas serán recuperar al usuario y recuperar las aplicaciones relacionadas con el usuario. Si planea hacer muchas cosas como "darme los usuarios que tienen más de dos colecciones con tres aplicaciones o menos en cada una", tendrá que generarlo no como una consulta de unión, pero como un proceso en código, será menos natural que en una base de datos relacional y puede llevar más tiempo procesarlo. Si desea buscar parámetros (por ejemplo, darme todas las aplicaciones que pertenecen a un usuario en particular; darme todas las aplicaciones que son de tipo X), eso es bastante fácil en MongoDB y no necesita usar combinaciones.

No estoy seguro del soporte de MongoDB on Rails. Lo he usado en Python y JavaScript.

EDITAR: se agregó un comentario sobre el tiempo al acceder a dos tablas y otra opción de MySQL

Khelben
fuente
no me gusta la segunda opción para usar MySQL para almacenar configuraciones opcionales porque creo que puede cargar cada fila con muchos bytes no necesarios ... para la segunda: ralentizará mucho mi aplicación para cargar dos filas de dos tablas diferentes para cargar un artículo?
Matteo Pagliazzi
por favor vea mi última actualización
Matteo Pagliazzi
Acerca de su pregunta sobre la velocidad, no debería ser mucho más lenta (está accediendo a ella a través de un valor único indexado). También edité mi respuesta, ya que la última propuesta editada es similar a la primera idea, y agregué otra opción.
Khelben
1

Yo diría que use la tecnología que mejor conoce, especialmente si es un proyecto real y desea impulsarlo rápidamente. El uso de MySQL y Mongo vendrá con sus propios beneficios y dolores de cabeza. Después de haber trabajado con ambos, también agregaría que no es muy difícil migrar de MySQL a Mongo si sigue buenos principios de diseño.

Dicho esto, una buena razón para usar MongoDB en su caso son sus datos. Como ha mencionado, tendrá varios tipos diferentes de entrada para sus colecciones: mapa, video, etc. Si tuviera que implementar esto usando RDBMS, tiene 3 enfoques:

  • tabla por tipo: cada tabla contiene columnas específicas para cada tipo de objetos

    Desventajas : N consulta para buscar en todos los tipos de datos.

    Ventajas : buen diseño OO, fácil de mantener

  • tabla única: una tabla enorme que contiene todos los atributos posibles para todos los tipos, y la mayoría de ellos son nulos para cualquier entrada en particular

    Desventajas : el cambio a cualquier objeto requerirá alterar la tabla, doloroso una vez que la tabla se vuelve grande. Difícil de mantener.

    Ventajas : Fácil de implementar.

  • tabla principal con metadatos: tiene una sola tabla con los atributos principales, por ejemplo, título, fechas y una tabla de metadatos con pares clave-valor para atributos adicionales

    Desventajas : dos consultas para obtener todos los datos de un solo objeto.

    Ventajas : Extremadamente flexible, no muy difícil de implementar.

He usado cada uno de estos enfoques antes, y puedo decir que ninguno es tan natural trabajando con Mongo. Sus datos probablemente se verán así:

{_id:"collection1",
 name:"My first Collection",
 owner: "user123243342",
 entries: [
    {type:"video",
     url: "http://www.youtube.com/234324",
     tags: ["roadtrip", "fun", "camera"]
     },
    {type:"map",
     coordinates: [LOC: [38, –102], LOC: [43, –33], LOC: [228, –102]],
     description: "Road trip to nowhere",
 ]
}

Pero realmente no tendrá que preocuparse por el diseño del esquema, ya que los objetos de su dominio pueden persistir directamente como tales. MongoDB es esencialmente su almacén de objetos contra el que puede consultar.

Noté que he dejado de lado cualquier discusión sobre la comparación de rendimiento entre MySql y Mongodb. Si bien siempre debe tener en cuenta el rendimiento, no podrá tomar decisiones de manera efectiva a menos que conozca el patrón de acceso a datos. Cualquier buen proyecto probablemente pasará por algunas iteraciones de refactorización a medida que crezca y surjan nuevos desafíos. No se preocupe por el rendimiento antes de tiempo y elija la herramienta que mejor conoce y comience a codificar.

Editar

Para responder a su pregunta específica sobre el uso de MySQL y mantener los atributos en el mismo campo usando "|". No hagas esto. Este enfoque le dará más problemas de los que resuelve. En primer lugar, no podrá consultar contra atributos individuales utilizando MySql. Segundo, agrega demasiada complejidad a su capa de acceso a datos. Utilice el enfoque de tipo por tabla o metadatos en su lugar. Si trabajó anteriormente con WordPress, utiliza el enfoque de metadatos:

  • tabla de usuario + usemeta para usuario
  • post table + postmeta table post

Esto hace que la estructura de datos sea extremadamente flexible y aún pueda consultarse con una velocidad razonable.

ltfishie
fuente
no me gusta la opción de metadatos ... pero estoy pensando en la tabla individual con campos que quedan nulos si no se usan
Matteo Pagliazzi
El enfoque de tabla única es probablemente el peor del grupo. Si bien puede hacer todo en una sola consulta, cualquier cambio en cualquier tipo de datos requerirá una tabla alternativa. Y es un dolor en mysql una vez que tu mesa se hace grande.
ltfishie
0

El siguiente artículo proporciona buenos resultados al comparar MySQL y MongoDB en términos de selección, recuperación e inserción, considerando la cantidad de datos en la base de datos y la cantidad de datos recuperados. Los resultados muestran un gran rendimiento para MongoDB con respecto a los "insertos", pero en los otros casos MySQL gana. Vea abajo:

http://www.moredevs.ro/mysql-vs-mongodb-performance-benchmark/

Tuve una experiencia usando MongoDB que creo que fue una buena solución. Lo usé para insertar miles de colecciones todos los días. En combinación con la solución Solr (solución de caché, actualizada una vez al día), puedo recuperar los datos de MongoDB por la identificación de la colección cuando sea necesario, por lo que no necesito selecciones sobre la marcha. Entonces, teniendo en cuenta que tiene que lidiar con muchos insertos y no necesita preocuparse por seleccionar y buscar, MongoDB podría ser una gran idea, dependerá de cada caso y de hacer un buen análisis.

Rogerio Hilbert
fuente