Daniel Coupal

16 results

Construyendo con patrones: un resumen

Al concluir la serie Construyendo con patrones, es una buena oportunidad para recapitular los problemas que resuelven los patrones que se han cubierto y resaltar algunos de los beneficios y compensaciones que tiene cada patrón. La pregunta más frecuente que se hace sobre los patrones de diseño de esquemas es "Estoy diseñando una aplicación para hacer X, ¿cómo modelo los datos?" Como esperamos que haya descubierto a lo largo de esta serie de blogs, hay muchas cosas a tener en cuenta para responder a esa pregunta. Sin embargo, hemos incluido un gráfico de casos de uso de muestra que nos ha parecido útil para al menos proporcionar una guía inicial sobre patrones de modelado de datos para casos de uso genéricos. Casos de uso de muestra El siguiente cuadro es una guía de lo que hemos encontrado después de años de experiencia trabajando con nuestros clientes sobre qué patrones de diseño de esquemas se utilizan en una variedad de aplicaciones. Este no es un conjunto de reglas “escritas en piedra” sobre qué patrón de diseño se puede utilizar para un tipo particular de aplicación. Asegúrese de mirar los que se usan con frecuencia en su caso de uso. Sin embargo, no descartes los demás, es posible que aún se apliquen. La forma en que diseña el esquema de datos de su aplicación depende en gran medida de sus patrones de acceso a los datos. Resúmenes de patrones de diseño Aproximación El patrón de aproximación es útil cuando con frecuencia se realizan cálculos costosos y cuando la precisión de esos cálculos no es la máxima prioridad. Ventajas Menos escrituras en la base de datos. Mantener números estadísticamente válidos. Contras No se representan números exactos. La implementación debe realizarse en la aplicación. Atributo El patrón de atributos es útil para problemas que se basan en tener documentos grandes con muchos campos similares, pero hay un subconjunto de campos que comparten características comunes y queremos ordenar o consultar ese subconjunto de campos. Cuando los campos que necesitamos ordenar solo se encuentran en un pequeño subconjunto de documentos. O cuando ambas condiciones se cumplen en los documentos. Ventajas Se necesitan menos índices. Las consultas se vuelven más sencillas de escribir y, en general, más rápidas. Balde Patron de cubo es una excelente solución cuando se necesita gestionar la transmisión de datos, como series temporales, análisis en tiempo real o aplicaciones de Internet de las cosas (IoT). Ventajas Reduce el número total de documentos de una colección. Mejora el rendimiento del índice. Puede simplificar el acceso a los datos aprovechando la agregación previa. Calculado Cuando hay patrones de acceso a datos intensivos en lectura y la aplicación debe calcular los datos repetidamente, el patrón calculado es una excelente opción para explorar. Ventajas Reducción de la carga de trabajo de la CPU para cálculos frecuentes. Las consultas se vuelven más sencillas de escribir y, en general, más rápidas. Contras Puede resultar difícil identificar la necesidad de este patrón. Se debe evitar aplicar o abusar del patrón a menos que sea necesario. Versiones de documentos Cuando se enfrenta a la necesidad de mantener versiones anteriores de documentos en MongoDB, el patrón de control de versiones de documentos es una posible solución. Ventajas Fácil de implementar, incluso en sistemas existentes. No hay impacto en el rendimiento de las consultas sobre la última revisión. Contras Duplica el número de escrituras. Las consultas deben dirigirse a la colección correcta. Referencia extendida Encontrará que el patrón de referencia extendida es más útil cuando su aplicación experimente muchas operaciones JOIN para reunir datos a los que se accede con frecuencia. Ventajas Mejora el rendimiento cuando hay muchas operaciones JOIN. Lecturas más rápidas y reducción del número total de JOIN. Contras Duplicación de datos. Parte aislada ¿Le parece que hay algunas consultas o documentos que no encajan en el resto de sus patrones de datos típicos? ¿Estas excepciones impulsan la solución de su aplicación? Si es así, el patrón de valores atípicos es una solución maravillosa para esta situación. Ventajas Evita que algunos documentos o consultas determinen la solución de una aplicación. Las consultas se adaptan a casos de uso "típicos", pero aún se abordan los valores atípicos. Contras A menudo se adaptan a consultas específicas, por lo que es posible que las consultas ad hoc no funcionen bien. Gran parte de este patrón se realiza con código de aplicación. Preasignación Cuando conoce la estructura de su documento y su aplicación simplemente necesita llenarla con datos, el patrón de asignación previa es la opción correcta. Ventajas Simplificación del diseño cuando se conoce de antemano la estructura del documento. Contras Simplicidad versus rendimiento. Polimórfico El Patrón Polimórfico es la solución cuando hay una variedad de documentos que tienen más similitudes que diferencias y los documentos necesitan mantenerse en una sola colección. Ventajas Fácil de implementar. Las consultas pueden ejecutarse en una única colección. Control de versiones de esquemas Prácticamente todas las aplicaciones pueden beneficiarse del patrón de control de versiones del esquema , ya que con frecuencia se producen cambios en el esquema de datos durante la vida útil de una aplicación. Este patrón permite que las versiones anterior y actual de documentos existan una al lado de la otra en una colección. Ventajas No se necesita tiempo de inactividad. Control de migración de esquemas. Reducción de la deuda técnica futura. Contras Es posible que necesite dos índices para el mismo campo durante la migración. Subconjunto El patrón de subconjunto resuelve el problema de que el conjunto de trabajo exceda la capacidad de la RAM debido a documentos grandes en los que gran parte de los datos del documento no están siendo utilizados por la aplicación. Ventajas Reducción del tamaño total del conjunto de trabajo. Tiempo de acceso al disco más corto para los datos utilizados con más frecuencia. Contras Debemos gestionar el subconjunto. Obtener datos adicionales requiere viajes adicionales a la base de datos. Árbol Cuando los datos tienen una estructura jerárquica y se consultan con frecuencia, el patrón de árbol es el patrón de diseño a implementar. Ventajas Mayor rendimiento al evitar múltiples operaciones JOIN. Contras Las actualizaciones del gráfico deben gestionarse en la aplicación. Conclusión Como esperamos que haya visto en esta serie, el modelo de documento de MongoDB proporciona mucha flexibilidad en la forma de modelar datos. Esa flexibilidad es increíblemente poderosa, pero ese poder debe aprovecharse en términos de los patrones de acceso a datos de su aplicación. Recuerde que el diseño de esquemas en MongoDB tiene un impacto tremendo en el rendimiento de su aplicación. Hemos descubierto que los problemas de rendimiento con frecuencia se deben a un diseño deficiente del esquema. Tenga en cuenta que para mejorar aún más el poder del modelo de documento, estos patrones de diseño de esquema se pueden usar juntos, cuando y si tiene sentido. Por ejemplo, el control de versiones de esquemas se puede utilizar junto con cualquiera de los otros patrones a medida que evoluciona la aplicación. Con los doce patrones de diseño de esquemas que se han cubierto, usted tiene las herramientas y el conocimiento necesarios para aprovechar el poder de la flexibilidad del modelo de documento.

October 2, 2023

Construindo com Padrões: Um Resumo

Ao encerrarmos a série Construindo com Padrões, é uma boa oportunidade para recapitular os problemas que os padrões abordados resolvem e destacar alguns dos benefícios e vantagens de cada padrão. A pergunta mais frequente sobre padrões de design de esquema é “Estou projetando um aplicativo para fazer X, como faço para modelar os dados?” Como esperamos que você tenha descoberto ao longo desta série de blogs, há muitas coisas a serem levadas em consideração para responder a isso. No entanto, incluímos exemplos de Charts de casos de uso que consideramos úteis para fornecer pelo menos alguma orientação inicial sobre padrões de modelagem de dados para casos de uso genéricos. Exemplos de casos de uso Os Charts abaixo são uma diretriz do que descobrimos após anos de experiência trabalhando com nossos clientes sobre quais padrões de design de esquema são usados em diversos aplicativos. Este não é um conjunto de regras “definidas” sobre qual padrão de design pode ser usado para um tipo específico de aplicação. Certifique-se de observar aqueles que são usados com frequência em seu caso de uso. No entanto, não descarte os outros, eles ainda podem ser aplicados. A maneira como você projeta o esquema de dados do seu aplicativo depende muito dos seus padrões de acesso aos dados. Resumos de padrões de design Aproximação O Padrão de Aproximação é útil quando cálculos caros são feitos com frequência e quando a precisão desses cálculos não é a prioridade mais alta. Prós Menos gravações no banco de dados. Mantenha números estatisticamente válidos. Contras Os números exatos não estão sendo representados. A implementação deve ser feita na aplicação. Atributo O Padrão de Atributo é útil para problemas baseados em documentos grandes com muitos campos semelhantes, mas há um subconjunto de campos que compartilham características comuns e queremos classificar ou consultar esse subconjunto de campos. Quando os campos que precisamos classificar são encontrados apenas em um pequeno subconjunto de documentos. Ou quando ambas as condições forem atendidas nos documentos. Prós Menos índices são necessários. As consultas tornam-se mais simples de escrever e geralmente mais rápidas. Balde O Bucket Pattern é uma ótima solução para quando você precisa managed dados de streaming, como Time Series, Real-Time Analytics ou aplicativos de Internet das Coisas (IoT). Prós Reduz o número total de documentos em uma collection. Melhora o desempenho do índice. Pode simplificar o acesso aos dados aproveitando a pré-agregação. Calculado Quando há padrões de acesso a dados com muita leitura e esses dados precisam ser computados repetidamente pelo aplicativo, o Padrão Computado é uma ótima opção a ser explorada. Prós Redução na carga de trabalho da CPU para cálculos frequentes. As consultas tornam-se mais simples de escrever e geralmente mais rápidas. Contras Pode ser difícil identificar a necessidade desse padrão. A aplicação ou uso excessivo do padrão deve ser evitado, a menos que seja necessário. Versionamento de documentos Quando você se depara com a necessidade de manter versões anteriores de documentos no MongoDB, o padrão Document Versioning é uma solução possível. Prós Fácil de implementar, mesmo em sistemas existentes. Nenhum impacto no desempenho nas consultas da revisão mais recente. Contras Dobra o número de gravações. As consultas precisam direcionar a collection correta. Referência estendida Você achará o padrão Extended Reference mais útil quando seu aplicativo estiver passando por muitas operações JOIN para reunir dados acessados com frequência. Prós Melhora o desempenho quando há muitas operações JOIN. Leituras mais rápidas e redução no número geral de JOINs. Contras Duplicação de dados. Ponto fora da curva Você acha que existem algumas consultas ou documentos que não se enquadram no restante dos seus padrões de dados típicos? Essas exceções estão orientando sua solução de aplicativo? Nesse caso, o Padrão Outlier é uma solução maravilhosa para esta situação. Prós Impede que alguns documentos ou consultas determinem a solução de um aplicativo. As consultas são adaptadas para casos de uso “típicos”, mas os valores discrepantes ainda são abordados. Contras Muitas vezes adaptado para consultas específicas, portanto, consultas ad hoc podem não ter um bom desempenho. Grande parte desse padrão é feito com código de aplicativo. Pré-alocação Quando você conhece a estrutura do seu documento e sua aplicação precisa simplesmente preenchê-lo com dados, o Padrão de Pré-Alocação é a escolha certa. Prós Simplificação do design quando a estrutura do documento é conhecida antecipadamente. Contras Simplicidade versus desempenho. Polimórfico O Padrão Polimórfico é a solução quando há uma variedade de documentos que possuem mais semelhanças do que diferenças e os documentos precisam ser mantidos em uma única collection. Prós Fácil de implementar. As consultas podem ser executadas em uma única collection. Versionamento de esquema Praticamente todos os aplicativos podem se beneficiar do Padrão de Versionamento de Esquema , já que alterações no esquema de dados ocorrem frequentemente durante a vida útil de um aplicativo. Esse padrão permite que versões anteriores e atuais de documentos existam lado a lado em uma collection. Prós Não é necessário tempo de inatividade. Controle de migração de esquema. Redução da dívida técnica futura. Contras Podem ser necessários dois índices para o mesmo campo durante a migração. Subconjunto O padrão de subconjunto resolve o problema de o conjunto de trabalho exceder a capacidade da RAM devido a documentos grandes que possuem muitos dos dados do documento que não estão sendo usados pelo aplicativo. Prós Redução no tamanho geral do conjunto de trabalho. Menor tempo de acesso ao disco para os dados usados com mais frequência. Contras Devemos managed o subconjunto. A obtenção de dados adicionais requer viagens adicionais ao banco de dados. Árvore Quando os dados são de uma estrutura hierárquica e são frequentemente consultados, o Tree Pattern é o padrão de design a ser implementado. Prós Maior desempenho evitando múltiplas operações JOIN. Contras As atualizações no gráfico precisam ser managed no aplicativo. Conclusão Como esperamos que você tenha visto nesta série, o modelo de documento MongoDB oferece muita flexibilidade na forma como você modela dados. Essa flexibilidade é incrivelmente poderosa, mas esse poder precisa ser aproveitado em termos dos padrões de acesso aos dados do seu aplicativo. Lembre-se de que o design do esquema no MongoDB tem um impacto tremendo no desempenho do seu aplicativo. Descobrimos que os problemas de desempenho podem frequentemente ser atribuídos a um design de esquema inadequado. Tenha em mente que para aumentar ainda mais o poder do modelo de documento, esses padrões de design de esquema podem ser usados juntos, quando e se fizer sentido. Por exemplo, o Schema Versioning pode ser usado em conjunto com qualquer outro padrão à medida que seu aplicativo evolui. Com os doze padrões de design de esquema abordados, você tem as ferramentas e o conhecimento necessários para aproveitar o poder da flexibilidade do modelo de documento.

October 2, 2023

How Much is Your Data Model Costing Your Business?

Economic volatility is creating an unpredictable business climate, forcing organizations to stretch their dollars further and do more with less. Investments are under the microscope, and managers are looking to wring every ounce of productivity out of existing resources. IT spend is a concern and many IT decision-makers aren't sure what's driving costs. Is it overprovisioning? Cloud sprawl? Shadow IT? One area that doesn't get a lot of attention is how the data is modeled in the database. That's unfortunate because data modeling can have a major impact in terms of the cost of database operations, the instance size necessary to handle workloads, and the work required to develop and maintain applications. This post is also available in: 简体中文 Pareto patterns Data access patterns are often an illustration of the Pareto Principle at work, where the majority of effects are driven by a minority of causes. Modern OLTP applications tend to work with data in small chunks. The vast majority of data access patterns (the way applications access and use data) work with either a single row of data or a range of rows from a single table. At least that's what we found at Amazon , looking at 10,000 services across all the various RDBMS based services we deployed. Normalized data models are quite efficient for these simple single table queries, but the less frequent complex patterns require the database to join tables to produce a result, exposing RDBMS inefficiencies. The high time complexity associated with these queries meant significantly more infrastructure was required to support them. The relational database hides much of this overhead behind the scenes. When you send a query to a relational database, you don't actually see all the connections opening up on all the tables, or all the objects merging. Even though 90% of the access patterns at Amazon were for simple things, the 10% that were doing more complex things were burning through CPU to the point that my team estimated they were driving ~50% of infrastructure cost. This is where NoSQL data modeling can be a game-changer. NoSQL data models are designed to eliminate expensive joins, reduce CPU utilization, and save on compute costs. Modeling for efficiency in NoSQL There are two fundamental approaches to modeling relational data in NoSQL databases: Embedded Document - All related data is stored in a single rich document which can be efficiently retrieved when needed. Single Collection - Related data is split out into multiple documents to efficiently support access patterns that require subsets of a larger relational structure. Related documents are stored in a common collection and contain attributes that can be indexed to support queries for various groupings of related documents. The key to building an efficient NoSQL data model and reducing compute costs is using the workload to influence the choice of data model. For example, a read-heavy workload like a product catalog that runs queries like, "get all the data for a product" or "get all the products in a category," will benefit from an embedded document model because it avoids overhead of reading multiple documents. On the other hand, a write-heavy workload where writes are updating bits and pieces of a larger relational structure would run more efficiently with smaller documents stored in a single collection which can be accessed independently and indexed to support efficient retrieval when all the data is needed. The final choice depends on the frequency and nature of the write patterns and whether or not there's a high velocity read pattern that's operating concurrently. If your workload is read-intensive, you want to get as much as you can in one read. For a write-intensive workload, you don't want to have to rewrite the full document every time it changes. Joins increase time complexity. In NoSQL databases, depending on the access pattern mix, all the rows from the relational tables are stored either in a single embedded document or as multiple documents in one collection that are linked together by indexes. Storing multiple related documents in a common collection means there is no need for joins. As long as you're indexing on a common dimension across documents, you can query for related documents very efficiently. Now imagine a query that joins three tables in a relational database and your machine needs to do 1,000 of them. You would need to read at least 3,000 objects from multiple tables in order to satisfy the 1,000 queries. With the document model, by embedding all the related data in one document, the query would read only 1,000 objects from a single collection. Machine wise, having to merge 3,000 objects from three tables versus reading 1,000 from one collection will require a more powerful and expensive instance. With relational databases, you don't have as much control. Some queries may result in a lot of joins, resulting in higher time complexity which translates directly into more infrastructure required to support the workload. Mitigate what matters In a NoSQL database, you want to model data for the highest efficiency where it hurts the most in terms of cost. Analytical queries tend to be low frequency. It doesn't matter as much if they come back in 100 ms or 10 ms. You just want to get an answer. For things that run once an hour, once a day, or once a week, it's okay if they're not as efficient as they might be in a normalized relational database. Transactional workloads that are running thousands of transactions a second need to process as efficiently as possible because the potential savings are far greater. Some users try to practice these data modeling techniques to increase efficiency in RDBMS platforms since most now support document structures similar to MongoDB. This might work for a small subset of workloads. But columnar storage is designed for relatively small rows that are the same size. They do work well for small documents, but when you start to increase the size of the row in a relational database, it requires off-row storage. In Postgres this is called TOAST (The Oversized-Attribute Storage Technique). This circumvents the size limit by putting the data in two places, but it also decreases performance in the process. The row based storage engines used by modern RDBMS platforms were not designed for large documents, and there is no way to configure them to store large documents efficiently. Drawing out the relationship The first step we recommend when modeling data is to characterize the workload by asking a few key questions: What is the nature of the workload? What is the entity relationship diagram (ERD)? What are the access patterns? What is the velocity of each pattern? Where are the most important queries that we need to optimize? Identifying the entities and their relationships to each other is going to form the basis of our data model. Once this is done we can begin to distill the access patterns. If it's a read heavy workload like the product catalog you'll most likely be working with large objects, which is fine. There are plenty of use cases for that. However, if you're working with more complex access patterns where you're accessing or updating small pieces of a larger relational structure independently, you will want the data separated into smaller documents so you can efficiently execute those high velocity updates. We teach many of these techniques in our MongoDB University course, M320: MongoDB Data Modeling . Working with indexes Using indexes for high-frequency patterns will give you the best performance. Without an index, you have to read every document in the collection and examine it to determine which documents match the query conditions. An index is a B-tree structure that can be parsed quickly to identify documents that match conditions on the indexed attributes specified by the query. You may choose to not index uncommon patterns for various reasons. All indexes incur cost as they must be updated whenever a document is changed. You might have a high velocity write pattern that runs consistently and a low velocity read that happens at the end of the day, in which case you'll accept the higher cost of the full collection scan for the read query rather than incur the cost of updating the index on every write. If you are writing to a collection 1,000 times a second and reading once a day, the last thing you want to do is add an index update for every single write just to make the read efficient. Again, it depends on the workload. Indexes in general should be created for high-velocity patterns, and your most frequent access patterns should be covered by indexes to some extent, either partially or fully. Remember that an index still incurs cost even if you don't read it very much or at all. Always make sure when you define an index that there is a good reason for it, and that good reason should be that you have a high frequency access pattern that needs to use it to be able to read the data efficiently. Data modeling and developer productivity Even after you've optimized your data model, cost savings will continue to accrue downstream as developers find that they can develop, iterate, and maintain systems far more efficiently than in a relational database. Specific document design patterns and characteristics of NoSQL can reduce maintenance overhead and in many cases eliminate maintenance tasks altogether. For example, document databases like MongoDB support flexible schema which eliminates the need for maintenance windows related to schema migrations and refactoring of a catalog as with RDBMS. A schema change in a relational database almost always impacts ORM data adapters that would need to be refactored to accommodate the change. That's a significant amount of code maintenance for developers. With a NoSQL database like MongoDB, there's no need for cumbersome and fragile ORM abstraction layers. Developers can store object data in its native form instead of having to normalize it for a tabular model. Updating data objects in MongoDB requires almost zero maintenance. The application just needs to be aware documents may have new properties, and how to update them to the current schema version if they don’t. MongoDB will lower license fees and infrastructure costs significantly, but possibly the biggest savings organizations experience from moving away from RDBMS will come from reduced development costs. Not only is there less code overall to maintain, but the application will also be easier to understand for someone who didn't write the code. MongoDB makes migrations far simpler and less prone to failure and downtime. Applications can be updated more frequently, in an easier fashion, and without stressing about whether a schema update will fail and require a rollback. Overall, maintaining applications over their lifetime is far easier with NoSQL databases like MongoDB. These efficiencies add up to significant savings over time. It's also worth mentioning that a lot of up-and-coming developers see relational databases as legacy technology and not technology they prefer to use. With MongoDB it is easier to attract top talent, a critical factor in any organization's ability to develop best-of-breed products and accelerate time-to-value. Uplevel your NoSQL data modeling skills If you want to start reining in the hidden costs in your software development lifecycle by learning how to model data, MongoDB University offers a special course, M320: MongoDB Data Modeling . There are also dozens of other free courses, self-paced video lessons, on-demand labs, and certifications with digital badges to help you master all aspects of developing with MongoDB.

March 15, 2023