Remember the properties of a unit test? It verifies a small unit of behavior in isolation from other tests and provides fast feedback. A test that lacks any of the mentioned properties is an integration test. Typically, an integration test verifies the code that glues your application together and the interaction with third party components or systems. While unit tests focus on a small unit of behavior integration tests might involve many modules of your productive code.
To effectively protect against regression and reduce maintenance costs you should mock as little third party dependencies as possible. If the database for example is exclusively used by your system you should make the integration test interact with a test instance of that database. Only dependencies that are not under your control like for example a time server should be mocked.
Integration tests provide slower feedback than unit tests because setting up external dependencies consumes much more time than setting up the environment for a unit test. Additionally, more code is executed and inter-process communication might happen during an integration test. Furthermore, the development and maintenance effort for the automatic setup of external dependencies is much higher. Since an integration test might span many modules of productive code it can become hard to track down the cause of a failure. For these reasons you should try to cover as much behavior as possible using unit tests and only resort to integration tests for verifying your system as a whole.