PostgreSQL has been around for a while now and is the go-to choice for applications that need reliability, performance and scalability. It's an open-source, SQL database used by lots of big companies and startups, from web apps to scientific research. But as more complex apps need to be built, the limitations of traditional SQL databases are showing. One of the main issues developers come up against with Postgres is writing complex joins. It's even tricky for experienced SQL programmers.
Introduction to SurrealDB and its history
SurrealDB has an SQL-style query language called SurrealQL which is a powerful database query language closely resembling traditional SQL, but with slight differences and improvements. In this article, we will explore the similarities and differences between PostgreSQL and SurrealQL. We will also see how SurrealQL can overcome some of the limitations that relational databases have. Consider this as a guide for every developer coming with a PostgreSQL background to understand SurrealQL better rather than a step-by-step tutorial.
Before we get started, here are some basic concepts you should know about SurrealQL.
You can use the SELECT, CREATE, UPDATE, DELETE, RELATE and INSERT statements to query and manipulate data in SurrealDB. You can also retrieve data using dot notation. , array notation [], and graph semantics ->.
SurrealQL allows records to link to other records and travel across all embedded links or graph connections as required.
You can read more about it and see all other features by visiting the features page.
Building an e-commerce platform
In this blog, we'll be studying an e-commerce platform built using PostgreSQL and SurrealQL side by side.
An e-commerce application needs a special schema that can handle product variations, pricing tiers, and customer details. While e-commerce databases can be successfully built using relational databases the schema can be complex with numerous tables and joins in order to maintain the transactional data.
Below is the relational schema of a lightweight e-commerce platform that we will be building. Our platform has a limited scope with only 3 customers and a couple of products so we can focus on each query and compare it with SurrealQL to understand how it's different.
Data Manipulation and Querying
This is how we INSERT data in a table in PostgreSQL vs in SurrealDB.
Manipulation and querying of data in SurrealQL is done using the SELECT, CREATE, UPDATE, and DELETE statements. These enable selecting or modifying individual records, or whole tables. Each statement supports multiple different tables or record types at once.
PostgreSQL
SurrealQL
If you were to use SurrealDB in a strictly SCHEMAFULL approach, you can define a schema similar to PostgreSQL. You can find a detailed explanation of defining tables in SurrealDB by viewing the DEFINE TABLE statement documentation.
But in the SCHEMALESS approach, you also have the option to quickly get started without having to define every column. In SurrealDB we can define relationships between entities directly. We do not need to know about foreign keys and neither do we have to write logic about how to store them.
PostgreSQL schema for remaining tables.
We need more tables to store the metadata about our e-commerce database in Postgres. These tables aren't required in SurrealDB because we follow the vertex -> edge -> vertex or noun -> verb -> noun convention to store metadata.
Let's populate our database
The insert statement in SurrealQL is similar to the one used in Postgres. However, SurrealQL has an UPDATE statement that can do the same job as Postgres' ALTER statement. Additionally, you can easily add data and columns in SurrealDB without altering the schema, which is possible because SurrealDB can function either as a schemafull or schemaless structure. In this particular example, we are following a schemaless approach, which means that adding a column will not alter the underlying schema of the e-commerce platform.
Let us add an options column to our product table.
PostgreSQL
SurrealQL
Before we start querying our e-commerce database, let's first enter some data in our PostgreSQL reference tables.
Let's insert some data in our SurrealDB tables too!
Retrieving the data
The SELECT statements in SurrealDB are similar to Postgres.
PostgreSQL
SurrealQL
The SELECT statement will fetch all required details from the product tables. In SurrealDB you can assign a unique id to each product. In case you do not assign it an id, it auto-assigns a unique ID to every record. In PostgreSQL, this can be achieved by using a uuid column and it has to be explicitly mentioned initially.
The RELATE statement
The RELATE statement can be used to generate graph edges between two records in the database. The graph edges stand for the relationship between two nodes that represent a record. When a customer buys a product SurrealDB relates the customer with the product using the "bought" relation. You can name your relationship whatever you feel fits right. It could also be called "purchased" or "ordered".
Let's select all the products bought by a particular customer
PostgreSQL
SurrealQL
If you notice this is an extremely complex query. One of the most powerful features in SurrealDB is the capability to relate records using graph connections and links. Instead of pulling data from multiple tables and merging that data together, SurrealDB allows you to select related records efficiently without needing to use JOINs.
Here's what you get when you fire the above SurrealQL query
You can also directly fetch the product ids without the metadata with the following query.
We can also query the graph edge bought
If you study the queries you will realise that customers Pratim and Alex both bought shirts and an iPhone. We have a new customer Tobie who also buys a shirt. Your e-commerce system wants to recommend Tobie the products that other customers have bought.
How would you do this using Postgres?
To recommend products to Tobie based on what Pratim and Alex have bought, we need to first find out what products Pratim and Alex have purchased and then look for other customers who have purchased the same products.
This query first selects all the products bought by Pratim and Alex, then filters out the products already bought by Tobie. The resulting list includes the product_id and product_name of the items to be recommended to Tobie.
Are you with me or is your head spinning? Let's try to do this in SurrealQL now.
Here we are selecting all unique values from the array of products that have been bought by the customers who have also bought a shirt.
But what if you do not want the common product i.e. shirt to be recommended?
You can use the SurrealQL operator NOTINSIDE from SurrealQL to manipulate the data.
Conclusion
In this blog post, we saw how SurrealDB can make it easier for you to structure and query your database compared to PostgreSQL. With SurrealDB you can truly have the best of both databases while not compromising on security and flexibility. SurrealDB has a lot of features like real-time queries with highly efficient related data retrieval, advanced security permissions for multi-tenant access, and support for performant analytical workloads to offer. You can read more about them here.
Next Steps
If you haven't started with SurrealDB yet, you can get started by visiting the install page. Drop your questions on our Discord and don't forget to star us on GitHub.
