You'll find a lot of information about this here:

What are the use cases for various scoping constructs?

I'll add that what Module does is called

*lexical scoping* and what Block does is called

*dynamic scoping* by computer scientists. You'll find some theoretical information about both on Wikipedia: https://en.wikipedia.org/wiki/Scope_(computer_science)

The simple way to think about them as a beginner is this: Module gives you local symbols. Block just temporarily removes the definition of symbols, if they have any, otherwise it doesn't do anything. If you need to localize something, use Module. Use Block only if you know you need it and you understand why.

Example:

In[1]:=

f[sym_] := Module[{x}, D[x sym, x]]

g[sym_] := Block[{x}, D[x sym, x]]

In[3]:= f[a]

Out[3]= a

In[4]:= g[a]

Out[4]= a

In[5]:= f[x]

Out[5]= x

In[6]:= g[x]

Out[6]= 2 x

The last one gives 2x because it calculates the derivative of x^2. The x symbol that was passed into the funtion g is the same as the x symbol used inside Block.