Why do we need data persistence?

"Sometimes, elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function."                                                                                                                                                                                                                         - John Carmack

Modern applications these days are data-heavy. Data is the new oil, as many say. Database-backed services are everywhere, from social gaming to cloud storage, to e-commerce, to healthcare, and so on. All of these services need to store and retrieve data correctly. The data that they store, must be easy to retrieve and must have guarantees regarding consistency and durability.

Databases are the go-to solution for providing a robust foundation for building applications that are data-backed and that support the expectations of their users. Before we build anything involving databases with Rust, we need to get an idea of the basics. A database, in general, is a collection of tables. Tables are units of data organization.

Data that's been organized into tables is only applicable to relational databases. Other databases, such as NoSQL and graph-based databases, use a more flexible document model to store and organize data.

Data is organized into logical bodies called tables. Tables are usually representations of entities from the real world. These entities can have various attributes that take the place of columns in these tables. These entities can also have relations with other entities. A column in one table can refer to another column. Changes to any database is performed using a specific DSL called Structured Query Language (SQL). SQL queries also allow you to spread a query across multiple tables using query clauses such as JOIN. Those are the basics. A common pattern with a user interacting with database-backed applications is the CRUD pattern, which is short for Create, Read, Update, and Delete. These are the usual operations a user performs most of the time on a database through the application.

SQL is a declarative way to perform transactions on a database. A transaction is a group of modifications to a database that must happen atomically or not at all in case there are any failures midway. The naive way to write a database transaction in any application is through a raw SQL query. However, there's a better way to do this, and it's called Object Relational Mapping (ORM). This is a technique that's used to access a database using native language abstractions and types that map almost one to one with the SQL syntax and semantics. Languages provide higher-level libraries for speaking SQL, which allow you to write queries in their native language, which is then translated into a raw SQL query. In traditional object-oriented languages, your objects become SQL-speaking objects. These libraries are called object-relational mappers. Many of these libraries exist in mainstream languages such as Hibernate for Java, Active Record for Ruby, SQLAlchemy for Python, and so on. Using ORMs reduces the possibility of any errors occurring when you're using raw SQL queries. However, ORMs also suffer from not being able to map themselves completely to the language's object model with the database model. As such, ORM libraries should try to limit the amount of abstraction they provide for interacting with a database and leave some of the parts to raw SQL queries.

The Rust ecosystem provides quite a few high-quality solutions to manage and build persistent applications. We'll look at a couple of them in the following section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset