The Relational Database & MySQL
An introduction to the relational database model and MySQL
There are many different choices when choosing a database for your application. Some of the most commonly used databases are based on the relational database model. For example, MySQL, Microsoft SQL Server, and PostgreSQL (Wikipedia, 2022a) (Wikipedia, 2022b) (Wikipedia, 2022c). The purpose of this article is to explain some of the concepts related to relational databases in general, combined with a guide to getting started with MySQL.
Key points:
- Relational model
- Structured query language (SQL)
- MySQL
- MySQL Workbench
- Data integrity
- Constraints
- Relationships
- Normalization
1. What is a Relational Database?
A relational database is based on concepts such as tables, relationships, constraints, normalization, and structured query language (SQL) (Wikipedia, 2022d).
The organization of data in the relational database is based on tables, rows, and columns, also known as relations, records/tuples, and attributes (Wikipedia, 2022d).
The tables in the relational model represent different entities (Wikipedia, 2022d). For example, one table may represent invoices and another table may represent accounts. The table’s columns specify different types of data values (Wikipedia, 2022f), or in other words, the properties a single entity is made of. For example, the invoice table could have columns such as id
, create_date
, company_id
, etc. The table’s rows each specify a single entity of data (Wikipedia, 2022g). So, a row in the invoice table from the last example would specify the data of a single invoice (see figure 1).
The model and theory behind the relational database were proposed by E. F. Codd in 1970 (Wikipedia, 2022d). Codd also defined a set of thirteen rules outlining the requirements of a relational database management system (RDBMS), known as Codd’s 12 rules (ordered 0–12) (Wikipedia, 2022h).
For example, Codd’s third rule describes the requirements for the behavior of absent information, which should be represented using a NULL
value (Wikipedia, 2022h). Another example is Codd’s fifth rule which describes the requirements related to having a least one language that can be used for database operations such as data manipulation or authorization (Wikipedia, 2022h).
A language widely used to configure relational databases is SQL (Wikipedia, 2022j). The language can be divided even further into sublanguages (see figure 2) called data query language (DQL), data definition language (DDL), data control language (DCL), data manipulation language (DML), and Data Transaction Language (DTL) (Wikipedia, 2022j) (Wikibooks, 2022).
Non-relational, or NoSQL databases are in contrast to relational databases based on other types of data structures than tables, such as key-value pairs or document stores (Wikipedia, 2022e). Examples of non-relational databases are MongoDB and Redis (MongoDB, 2022) (Redis, 2022).
2. Get Started With MySQL
MySQL is an open-source RDBMS released by a company named MySQL AB in 1995, and, at the time of writing (2022), distributed by Oracle Corporation (Wikipedia, 2022a) (Wikipedia, 2022i) (Oracle, 2022a). The RDBMS is supported on several operating systems such as Microsoft Windows 10, different versions of Linux Ubuntu, and macOS (Oracle, 2022b).
2.1. MySQL Workbench
An easy way to get started with MySQL is to download MySQL Community Server and MySQL Workbench. You can also use the MySQL Installer, currently only supported on Windows. MySQL Workbench is a tool that can be used to manage a MySQL Server, for example, MySQL Workbench can be used to send SQL statements to the server (Oracle, 2022c).
After installing the workbench, connect to the database by pressing the local instance and entering the password you created in the installation process (see figure 3).
MySQL Workbench got many different features for managing the database, but it is actually really easy to get started.
Figure 4 shows an example of how a simple SQL statement can be executed. The purple box on the left side of figure 4 shows where the statement should be written, and the green box shows how to execute the statement. The purple box on the right side of figure 4 shows where the result is outputted, and the green box shows information about the request.
2.2. Creating a Database
A new database can be added to the instance by using the statement: CREATE DATABASE
; followed by a preferred name (Oracle, 2022c). Let’s create a new database called test
which will be used in the following in section 2 (see figure 5).
The statement: SHOW DATABASES
; returns a list of databases on the connected instance (Oracle, 2022d). The list should return the new test
database, created in the last example.
2.3. Creating Tables
Tables can be created using the statement: CREATE TABLE
; followed by the table’s name, and column definitions (Oracle, 2022e).
Figure 7 shows an example of how to add a simple invoice table to the test database. The database is specified by inserting the database name before the table’s name: test.invoices
; (see line 1).
The invoice table has four columns: id
; due_amount
; due_date
; create_date
; The data type of the column is specified after the column’s name, for example, line 2 specifies the column id
should be of type INT
, and line 3 specifies the column due_date
should be of type FLOAT
. NOT NULL
specifies that a column cannot be empty, and DEFAULT
specifies a default value, for example, the column create_date
is defined to set the CURRENT_TIMESTAMP
as the default value for new rows added to the table.
CURRENT_TIMESTAMP
returns the current time, and AUTO_INCREMENT
ensures the column id
automatically gets assigned an incremented number for each row (Oracle, 2022h) (Oracle, 2022i).
PRIMARY KEY
, line 6, sets the column id
as the table’s primary key. The primary key is set to specify a unique identifier for each row, however, more details about primary keys will be introduced later in the article‘s section 3.
2.4. Inserting Into Tables
The statement: INSERT
; can be used to insert new rows (Oracle, 2022f). The statement should be followed by INTO
, the table’s name, attributes, and values.
Figure 8 shows an example of how to insert a new invoice with a due amount of 120.5. The invoice’s due_date
would automatically be set to null
since none was provided, and the create_date
would automatically be set to the specified default value (CURRENT_TIMESTAMP
).
Figure 9 shows an example of how to insert a new invoice with both a due_amount
and a due_date
. It should be noticed that the order of columns in the first parenthesis refers to values inserted in the same order in the second parenthesis.
2.5. Selecting Rows From Tables
The statement: SELECT
; can be used to get rows from a table (Oracle, 2022g). The statement should be followed by columns and a table’s name. Asterisk (*) can be used instead of specific column names to get all columns of a table. Figure 10 shows an example of how to get all rows in the invoices table.
It can be seen in figure 11 that the first row, inserted in the first example in section 2.4, has an id
set to 1, a due_amount
set to 120.5, a due_date
set to null, and a create_date
set to the time the row was inserted (Note: you should see two rows if you executed both insert examples in section 2.4).
2.6. Updating Rows
The statement: UPDATE
; can be used to update rows in a table (Oracle, 2022j). The statement should be followed by the table’s name, SET
, and the columns’ names set equal to their new values. Furthermore, the WHERE
clause can be added to specify the specific rows that should be updated.
Figure 12 shows an example of how to replace the due_date
of the first invoice inserted in section 2.4.
2.7. Deleting Rows
The statement: DELETE
; can be used to delete rows from a table (Oracle, 2022k). The statement should be followed by FROM
, and the table’s name. Furthermore, the WHERE
clause can be used to specify the specific rows as shown in the example with the UPDATE
statement.
Figure 13 shows an example of how to delete an invoice with an id equal to one.
2.8. Altering Tables
The statement: ALTER TABLE
; can be used to modify a table’s structure (Oracle, 2022m). The statement should be followed by the table’s name and the modification specification. For example, ALTER TABLE
can be used to ADD
, MODIFY
, or DROP
a column
.
Figure 14 shows an example of how a new column named state
can be added to the invoices table. The column’s data type is set to VARCHAR
with a length of 255. VARCHAR
is a string data type that can contain a set of characters, for example, words, numerical values, and symbols (Wikipedia, 2022l) (Oracle, 2022n).
Figure 15 shows an example of how to change the length of VARCHAR
to 300.
Figure 16 shows an example of how to delete the column state
from the invoices table.
2.9. Dropping Tables
The statement: DROP TABLE
; can be used to delete tables from a database (Oracle, 2022l). The statement should be followed by the table’s name.
Figure 17 shows an example of how to delete the invoices table from the test database.
3. Data Integrity
Constraints can be used to ensure the data integrity of the database. Three types of integrity constraints in the relational database model are domain integrity, entity integrity, and referential integrity (Wikipedia, 2022m).
3.1 Domain Integrity
Wikipedia (2022m) defines domain integrity as the requirement of columns to have a defined domain, and a domain in relational databases refers to a set of valid values allowed in rows of a specific column (Wikibooks, 2022b). For example, the column due_amount
in the invoices table, in section 2.3, was defined to be of type FLOAT
and NOT NULL
, restricting the column’s domain to only allow numerical values.
There are many other ways to restrict the domain of a column, for example, by using a check constraint. The check constraint was introduced in MySQL in version 8.0.16 (Hulakund, 2019).
3.2. Entity Integrity
Entity integrity is defined as a requirement that states a row must have an identifier that is unique and not null (Wikipedia, 2022n). The identifier is called the primary key (PK) (Wikipedia, 2022n).
A primary key can be defined with a single column, or several columns (Wikipedia, 2022d). Primary keys combined with several columns are called composite keys (Wikipedia, 2022d).
Two types of primary keys are surrogate and natural keys (Wikipedia, 2022p) (Wikipedia, 2022q). A surrogate key is a sequential key with no relation to the rest of the table’s data, simply used to uniquely identify a row (Wikipedia, 2022d).
A natural key is defined using the columns defining the table’s real-world entity (Wikipedia, 2022q). For example, a table of addresses could be assigned a primary key based on street name, street number, city, and country. This would mean that each address is identified by the real-world properties of an address, and it would also ensure that each address is unique.
3.3. Referential Integrity
Referential integrity is defined as a requirement concerned with whether or not a row in one table refers to an existing row in another table (Wikipedia, 2022o). This concept prevents having rows with invalid references. A column in a table can be defined as a foreign key to ensuring referential integrity is enforced (Wikipedia, 2022o).
The foreign key, in contrast to the primary key, is not required to be unique or not null (Wikipedia, 2022d). If a row with a column defining the foreign key is null, it simply means the row has no relationship.
4. Different Types Of Relationships
Three types of relationships in the relational database model are one-to-one, one-to-many, and many-to-many (Wikipedia, 2022d).
4.1. One-to-many
One-to-many describes a relationship where a row in one table has a relationship to many rows in another table (Wikipedia, 2022r).
For example, imagine an application where a user can get assigned a task. The database has two tables, one containing users with a column named id as the primary key, and another table containing tasks with a column named user_id as the foreign key (see figure 20).
Figure 21 shows an example of how to create the one-to-many relationship illustrated in figure 20. It should be noticed that the foreign key of the task table is defined on line 11 by using the keywords FOREIGN KEY
and REFERENCES
. FOREIGN KEY
should be followed by the name of the column that should be defined as a foreign key, and REFERENCES
should be followed by the name of the table and primary key that the foreign key has a reference to.
Figure 22 shows an example of how to add a user and a couple of tasks with a reference to the user. It should be noticed that the tasks are referring to a user with an id equal to one. If the tasks should refer to another user or no user at all, the user_id could simply be changed to another value.
But what if a task referring to a non-existing user was inserted? Figure 23, shows the insertion would fail with the following response:
Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`test`.`tasks`, CONSTRAINT `tasks_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
This error occurs because the insertion violates the referential integrity enforced by the foreign key configuration between the tables.
4.2. One-to-one
The one-to-one relationship is very similar to the one-to-many relationship. A one-to-one relationship between two tables means a single row in one table refers to a single row in another table (Wikipedia, 2022s).
Figure 24 shows an example of a one-to-one relationship where a single user can have a single address. It should be noticed the primary key of the address table is also the foreign key which refers to the user’s primary key. This configuration ensures that only one address for each user can exist.
Figure 25 shows an example of how to create the users and addresses table with a one-to-one relationship. It should be noticed the primary key defined in the addresses table does not include the AUTO_INCREMENT
configuration. This is because the primary key (and foreign key) should be equal to a user’s primary key, instead of being assigned a sequential value.
Figure 26 shows an example of adding a user and an address into the tables with a one-to-one relationship.
As explained in section 3.1, the insertion would fail if the specified foreign key was referring to a non-existing user, but what if two addresses were inserted with the same user_id?
Figure 27 shows the insertion would fail with the following response:
Error Code: 1062. Duplicate entry ‘1’ for key ‘addresses.PRIMARY’
This is because the table already contains a row with a primary key equal to one, thereby preventing a violation of the one-to-one relationship.
4.3. Many-to-many
A many-to-many relationship between two tables means a row in one table can have a relationship with many rows in another table, and one row in the other table can have a relationship with many rows in the first table as well (Wikipedia, 2022t).
The many-to-many relationship, in contrast to one-to-one and one-to-many, includes a third table mapping the relationship, known as the associative table (Wikipedia, 2022u).
Figure 28 shows an example of a many-to-many relationship where a user can have many messages, and a message can have many users. For example, imagine an application where a message can be sent to one or multiple recipients. Each user would, in this case, need the ability to have multiple messages, and the message could be for multiple users.
Figure 29 shows an example of how to create a many-to-many relationship between the users and the messages table by an associative table called user_message.
Figure 30 shows a simple example of how data can be inserted to create a message belonging to two different users. If this example were executed twice, it can be seen the users would have references to multiple messages, and the messages would have references to multiple users.
4.4. Fetch Entities With Relation
The last thing I want to introduce about relations is how to use the JOIN
clause to get entities together with matching entities in another table.
There exist different types of JOIN
clauses such as LEFT
, RIGHT
, INNER
, or CROSS
(Oracle, 2022o). Each type returns a different result, for example, LEFT JOIN
returns NULL
for the right table for all entities where there is no matching entity (Oracle, 2022o).
Imagine the scenario in section 4.2. with a one-to-one relationship between users and the addresses table. LEFT JOIN
could be used in this scenario to get all users and their addresses by matching addresses using the user_id
column (see figure 31).
If two users were created and one of them only had an address, the result would return NULL
for the address table for the user who does not have an address (see figure 32).
5. Normalization Of The Structure
Database normalization concerns avoiding anomalies and redundant data by structuring tables after the rules of normal forms (Wikipedia, 2022v). The concept was introduced by Codd in 1970 (Wikipedia, 2022v).
5.1. Anomalies
Three types of anomalies are the insertion anomaly, update anomaly, and deletion anomaly (Wikipedia, 2022v).
5.1.1. Insertion Anomaly
The insertion anomaly occurs when records cannot be inserted because of the table’s design.
For example, a table is created to assign students to different classes (see figure 33). The table’s column class
is defined as NOT NULL
because it is part of a natural primary key together with student ID. This means a student only can be created if the class is already known.
It may be thought that the column class
could be removed from the primary key, but this would result in rows which are no longer unique, so that is not a possibility.
5.1.2. Update Anomaly
The update anomaly occurs when multiple rows contain the same data and an update fails to update all rows specifying the same.
For example, the table in figure 34 contains two records of classes John Doe is a part of. At some point, John Doe changes his surname to Johnson resulting in all the existing records should be updated.
However, in a scenario where the update fails to change the data for every row would leave the database in a state where John Doe/Johnson is recorded with two different surnames.
5.1.3. Deletion Anomaly
The deletion anomaly occurs when deleting a row result in losing additional data.
For example, the table in figure 35 contains information about both the students’ names and the classes they are attending.
In a scenario where a student is removed from all their classes would result in all information about the student getting completely removed from the database.
5.2. Normal forms
There are different levels of normalization known as normal forms. The level starts with the least normalized form (First Normal Form, 1NF) and expands to the most normalized form (Sixth Normal Form, 6NF) (Wikipedia, 2022v).
5.2.1. First Normal Form, 1NF
The rules of the first normal form are cells should only contain atomic values and every row must be unique (Wikipedia, 2022v).
Figure 36 shows an example of a table containing students and their classes. It should be noticed the cells containing Student ID
and Names
are specifying multiple ids and names for each class which means the cells does not contain atomic values.
The solution if only a first normal form was the goal would be to ensure every student has its own row, split names up into two columns called first name
and surname
, and define the Class ID
and Student ID
as a composite key (see figure 37).
5.2.2. Second Normal Form, 2NF
The rules of the second normal form are tables should be in the first normal form, and partial functional dependencies of non-key attributes are not allowed (Wikipedia, 2022v).
Figure 38 shows the table from the last example which is currently in the first normal form. It can also be seen that it contains partial dependencies of non-key attributes only depending on part of the primary key.
The solution is to split the table up into the following three tables (see figure 39). The columns/attributes of each table are now fully dependent on the primary key.
5.2.3. Third Normal Form, 3NF
The rules of the third normal form are tables should be in the second normal form, and transitive functional dependencies of non-key attributes are not allowed.
To demonstrate the idea of a transitive dependency, let’s assume the unnormalized table in figure 36 was redesigned to only use the Student ID
as the primary key (see figure 40).
This design would not really make sense if a student were supposed to be assigned to multiple classes, but I think it clearly demonstrate the idea of the transitive dependency.
Because, if a student changes the Class ID
to another class id, it automatically requires the class name also to be changed.
The solution is to either adding a one-to-many relationship, or a many-to-many relationship as shown in figure 39.
8. Bibliography
Hulakund. P. 2019. MySQL :: MySQL 8.0.16 Introducing CHECK constraint. [online] Available at: <https://dev.mysql.com/blog-archive/mysql-8-0-16-introducing-check-constraint/> [Accessed 1 October 2022].
MongoDB. 2022. Relational Vs. Non-Relational Databases | MongoDB. [online] MongoDB. Available at: <https://www.mongodb.com/compare/relational-vs-non-relational-databases> [Accessed 2 October 2022].
Oracle. 2022a. MySQL :: MySQL 8.0 Reference Manual :: 1.2.1 What is MySQL?. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/what-is-mysql.html> [Accessed 1 October 2022].
Oracle. 2022b. MySQL :: Supported Platforms: MySQL Database. [online] Available at: <https://www.mysql.com/support/supportedplatforms/database.html> [Accessed 1 October 2022].
Oracle. 2022c. MySQL :: MySQL 8.0 Reference Manual :: 13.1.12 CREATE DATABASE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/create-database.html> [Accessed 3 October 2022].
Oracle. 2022c. MySQL :: MySQL Workbench Manual :: 1 General Information. [online] Available at: <https://dev.mysql.com/doc/workbench/en/wb-intro.html> [Accessed 2 October 2022].
Oracle. 2022d. MySQL :: MySQL 8.0 Reference Manual :: 13.7.7.14 SHOW DATABASES Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/show-databases.html> [Accessed 3 October 2022].
Oracle. 2022e. MySQL :: MySQL 8.0 Reference Manual :: 13.1.20 CREATE TABLE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/create-table.html> [Accessed 3 October 2022].
Oracle. 2022f. MySQL :: MySQL 8.0 Reference Manual :: 13.2.6 INSERT Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/insert.html> [Accessed 3 October 2022].
Oracle. 2022g. MySQL :: MySQL 8.0 Reference Manual :: 13.2.10 SELECT Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/select.html> [Accessed 3 October 2022].
Oracle. 2022h. MySQL :: MySQL 8.0 Reference Manual :: 12.7 Date and Time Functions. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_current-time> [Accessed 3 October 2022].
Oracle. 2022i. MySQL :: MySQL 8.0 Reference Manual :: 3.6.9 Using AUTO_INCREMENT. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html> [Accessed 3 October 2022].
Oracle. 2022j. MySQL :: MySQL 8.0 Reference Manual :: 13.2.13 UPDATE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/update.html> [Accessed 3 October 2022].
Oracle. 2022k. MySQL :: MySQL 8.0 Reference Manual :: 13.2.2 DELETE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/delete.html> [Accessed 3 October 2022].
Oracle. 2022l. MySQL :: MySQL 8.0 Reference Manual :: 13.1.32 DROP TABLE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/drop-table.html> [Accessed 3 October 2022].
Oracle. 2022m. MySQL :: MySQL 8.0 Reference Manual :: 13.1.9 ALTER TABLE Statement. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/alter-table.html> [Accessed 3 October 2022].
Oracle. 2022n. MySQL :: MySQL 8.0 Reference Manual :: 11.3 String Data Types. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/string-types.html> [Accessed 3 October 2022].
Oracle. 2022o. MySQL 8.0 Reference Manual :: 13.2.10.2 join clause. [online] Available at: <https://dev.mysql.com/doc/refman/8.0/en/join.html> [Accessed: November 12, 2022].
Redis. 2022. What Is NoSQL | Redis. [online] Available at: <https://redis.com/nosql/what-is-nosql/> [Accessed 2 October 2022].
Wikipedia. 2022a. MySQL — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/MySQL> [Accessed 1 October 2022].
Wikipedia. 2022b. Microsoft SQL Server — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Microsoft_SQL_Server> [Accessed 1 October 2022].
Wikipedia. 2022c. PostgreSQL — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/PostgreSQL> [Accessed 1 October 2022].
Wikipedia. 2022d. Relational database — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Relational_database> [Accessed 1 October 2022].
Wikipedia. 2022e. NoSQL — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/NoSQL> [Accessed 1 October 2022].
Wikipedia. 2022f. Column (database) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Column_(database)> [Accessed 1 October 2022].
Wikipedia. 2022g. Row (database) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Row_(database)> [Accessed 1 October 2022].
Wikipedia. 2022h. Codd’s 12 rules — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Codd%27s_12_rules> [Accessed 1 October 2022].
Wikipedia. 2022i. MySQL AB — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/MySQL_AB> [Accessed 1 October 2022].
Wikipedia. 2022j. SQL — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/SQL> [Accessed 2 October 2022].
Wikipedia. 2022k. SQL syntax — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/SQL_syntax> [Accessed 2 October 2022].
Wikipedia. 2022l. String (computer science) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/String_(computer_science)> [Accessed 3 October 2022].
Wikipedia. 2022m. Data integrity — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Data_integrity#TYPES> [Accessed 5 October 2022].
Wikipedia. 2022n. Entity integrity — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Entity_integrity> [Accessed 5 October 2022].
Wikipedia. 2022o. Referential integrity — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Referential_integrity> [Accessed 5 October 2022].
Wikipedia. 2022p. Surrogate key — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Surrogate_key> [Accessed 5 October 2022].
Wikipedia. 2022q. Natural key — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Natural_key> [Accessed 5 October 2022].
Wikipedia. 2022r. One-to-many (data model) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/One-to-many_(data_model)> [Accessed 11 October 2022].
Wikipedia. 2022s. One-to-one (data model) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/One-to-one_(data_model)> [Accessed 11 October 2022].
Wikipedia. 2022t. Many-to-many (data model) — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Many-to-many_(data_model)> [Accessed 11 October 2022].
Wikipedia. 2022u. Associative entity — Wikipedia. [online] Available at: <https://en.wikipedia.org/wiki/Associative_entity> [Accessed 11 October 2022].
Wikipedia. 2022v. Database normalization. Available at: https://en.wikipedia.org/wiki/Database_normalization (Accessed: October 23, 2022).
Wikibooks. 2022a. MySQL/Language/Definitions: what are DDL, DML and DQL? — Wikibooks, open books for an open world. [online] Available at: <https://en.wikibooks.org/wiki/MySQL/Language/Definitions:_what_are_DDL,_DML_and_DQL%3F> [Accessed 3 October 2022].
Wikibooks. 2022b. Database Design/The Relational Data Model — Wikibooks, open books for an open world. [online] Available at: <https://en.wikibooks.org/wiki/Database_Design/The_Relational_Data_Model> [Accessed 5 October 2022].