|
| 1 | +--- |
| 2 | +id: index-ebook-8-data-modeling-patterns |
| 3 | +title: Learn 8 NoSQL Data Modeling Patterns in Redis |
| 4 | +image: /img/ebooks/nosql-data-modeling-patterns/8-data-modeling-patterns-in-redis.jpg |
| 5 | +sidebar_label: NoSQL Data Modeling Patterns |
| 6 | +slug: /ebooks/8-nosql-data-modeling-patterns |
| 7 | +editUrl: false |
| 8 | +showLastUpdateTime: false |
| 9 | +--- |
| 10 | + |
| 11 | +import Excerpt from '@theme/Excerpt'; |
| 12 | + |
| 13 | +<Excerpt cta="https://redis.com/docs/8-data-modeling-patterns-in-redis/" image={frontMatter.image} title={frontMatter.title}> |
| 14 | + |
| 15 | +## Introduction |
| 16 | + |
| 17 | +When someone is looking to use NoSQL for an application, the question that most often comes up is, “How do I structure |
| 18 | +my data?” The short answer to this question is, as you might guess, it depends. There are several questions that can |
| 19 | +inform how to structure your data in a NoSQL database. |
| 20 | +Is your application read heavy, or write heavy? What does the user experience of your application look like? How does |
| 21 | +your data need to be presented to the user? How much data will you be storing? What performance considerations do |
| 22 | +you need to account for? How do you anticipate scaling your application? |
| 23 | + |
| 24 | +These questions are only a small subset of what you need to ask yourself when you start working with NoSQL. A common |
| 25 | +misconception with NoSQL databases is that since they are “schemaless” you don’t need to worry about your schema. |
| 26 | +In reality, your schema is incredibly important regardless of what database you choose. You also need to ensure that the |
| 27 | +schema you choose will scale well with the database you plan to use. |
| 28 | + |
| 29 | +In this e-book you will learn how to approach data modeling in NoSQL, specifically within the context of Redis. Redis is a |
| 30 | +great database for demonstrating several NoSQL patterns and practices. Not only is Redis commonly used and loved by |
| 31 | +developers, it also is a multi-model database. This means that while many of the patterns covered in this e-book apply to |
| 32 | +different types of databases (e.g. document, graph, time series, etc.), with Redis you can apply all of the patterns in |
| 33 | +a single database. |
| 34 | + |
| 35 | +:::note |
| 36 | + |
| 37 | +By the end of this, you should have |
| 38 | + |
| 39 | +- A firm understanding of how to approach modeling data in Redis as well as in NoSQL generally. |
| 40 | +- An understanding of several NoSQL data modeling patterns, their pros and cons, as well as use cases for |
| 41 | + them in practice. |
| 42 | +- A working knowledge of how to actually write code (with examples) to take advantage of NoSQL patterns |
| 43 | + within Redis. |
| 44 | + |
| 45 | +::: |
| 46 | + |
| 47 | +## SQL versus NoSQL |
| 48 | + |
| 49 | +I’m sure at a certain level you understand the difference between SQL and NoSQL. SQL is a structured query language |
| 50 | +whereas NoSQL can mean several different things depending on the context. However, generally speaking, the approach |
| 51 | +to modeling data is fundamentally different in NoSQL than in SQL. There are also differences in terms of scalability, with |
| 52 | +NoSQL being easier to scale horizontally. |
| 53 | + |
| 54 | +When building applications you are probably using an object-oriented language like JavaScript, Java, C#, or others. |
| 55 | +Your data is represented as strings, lists, sets, hashes, JSON, and so on. However, if you store data in a SQL database |
| 56 | +or a document database, you need to squeeze and transform the data into several tables or collections. You also need |
| 57 | +complex queries (such as SQL queries) to get the data out. This is called **impedance mismatch** and is the fundamental |
| 58 | +reason why NoSQL exists. |
| 59 | + |
| 60 | +A large application might use other systems for data storage such as Neo4J for graph data, MongoDB for document |
| 61 | +data, InfluxDB for time series, etc. Using separate databases turns an impedance mismatch problem into a database |
| 62 | +orchestration problem. You have to juggle multiple connections to different databases, as well as learn the different client |
| 63 | +libraries used. |
| 64 | + |
| 65 | +With Redis, in addition to the basic data structures such as strings, lists, sets, and hashes, you can also store advanced |
| 66 | +data structures such as RedisJSON for documents, RediSearch for secondary indexing, RedisGraph for graph data, |
| 67 | +RedisTimeSeries for time-series data, and RedisBloom for probabilistic data (think leaderboards). |
| 68 | + |
| 69 | +This reduces impedance mismatch because your data is stored in one of 15 structures with little or no transformations. |
| 70 | +You can also use a single connection (or connection pool) and client library to access your data. What you end up with is |
| 71 | +a simplified architecture with purpose-built models that are blazing fast and simple to manage. For this reason, this e-book |
| 72 | +will use Redis to explain several of the NoSQL data modeling patterns. |
| 73 | + |
| 74 | +Most developers have at least a little understanding of SQL and how to model data in it. This is because SQL is widely |
| 75 | +used and there are several incredible books and even full courses devoted to it. NoSQL is quickly growing and becoming |
| 76 | +more popular. But given that when you’re talking about NoSQL you’re talking about more than just a document store, there |
| 77 | +is a lot of ground to cover. That’s why when covering certain NoSQL data modeling patterns in this e-book, you will be |
| 78 | +presented with what it might look like to model the data in SQL as well. |
| 79 | + |
| 80 | +When you approach data modeling in SQL you are typically focused on relationships, as SQL is meant for set-based |
| 81 | +operations on relational data. NoSQL doesn’t have this constraint and is more flexible in the way you model data. |
| 82 | +However, this can lead to schemas that are overly complex. When considering NoSQL schema design, always think about |
| 83 | +performance and try to keep things simple. |
| 84 | + |
| 85 | +So to kick things off, let’s start by looking at something that is very near and dear to a SQL developer’s heart: **relationships**. |
| 86 | + |
| 87 | +## Modeling 1-to-1 Relationships |
| 88 | + |
| 89 | +Imagine that you are creating a retail app that sells electronics. Let’s use **Picture 1** and **Picture 2** as an example of the |
| 90 | +UI for a standard retail e-commerce app. First, you’ll create a list view of all the electronics and then a detailed view |
| 91 | +that shows all the details of each item. There is a 1-to-1 relationship between each item in the list view and the detailed |
| 92 | +view (shown in **Picture 2**) of the item. The detailed view shows all the details such as multiple photos, description, |
| 93 | +manufacturer, dimensions, weight, and so on. |
| 94 | + |
| 95 | +<div className="container"> |
| 96 | + <div className="row"> |
| 97 | + <div className="col col--6"> |
| 98 | + <strong>Picture 1</strong> |
| 99 | + <img |
| 100 | + src="/img/ebooks/nosql-data-modeling-patterns/1-to-1-list-view.png" |
| 101 | + alt="Picture 1 1-to-1 List View" |
| 102 | + title="Picture 1 1-to-1 List View" |
| 103 | + /> |
| 104 | + </div> |
| 105 | + <div className="col col--6"> |
| 106 | + <strong>Picture 2</strong> |
| 107 | + <img |
| 108 | + src="/img/ebooks/nosql-data-modeling-patterns/1-to-1-detail-view.png" |
| 109 | + alt="Picture 2 1-to-1 Detailed View" |
| 110 | + title="Picture 2 1-to-1 Detailed View" |
| 111 | + /> |
| 112 | + </div> |
| 113 | + </div> |
| 114 | +</div> |
| 115 | + |
| 116 | +### 1-to-1 Relationships using SQL |
| 117 | + |
| 118 | +In a relational database, you may create a table called `products` where each row holds just enough data to display the information in the list view. Then, you may create another table called `product_details` where each row holds the rest of the details. You would also need a `product_images` table, where you store all of the images for a product. You can see the entity relationship diagram in **Picture 3**. |
| 119 | + |
| 120 | +<strong>Picture 3</strong> |
| 121 | +<img |
| 122 | + src="/img/ebooks/nosql-data-modeling-patterns/1-to-1-entity-diagram.png" |
| 123 | + alt="Picture 3 1-to-1 Entity Diagram" |
| 124 | + title="Picture 3 1-to-1 Entity Diagram" |
| 125 | +/> |
| 126 | + |
| 127 | +Picture 3 depicts the entity relationships between `products`, `product_details`, and `product_images` and represents a normalized data model with a single denormalized field image in the `products` table. The reason for this is to avoid having to use a SQL JOIN when selecting the products for the list view. Using this model, the SQL query used to get the data needed for the list view might resemble **Code Example 1**. |
| 128 | + |
| 129 | +```sql title="Code Example 1" |
| 130 | +SELECT |
| 131 | + p.id, p.name, p.image, p.price, pi.url |
| 132 | +FROM |
| 133 | + products p |
| 134 | +``` |
| 135 | + |
| 136 | +### 1-to-1 Relationships using Redis |
| 137 | + |
| 138 | +In Redis, similar to a relational database, you can create a collection called `products` and another called `product_details`. But with RedisJSON you can improve this by simply embedding `product_images` and `product_details` directly into the `Products` collection. Then, when you query the `Products` collection, specify which fields you need based on which view you are trying to create. |
| 139 | + |
| 140 | +This will allow you to easily keep all the data in one place. This is called the **Embedded Pattern** and is one of the most common patterns you will see in NoSQL document databases like RedisJSON. **Code Example 2** uses Python and a client library called Redis OM (an ORM for Redis) to model `Products` and `ProductDetails`. Note that `ProductDetails` is embedded into `Products` directly, so all of the data for a product will be stored within the same document. |
| 141 | + |
| 142 | +```python title="Code Example 2" |
| 143 | +class ProductDetail(EmbeddedJsonModel): |
| 144 | + description: str |
| 145 | + manufacturer: str |
| 146 | + dimensions: str |
| 147 | + weight: str |
| 148 | + images: List[str] |
| 149 | + |
| 150 | +class Product(JsonModel): |
| 151 | + name: str = Field(index=True) |
| 152 | + image: str = Field(index=True) |
| 153 | + price: int = Field(index=True) |
| 154 | + details: Optional[ProductDetail] |
| 155 | +``` |
| 156 | + |
| 157 | +**Code Example 2** also shows how you can index fields using Redis OM and RediSearch. Doing this turns Redis into not only a document store but also a search engine since RediSearch enables secondary indexing and searching. When you create models using Redis OM, it will automatically manage secondary indexes with RediSearch on your behalf. |
| 158 | + |
| 159 | +Using Redis OM we can write a function to retrieve our `products` list for the list view, as shown in **Code Example 3**. |
| 160 | + |
| 161 | +```python title="Code Example 3" |
| 162 | +async def get_product_list(): |
| 163 | + results = await connections \ |
| 164 | + .get_redis_connection() \ |
| 165 | + .execute_command( |
| 166 | + f'FT.SEARCH {Product.Meta.index_name} * LIMIT 0 10 RETURN 3 name image price' |
| 167 | + ) |
| 168 | + return Product.from_redis(results) |
| 169 | +``` |
| 170 | + |
| 171 | +Notice that in **Code Example 3** we are using the `FT.SEARCH` (RediSearch) command, which specifies the index managed on our behalf by Redis OM and returns three fields: name, image, and price. While the documents all have details and images embedded, we don’t want to display them in the list view so we don’t need to query them. When we want the detailed view, we can query an entire Product document. See **Code Example 4** for how to query an entire document. |
| 172 | + |
| 173 | +```python title="Code Example 4" |
| 174 | +async def get_product_details(product_id: str): |
| 175 | + eturn await Product.get(product_id) |
| 176 | +``` |
| 177 | + |
| 178 | +When using Redis, you can use RedisInsight as a GUI tool to visualize and interact with the data in your database. **Picture 4** shows you what a `Products` document looks like. |
| 179 | + |
| 180 | +<strong>Picture 4</strong> |
| 181 | +<img |
| 182 | + src="/img/ebooks/nosql-data-modeling-patterns/1-to-1-redisinsight.png" |
| 183 | + alt="Picture 4 1-to-1 RedisInsight" |
| 184 | + title="Picture 4 1-to-1 RedisInsight" |
| 185 | +/> |
| 186 | + |
| 187 | +## Download the E-book |
| 188 | + |
| 189 | +</Excerpt> |
0 commit comments