Ok, so you have your computer, and it’s connected to the internet. Call that the client. The store is on another computer, call that the server.
You want to connect to the store, so you type an address into the browser. The browser connects takes that address, and looks up the real address of the server on the network.
The client and the server talk to each other using a protocol (set of rules) called HTTP. The client sends a request along with a packet of data, the server checks that that packet of data matches the HTTP specification. If it does, it carries out whatever instructions were contained and makes an HTTP request to the client along with a packet of data, and so on, back and forth.
At some point, the request from the client is going to ask for some stuff that is useful - HTML files, CSS, JS, images, etc - so that you can see something in your browser. Browsers only understand HTML/CSS/JS (+ assets like images), so there’s your frontend.
The backend is, at the basic level, just the web server. It’s a piece of software written to parse the information from incoming HTTP requests and respond by sending HTML* pages back. It can be written in any language. Examples would be Microsoft’s IIS, and the open-source Apache (the server normally used with PHP) and Nginx. NodeJS comes with a server as part of its standard library, as does Python. All of the complexities of different backend stuff in different languages are all there to do this one thing: take HTTP requests to the server, return HTML* back to the client.
So if there is just that very basic server, things will work: there is an HTML file stored on the filesystem of the server, the web server software sees the incoming HTTP request, returns the HTML file. But that’s extremely limiting: everything needs to be in that HTML file when a client connects to the server, that’s all they can get.
So backend software normally includes a way of specifying the location of different HTML files, routing. The router program basically takes requests, and for each type that is specified, runs a function that returns some HTML. So if the request comes in for
ecommerce.com/products, return an HTML file with all the products. If the request is for
ecommerce.com/product/1, return an HTML file with product 1. There are other ways to specify routes, it doesn’t have to look like that, but hopefully, you get the idea.
This is still quite limiting because if that were it, there would need to be an HTML page manually written for every single route. So one solution to this is to store the data on the server, for example in a database. Then some software on the server translates that into HTML files when a request comes in. PHP is an example of this: it allows you to connect to a database, and, given specific parameters, get data from the database and use it to fill in values in templates, which get converted to HTML.
SQL is a language to query databases and doesn’t really have much bearing on any of this. It’s an implementation detail of the server, or of software that the server calls out to on the computer that hosts the server (Or it should be: the ability to make queries directly to a database sometimes gets exposed to the outside world, and very bad things generally happen as a result).
* Note that files returned by the server don’t have to be HTML, they can be anything. For example, a text file written in a different specific way can be returned. Very commonly, this is JSON. Instead of translating the incoming request into HTML, sends the data back in that structured format instead.