Setting up and connecting to a SQL database

This blog post may be a bit redundant, considering how ubiquitous SQL databases are today, but I thought I'd write a summary of what I've accomplished so far with configuring a simple MySQL database on my home LAN.

I haven't messed around with SQL too much, having never come across so much data that a database was required to organize it in a more manageable way. However, at some point in the future I know I'll come across this problem, so it's probably best to start learning the toolkit now.

For starters, I have a VM running a Ubuntu 18 server instance that's hosting a mysql-server install. Next, I've configured the SQL server to listen on 192.168.1.60, as opposed to just localhost, which is the bridged IP of the VM. EDIT 12/10: I've since edited the configuration file to allow incoming connections from any IP by setting this value to 0.0.0.0. That way I can connect to it on port 3306 from any other machine. You may find these configuration options in the following file.
root@ubuntu_vm_server:~# cat /etc/mysql/mysql.conf.d/mysqld.cnf | awk '{ if ($1 !~ /^\#/ && length($0) != 0) { print $0 } }'
[mysqld_safe]
socket          = /var/run/mysqld/mysqld.sock
nice            = 0
[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address            = 192.168.1.60
key_buffer_size         = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover-options  = BACKUP
query_cache_limit       = 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days        = 10
max_binlog_size   = 100M
(I've simply stripped blank and commented lines). Do also keep in mind that defining these variables in more than one place will prevent the service from starting (such as in /etc/mysql/my.cnf).
root@ubuntu_vm_server:~# service mysql restart
Job for mysql.service failed because the control process exited with error code.
See "systemctl status mysql.service" and "journalctl -xe" for details.
You should should be able to create a database as root on the host machine.
mysql root@(none):(none)> create database example;
Query OK, 1 row affected
Time: 0.031s
However, this database will not be visible to other users' accounts. I'm not yet familiar with permissions/privileges in MySQL, but the documentation does seem straightforward enough. Following granting my account access to this new database, I was able to connect to it from another machine.
mysql> show grants for 'brandon'@'%';
+------------------------------------------------------+
| Grants for brandon@%                                 |
+------------------------------------------------------+
| GRANT USAGE ON *.* TO 'brandon'@'%'                  |
| GRANT ALL PRIVILEGES ON `example`.* TO 'brandon'@'%' |
+------------------------------------------------------+
2 rows in set (0.00 sec)
And from another machine:
~ $ mycli -h 192.168.1.60 -u brandon
Password:
mysql 5.7.24-0ubuntu0.18.04.1
mycli 1.19.0
Chat: https://gitter.im/dbcli/mycli
Mail: https://groups.google.com/forum/#!forum/mycli-users
Home: http://mycli.net
Thanks to the contributor - bjarnagin
mysql brandon@192.168.1.60:(none)> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| example            |
+--------------------+
2 rows in set
Time: 0.028s
Perhaps more importantly, I can connect to this database with Python.
#! /usr/bin/env python3.7
# -*- coding: utf-8 -8-

"""
Basic test of connectivity on my SQL database.
"""

from mysql.connector import connect


def sqlConnectorExamble() -> None:
    """
    Connection example.
    """
    
    # Not sure why this isn't a CM.
    connection = connect(
        user='brandon',
        password='***',       # Your password.
        host='192.168.1.60',
        port=3306,
        database='example'
    )

    connection.close()


def main() -> None:
    sqlConnectorExamble()


if __name__ == '__main__':
    main()
Albeit in a rather insecure way, as the passwords are stored and executed in plaintext.

From here, I think it's just a matter of writing a set of custom functions to interact with the database and executing commands to retrieve or store certain types of data.