So lets first see the different kinds of databases available to us
There are mainly two kinds of databases available to us : SQL and noSQL.
So whats the difference between the two:
i) SQL databases require strict schemas which are very hard to change .
Are they important ? Very much . Big companies like Microsoft use SQL databases .
ii) NoSQL databases are schemaless and can be used to produce apps faster . Any beginner in web developement has possibly used MongoDB as their first database which is also a NoSQL database . And yes , even this is used by a lot of companies .
Lets deep dive into SQL databases
Normalisation
Lets first discuss one important point you might need to know while working with SQL databases . And that is relationship or normalisation of tables . You see we are going to deal with tables when using SQL databases . So , it is sometimes better to divide a bigger table into 2 smaller tables for better understanding when dealing with a large amount of data . In the below example instead of piling up the address as well to the individual's login identity , we create a separate table for it (we also use user_id for knowing who's address we are talking about) .
We will also need to establish connection between the two tables and we can do that by matching _id of left table to user_id of right table since they can be used to match same person .
Lets set up a SQL Database
We are going to consider PostgreSQL . It is very popular and anyways we need to choose one for now . Now we are going to ElephantSQL's website to create a free instance of a Postgres Database . You would just need to sign up and then you can create your free instance (if you are not able to then you can simply youtube it but I am assuming you are technical enough for that) . Now go to that instance and you will be able to see the postgres URL . We will need it later .
The URL would be of the format "postgres://[username]:[password]@[host]/[database_name]"
Basic types of queries
These are mainly some basic ways for the NodeJS backend to interact with the database .
Warming up
As we can see , we will need to create two tables : one for the users and the other for the todos . Lets have a look for the first table :
This is going to create a table named "users" with three columns for id , email and password respectively .
"SERIAL PRIMARY KEY" means that the id would be increasing through the rows by default (starting from 1) .
"VARCHAR(255)" means a string of variable length <= 255 and can use any character.
"UNIQUE" means unique , ofc .
"NOT NULL" means it has to be there .
Overall we can understand that the id would be simple a serial number , email would be a non-null unique string of max length 255 and password would be a non-null string of max length 255 .
Now lets move to the other table .
Here we can understand we are trying to create table named "todos" with columns for id (increasing serial number) , title (non-null text), description (text) , user_id( this ones important so mentioning it separately) and done (boolean with default value set to false unless value explicitly provided) .
user_id is going to be an integer but it is going to be related to corresponding id values under "users" table .
Lets get our hands dirty
Setup
So you can simply clone this repo so that its easier for you to get started
https://github.com/career-tokens/PostgresTutorial.git
After that , you can run :
npm install
This will install the required dependencies which are currently "@types/pg" and "pg" which we are going to discuss shortly .
Connecting to Postgres Database
Lets first have a look at utils.ts file:
You have to copy your postgres url from ElephantSQL and paste it in place of "your postgres url".
You can view "pg" as "mongoose" (if you have worked on MERN stack then you can relate) . Mainly its going to be used to connect to Postgres Database using the link .
Creating Tables
Now lets have a look at "create-table.ts" file .
No need to get overwhelmed , we have already discussed their meanings . Here we are using the client we got from "pg" to simply tell the remote database that it needs to create two tables of so and so type . To run this file , you can first run :
npm run build
This will convert the .ts files to .js files and store them in "dist" folder . Now run :
node dist/create-table.js
This will run and hopefully display "Table created successfully!" .
Inserting values in tables
Lets see an example SQL code for inserting values in respective tables :
Here the first SQL code is going to add a row under the table "todos" where "Buy groceries" , "Milk,..." , 1 and FALSE are going to be under title , description , user_id and done respectively .
Similarly I hope you can understand the next insertion . Lets have a look at the equivalent TS code in the project . Open insert-data.ts .
You can run the file using :
node dist/insert-data.js
Hopefully you will see "Entries created!" in the logs .
Fetching data from tables
Have a look at the SQL code :
Here we want to SELECT all such rows from "todos" table such that user_id matches the id we give so we are able to see all the todos for that specific user .
Lets see the TS code for it :
Lets run the corresponding JS file for it :
node dist/get-data.js
And hopefully you see the below result :
Updating tables
Lets have a look at "update-data.ts" file and run its corresponding JS file as usual .
Deleting rows from tables
Lets have a look at "delete-data.ts" and then run its JS code .
Deleting entire table
This will delete the entire "todos" table .
Lets move to some advanced stuff
Joins
Now lets consider this problem that we need the email of an user and his/her corresponding todos .
What could be the basic way to do this ?
Lets have a look at the below code :
This you will find under the "joins" folder . Here we have simply called for the users and the todos using the user id . You can run the file's JS equivalent using :
node dist/joins/basic.js
But the problem with this is that sometimes establishing relations can be very complicated . We would prefer to fetch data simultaneously from all of them based on certain conditions and store them as combined rows .
This we can do using JOIN .
Lets have a look at "advance-1.ts" :
I hope you could understand the working from the comments .
Now there are four types of joins :
i) FULL JOIN : basically from either of the tables you could find the required rows and use them . You don't need a related row in the other table .
ii) INNER JOIN : there has to be a related row in the other table otherwise no row will be produced
iii) LEFT JOIN : discussed
iv) RIGHT JOIN : opposite of LEFT JOIN
Usage of INNER JOIN is discussed in "advance-2.ts" :
The default join is INNER JOIN .
Problems with writing raw SQL queries
You need to learn a new language that is SQL . It would be better if it could be encapsulated .
Migrating from one set of schema to another is hard .
Your code editor can't understand the types very well lets say in "SELECT * FROM users" , it won't be able to understand the type of "users" .
The Solution ? ORM.
This is something which we are going to see in my next blog . Till then , please do try to marinate all these stuff and thanks for reading !