You need to connect a desktop client to a database on a server. The quick way - bind to all addresses and open the port - puts your database in front of the whole internet, where it is found by scanners within hours. There is a better way that takes no longer.

The right answer: an SSH tunnel

ssh -N -L 3307:127.0.0.1:3306 sara@server.example.com

# then point the client at:
#   host 127.0.0.1   port 3307

The database keeps listening on localhost only, nothing is opened in the firewall, and the connection is encrypted by SSH. Every desktop client - TablePlus, DBeaver, Sequel Ace, MySQL Workbench - has this built in as an SSH option.

Confirm it is not already exposed

sudo ss -tlnp | grep 3306
# 127.0.0.1:3306  good
# 0.0.0.0:3306    exposed
# /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 127.0.0.1

If it genuinely must be reachable

An application server in another data centre, for instance. Then: a private network if the provider offers one, a firewall rule naming the exact source address, a user restricted to that host, and TLS required.

sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp

CREATE USER 'app'@'203.0.113.20' IDENTIFIED BY '...' REQUIRE SSL;
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'app'@'203.0.113.20';
Never create a user with the host wildcard - a grant to 'app'@'%' means from anywhere on earth. It is the single most common cause of a database being taken, and it is one character.

Check what exists already

SELECT user, host FROM mysql.user ORDER BY host;

Any row with % in the host column is worth an explanation. See users and grants without over-granting.