User Management
Learn how to create, inspect, and remove MySQL user accounts, and why applications should never connect as root.
Introduction
Every MySQL server starts with an all-powerful root user, capable of doing absolutely anything — creating and dropping databases, changing other users' passwords, even shutting the server down. Using this account for everyday application work is one of the most common and dangerous MySQL mistakes.
This lesson introduces MySQL's user management: creating dedicated accounts with CREATE USER, understanding host restrictions, inspecting a user's access with SHOW GRANTS, and removing accounts with DROP USER.
- Why applications should never connect to MySQL as root.
- How to create a new user with CREATE USER.
- What the host part of a username means.
- How to view and remove a user's access.
Why Not Just Use Root?
The root account has unrestricted access to everything on the server: every database, every table, and every administrative command. If an application connects as root and has any kind of security flaw — like a SQL injection vulnerability — an attacker inherits full control of the entire server, not just that one application's data.
An application should only ever be able to do what it actually needs to do. If a bug or attack compromises an application connecting as root, the damage is unlimited. If it connects as a restricted user, the damage is contained to whatever that user was allowed to touch.
The fix is straightforward: create a separate, dedicated MySQL user for each application (or person), and grant it only the specific permissions it actually requires.
Creating a New User
A new user account is created with the CREATE USER statement, which specifies a username, a host, and a password.
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'S3cur3P@ssword!';At this point, app_user exists and can log in, but it has no permissions on any database yet — it cannot even SELECT from a single table. Permissions are granted separately, which you will cover in detail in the next lesson.
SELECT User, Host FROM mysql.user WHERE User = 'app_user';+----------+-----------+
| User | Host |
+----------+-----------+
| app_user | localhost |
+----------+-----------+Understanding the Host Part
Every MySQL user is really identified by a username AND a host combined — 'user'@'host'. The host restricts which machines that account is even allowed to connect from, before any permissions are checked.
| Host Value | Meaning |
|---|---|
| 'localhost' | Only connections from the same machine the MySQL server runs on. |
| '%' | Any host at all — connections are allowed from anywhere. |
| '192.168.1.50' | Only connections from that one specific IP address. |
| '%.example.com' | Only connections from hosts within that domain. |
-- Only usable by an application running on this same server
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'S3cur3P@ssword!';
-- Usable from any machine that can reach this server over the network
CREATE USER 'remote_user'@'%' IDENTIFIED BY 'AnotherP@ssword!';A user created with '%' as the host can attempt to connect from anywhere on the network, which meaningfully widens your attack surface. Prefer 'localhost' or a specific, known host whenever possible, and reserve '%' for cases that genuinely require it.
Because the username and host together form the account's identity, 'app_user'@'localhost' and 'app_user'@'%' are two entirely separate accounts, even though they share the same username.
Viewing a User's Permissions
To see exactly what an existing user is allowed to do, use SHOW GRANTS FOR, specifying the exact user and host.
SHOW GRANTS FOR 'app_user'@'localhost';+---------------------------------------------------------------+
| Grants for app_user@localhost |
+---------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_user`@`localhost` |
+---------------------------------------------------------------+GRANT USAGE ON *.* essentially means "this user can log in, but has no meaningful privileges yet." Once privileges are granted (covered in the next lesson), they will appear here as additional GRANT lines.
Removing a User
When an account is no longer needed — an employee leaves, or an application is retired — remove it with DROP USER so it can no longer be used to connect.
DROP USER 'app_user'@'localhost';SELECT User, Host FROM mysql.user WHERE User = 'app_user';Empty set (0.00 sec)DROP USER removes the account itself and its permissions, but does not delete any database or table data that user previously accessed — only the login and its privileges are gone.
Common Mistakes
- Having every application connect as root instead of a dedicated, limited user.
- Creating a user with '%' as the host when 'localhost' or a specific IP would be safer.
- Forgetting that 'user'@'localhost' and 'user'@'%' are two completely separate accounts.
- Leaving unused accounts around indefinitely instead of removing them with DROP USER.
Best Practices
- Create a separate MySQL user for each application and each person who needs access.
- Restrict the host to 'localhost' or a specific address whenever possible.
- Regularly review accounts with SHOW GRANTS and remove ones that are no longer needed.
- Always use a strong, unique password when creating a new user with IDENTIFIED BY.
Frequently Asked Questions
Does creating a user automatically give it any permissions?
No. A newly created user can log in but cannot access any database or table data until privileges are explicitly granted, as covered in the next lesson.
Can the same username exist with different hosts at the same time?
Yes — 'app_user'@'localhost' and 'app_user'@'%' can both exist simultaneously as entirely separate accounts, each with its own permissions and password.
What happens if I try to DROP USER an account that does not exist?
MySQL returns an error, unless you use DROP USER IF EXISTS, which succeeds silently even if the account was never there.
Is it safe to use '%' for a production application user?
It is riskier than a specific host, since it allows connection attempts from anywhere. It is generally better to restrict to known application server addresses when possible.
How is a password changed for an existing user?
Use ALTER USER 'username'@'host' IDENTIFIED BY 'new_password'; to change an existing account's password.
Key Takeaways
- Applications should connect with a dedicated, limited user, never as root.
- CREATE USER 'username'@'host' IDENTIFIED BY 'password' creates a new account.
- The host part restricts where a user is allowed to connect from — 'localhost' vs '%' for any host.
- SHOW GRANTS FOR 'username'@'host' reveals a user's current permissions.
- DROP USER removes an account and its privileges, without touching existing data.
Summary
Creating dedicated, appropriately restricted user accounts, instead of relying on root, is one of the most important security habits in working with MySQL.
In this lesson, you learned why root should be avoided for everyday use, how to create and remove users, and how host restrictions control where a user can connect from. Next, you will learn how to grant those users precisely the privileges they need.
- You understand why applications should not connect as root.
- You can create a new user with CREATE USER.
- You understand the meaning of the host part of an account.
- You are ready to learn about granting and revoking privileges.