MariaDB is a fork of MySQL, by some lead MySQL developpers, following acquisition of the later by Oracle. It intends to be a free drop-in replacement for MySQL under GPLv2 licene
MariaDB matches MySQL API and commands, and as such, either MySQL or MariaDB can be used.
There are 3 majors components that needs to be installed to use SQL database:
sudo apt install mariadb-server mariadb-client php-mysql sudo systemctl restart apache2
SQL installation already creates specific user/group 'mysql' that runs the database Server, so that if the SQL database is compromised, effect will be limited by OS access control mechanism.
However, by default, the database is configured for ease of use, and that could be abused to grant access to restricted information. MariaBD and MySQL provide a script to secure the database installation that performs the following actions:
sudo mysql_secure_installation
For added security, each database client should use a dedicated user that only has access to its relevant databases, tables and SQL commands.
A user is created as follow:
sudo mysql -u root -p Enter password: ******** CREATE USER 'www-data'@'localhost' IDENTIFIED BY '########'; Query OK, 0 rows affected (0.00 sec) FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) SELECT user,host,password,plugin FROM mysql.user; +----------+-----------+-------------------------------------------+-------------+ | user | host | password | plugin | +----------+-----------+-------------------------------------------+-------------+ | root | localhost | *8106731ABDA8D2909CCAD3A43F5F987F9153D4C0 | unix_socket | | www-data | localhost | *2C12975A747374CDBC5DB61E876BEEB280989266 | | +----------+-----------+-------------------------------------------+-------------+ 2 rows in set (0.00 sec) quit
Note: Linux user www-data and SQL user www-data are not related, the same name is only used for convenience.
It is time now to create a database and give access to its user
mysql -u root -p Enter password: ******** CREATE DATABASE web; Query OK, 1 row affected (0.00 sec) GRANT CREATE, DROP, INSERT, SELECT, UPDATE, DELETE ON web.* TO 'www-data'@'localhost'; Query OK, 0 rows affected (0.00 sec) FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) quit
User 'www-data' can now use the 'web' database.
mysql -u www-data -p######## CREATE TABLE web.links ( id INT NOT NULL AUTO_INCREMENT, url VARCHAR(200) NOT NULL, name VARCHAR(50), last_access DATETIME, PRIMARY KEY (id) ); Query OK, 0 rows affected (0.14 sec) INSERT INTO web.links (url, name, last_access) VALUES ("https://www.tognoli.fr/", "Home", "2017-05-14 08:45:30.00"); Query OK, 1 row affected (0.02 sec) INSERT INTO web.links (url) VALUES ("https://www.google.com"); Query OK, 1 row affected (0.04 sec) SELECT * from web.links; +----+-------------------------+------+---------------------+ | id | url | name | last_access | +----+-------------------------+------+---------------------+ | 1 | https://www.tognoli.fr/ | Home | 2017-05-14 08:45:30 | | 2 | https://www.google.com | NULL | NULL | +----+-------------------------+------+---------------------+ 2 rows in set (0.00 sec)
To check the status of the SQL server:
systemctl status mysql
To invoke SQL client:
# mysql [-h host] [-u user] [-p[password]] mysql -u root -p Enter password: ******** mysql -u user -p######
To show SQL user information (as root)
SELECT User, Host, Password from mysql.user; +------------------+-----------+-------------------------------------------+ | User | Host | Password | +------------------+-----------+-------------------------------------------+ | root | localhost | *4306E4D2162FCC73240A10B0FED25CC3CA7F97A1 | | root | 127.0.0.1 | *4306E4D2162FCC73240A10B0FED25CC3CA7F97A1 | | root | ::1 | *4306E4D2162FCC73240A10B0FED25CC3CA7F97A1 | | debian-sys-maint | localhost | *D08EE04D9B2FD61F784DCCA6E6C05ECC7887C39B | | www-data | localhost | *F5B06B46C6ECEF11AA276665B91F62DC4ACDA301 | +------------------+-----------+-------------------------------------------+ 5 rows in set (0.01 sec) SHOW GRANTS FOR 'www-data'@'localhost'; +-----------------------------------------------------------------------------------------------------------------+ | Grants for www-data@localhost | +-----------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'www-data'@'localhost' IDENTIFIED BY PASSWORD '*F5B06B46C6ECEF11AA276665B91F62DC4ACDA301' | | GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON `web`.* TO 'www-data'@'localhost' | +-----------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)
SHOW: Check the database structure:
SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | web | +--------------------+ 2 rows in set (0.00 sec) SHOW TABLES FROM web; +---------------+ | Tables_in_web | +---------------+ | links | +---------------+ 1 row in set (0.01 sec) SHOW COLUMNS FROM web.links; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | url | varchar(200) | NO | | NULL | | | name | varchar(50) | YES | | NULL | | | last_access | datetime | YES | | NULL | | +-------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
DROP TABLE web.links; DROP DATABASE web; DROP USER 'www-data'@'localhost';
CREATE DATABASE howto; CREATE TABLE howto.lists ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(32) NOT NULL, sort_type ENUM('creation_date', 'due_date', 'name', 'completed') DEFAULT 'creation_date', sort_dir ENUM('ascending', 'descending') DEFAULT 'ascending', show_all BOOLEAN DEFAULT true, parent INT, icon VARCHAR(64), PRIMARY KEY(id) ); CREATE TABLE web.items ( id INT NOT NULL AUTO_INCREMENT, owner VARCHAR(16), public BOOLEAN DEFAULT false, name VARCHAR(32) NOT NULL, descr VARCHAR(255), created DATETIME DEFAULT CURRENT_TIMESTAMP, modified DATETIME ON UPDATE CURRENT_TIMESTAMP, start DATETIME, due DATETIME, finish DATETIME, effort INT, done INT, position INT, period ENUM('daily', 'weekly', 'monthly'), parentId INT, childsId INT, icon VARCHAR(64), PRIMARY KEY(id) ); insert into items(name) values ("Buy apples") update items set name="Buy tomatoes" where id='1'; select * from items insert into items(name) values ("Buy apples"); update items set name="Buy tomatoes" where id='1'; select * from items;
Adding a column to a table
ALTER TABLE orders ADD icon VARCHAR(32) AFTER value;
Renaming/modifying a column
ALTER TABLE orders CHANGE shippedBy shipBy varchar(16);
sudo mysqldump --all-databases | gzip > backup-`date +%Y-%M-%d`.sql.gz gunzip < backup-*.sql.gz | sudo mysql/span>
To backup the database:
sudo mysqldump --quick web -u root -p | gzip > db_web.gz scp db_web.gz user@host:/home/user rm db_web.gz
To restore the database:
sudo mysqladmin create web gunzip < db_web.gz | sudo mysql web27-Nov-2020