What it is
MySQL is an open-source relational database now developed under Oracle's stewardship, with a large installed base in web applications. It stores tables and serves SQL. The storage engine you actually want for transactions is InnoDB. MariaDB began as a fork and remains compatible for many workloads and different for others; do not assume every blog post applies to both.
Cloud products (Amazon Aurora MySQL, Google Cloud SQL, Azure Database for MySQL) host it so you do not patch the OS yourself. MySQL is not "the free database" as a category. PostgreSQL and SQLite are the other common answers. This page is how to decide and how not to get hurt by defaults.
Why and when it is used
Choose MySQL when the company already runs it, when a product you must use expects it, or when your platform team's golden path is a managed MySQL. The operational knowledge you already have is worth more than a feature list. Choose Postgres for many green-field systems if you have no installed base, especially if you want stricter SQL behaviour and extensions such as pgvector in the same engine. Either can run a serious application.
Do not choose a database because a shared host in 2012 included it. Do not run two of them "for different microservices" that share one team and one schema's worth of data.
How it works
A server accepts connections, authenticates a user, and runs SQL against InnoDB tables. Transactions and row locks are InnoDB features; the old MyISAM engine does not give you the transactional behaviour you assume. Indexes, query plans (EXPLAIN) and slow-query logs are how you diagnose performance. Replication copies changes to other servers for reads or failover. Dialects differ from Postgres: upsert syntax, quoting, autoincrement, and the way some modes silently truncate or coerce bad values.
That last point matters. In loose SQL modes, MySQL has historically accepted invalid dates or truncated strings with a warning instead of an error. Strict mode exists and you want it for new applications so bad data fails loudly. Check the mode; do not inherit a server someone configured to be "helpful" in 2009.
Technologies and dependencies
A MySQL 8.x (or current) server, a client, and a driver. Migrations in git. An ORM if you use one, pointed at the right dialect. Connection limits are easy to exhaust; use a pool. Backups (mysqldump for small databases, the platform's snapshots for real ones) need a restore drill. Prisma supports MySQL as one provider. SQL is still the language underneath.
How to get started
- Install MySQL 8 or run the official container. Create a database and an application user with rights only on that database.
- Confirm
sql_modeincludes strict settings. Insert an invalid value and watch it fail. - Create a table with a primary key, a unique column and a foreign key. InnoDB is required for the foreign key to mean what you think.
- From your app, connect with parameters and a pool size you chose, not the driver's infinite default.
- Run
EXPLAINon the main query. Add the obvious index. - If you are choosing between MySQL and Postgres and nobody in the team has operated either, prefer the one your cloud's tutorial and your hiring pool match, and document the choice.
Do not copy a Postgres schema in and hope. Types and autoincrement differ. Write the migration for the engine you run.
Cautions and trade-offs
Silent coercion is the historic footgun. Strict mode is step zero. Charset should be utf8mb4 or you will corrupt emoji and some symbols; the old utf8 in MySQL is not full Unicode. Time zones and DATETIME versus TIMESTAMP cause off-by-hours bugs.
MariaDB compatibility is not identity. An extension or a version-specific feature needs a test on the engine you will deploy. Managed MySQL that lags upstream will not have the blog post's feature. And as with any relational engine, the ORM is not the schema. Read the SQL, add indexes, and do not use the database user that has SUPER privileges as the application's login.