MySQL and MariaDB are both free, open-source Relational Databases. MariaDB is a fork of MySQL, created by MySQL’s original developers after Oracle acquired it.
The MariaDB developers aim to maintain compatibility with MySQL as much as possible, making it a great low-risk migration alternative.
BONUS KNOWLEDGE
Besides SQL and NoSQL definitions, databases can be grouped into 7 paradigms (but not limited to):
- Relational (RDB) (SQL): MySQL, MariaDB, Oracle, SQLite, MSSQL, PostgreSQL, AWS Aurora, CockroachDB…
- Key-Value (single value per entry) (NoSQL): Redis, ElasticCache…
- Wide Column (multiple values per entry) (NoSQL): ScyllaDB, Apache Cassandra, Apache HBase, AWS DynamoDB, Azure CosmosDB, Google BigTable…
- Document (JSON format) (NoSQL): MongoDB, Firestore, CouchDB…
- Graph (NoSQL): Neo4j, DGraph, Janus Graph…
- Search Engine (NoSQL): ElasticSearch, Algolia, MeiliSearch…
- Multi-model (SQL and/or NoSQL): FaunaDB, CosmosDB, MongoDB, Redis…
MANAGING MySQL / MariaDB
Keep the following points in mind, as they often frustrate beginners:
- Commands may differ depending on the version of the application.
- Forgetting the semicolon at the end of a command will leave the prompt waiting for it.
- MySQL and MariaDB are not exactly the same, though they are compatible most of the time.
Before starting, check the application version:
mysql --version
OR
mysql> SELECT VERSION();
If you have MySQL 5.7.6+ or MariaDB 10.1.20+, some commands may differ from older versions.
Log in to MySQL as root:
mysql -u root -p
Managing databases:
mysql> SHOW DATABASES; mysql> CREATE DATABASE databaseName; mysql> CREATE DATABASE IF NOT EXISTS databaseName; mysql> DROP DATABASE databaseName; mysql> DROP DATABASE IF EXISTS databaseName;
Managing users:
mysql> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; mysql> CREATE USER IF NOT EXISTS 'user'@'localhost' IDENTIFIED BY 'password';
For newer versions:
mysql> ALTER USER 'user'@'localhost' IDENTIFIED BY 'password';
For older versions:
mysql> SET PASSWORD FOR 'user'@'localhost' = PASSWORD('password');
Listing and deleting users:
mysql> SELECT user, host FROM mysql.user; mysql> DROP USER 'user'@'localhost'; mysql> DROP USER IF EXISTS 'user'@'localhost';
Managing privileges:
mysql> GRANT ALL PRIVILEGES ON databaseName.* TO 'user'@'localhost'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'user'@'localhost'; mysql> GRANT ALL PRIVILEGES ON databaseName.tableName TO 'user'@'localhost'; mysql> GRANT SELECT, INSERT, DELETE ON databaseName.* TO 'user'@'localhost'; mysql> REVOKE ALL PRIVILEGES ON databaseName.* FROM 'user'@'localhost'; mysql> SHOW GRANTS FOR 'user'@'localhost';
If you forgot your root password:
sudo systemctl stop mysql sudo systemctl stop mariadb sudo mysqld_safe --skip-grant-tables & mysql -u root
For newer versions:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password'; mysql> FLUSH PRIVILEGES;
If ALTER USER does not work, try:
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('password') WHERE User = 'root' AND Host = 'localhost';
mysql> FLUSH PRIVILEGES;
For older versions:
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MY_NEW_PASSWORD');
mysql> FLUSH PRIVILEGES;
Grant the privilege to manage users and permissions (Ansible example):
GRANT ALL ON *.* TO '_Ansible'@'%' WITH GRANT OPTION;
Grant the privileges required for management tools (Percona example):
CREATE USER 'pmm'@'%' IDENTIFIED BY '*********' WITH MAX_USER_CONNECTIONS 10; GRANT SELECT, PROCESS, REPLICATION CLIENT, RELOAD ON *.* TO 'pmm'@'%';
Show users and grants:
SELECT user, host FROM mysql.user; SHOW GRANTS; SHOW GRANTS FOR user@localhost;
Restart the service:
sudo systemctl restart mysql sudo systemctl restart mariadb
Try logging in as root:
mysql -u root -p
ADDITIONALLY
Consider periodically running the following commands:
- ANALYZE TABLE – analyzes the table and updates its statistics, which the MySQL optimizer uses to build query execution plans and make better decisions about how to run queries.
- OPTIMIZE TABLE – rebuilds the table and its indexes, reclaiming unused space, defragmenting data files, repairing any corruption, and updating the same statistics as ANALYZE TABLE.
Note: these operations can be resource-intensive. Test in a sandbox environment first to avoid impacting database performance.
BONUS
Not all applications support MySQL 8 out of the box.
Follow these steps to install MySQL 5.7 on Ubuntu 20.04 and 22.04:
wget https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb sudo dpkg -i mysql-apt-config_0.8.12-1_all.deb sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B7B3B788A8D3785C sudo apt update && sudo apt-cache policy mysql-server sudo apt install -f mysql-client=5.7* mysql-community-server=5.7* mysql-server=5.7* -y sudo mysql_secure_installation
SQLite
sqlite3 database_filename.db
sqlite> .help sqlite> .tables sqlite> PRAGMA table_info(table_name); sqlite> SELECT * FROM table_name; sqlite> .quit
Note: SQLite has unique navigation commands, but its querying is very similar to MySQL.
PostgreSQL
Getting help:
psql --help
postgresql=# help postgresql=# \?
Basic navigation and querying:
postgresql=# \l -- List databases postgresql=# CREATE DATABASE abcDB; postgresql=# \c abcDB -- Connect to a DB postgresql=# CREATE TABLE tableName ( id int NOT NULL PRIMARY KEY, column1 varchar(10) NOT NULL, column2 TIMESTAMP ); postgresql=# \d -- List tables postgresql=# \dt -- List tables in the current schema postgresql=# \d tableName -- Describe table postgresql=# INSERT INTO tableName ( column1, column2 ) VALUES ( 'ABC', NOW() ); postgresql=# SELECT * FROM tableName; postgresql=# DROP DATABASE abcDB;
Note: PostgreSQL has unique navigation commands, but its querying is very similar to MySQL.
Connecting from the command line:
psql -h localhost -p 5432 -U userName -W abcDB
Importing and exporting files:
postgresql=# \i importFile.sql postgresql=# \c ( SELECT * FROM tableName ) TO 'exportFile.sql' DELIMITER ',' CSV HEADER;
Users, Roles, and Groups:
- User: an account (user or service) that can log in to a database by default.
- Role: a collection of privileges that can be assigned to users or other roles, and can optionally be configured to log in like a user.
- Group: essentially a role that cannot log in. There is no practical advantage to using this over roles.
Schema:
- Schema: a namespace (logical grouping) for managing database objects, helping avoid naming conflicts and control access to data.
- Tables, functions, and other objects are created within a schema, not directly in the database (if no schema is specified, the
defaultschema is used). - Objects like tables can share the same name within the same database as long as they belong to different schemas.
- Tables, functions, and other objects are created within a schema, not directly in the database (if no schema is specified, the