From c558d4774e29a8efc148970b025cdb1dd00d924a Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Mon, 20 May 2019 19:42:07 -0500 Subject: [PATCH] Created Database Conventions and Guidelines (markdown) --- Database-Conventions-and-Guidelines.md | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Database-Conventions-and-Guidelines.md diff --git a/Database-Conventions-and-Guidelines.md b/Database-Conventions-and-Guidelines.md new file mode 100644 index 0000000..0f6b393 --- /dev/null +++ b/Database-Conventions-and-Guidelines.md @@ -0,0 +1,75 @@ +This page serves as a reference for rules that we adhere to as a project, things could change over time but this is mostly a living representation of our current spec + +This does not mean that past table creations match this specification, but that we intend to keep it consistent going forward + +## Table Names + +* lowercase +* snake_case +* Plural + +Table names should be **lowercase**, `snake_case` and should clearly describe the purpose of the table itself + +Table names should also adhere to an appropriate category prefix if necessary. For example, if the table is storing data that is particular to that of a character, it is appropriate to prefix the table name with `character_x` + +**Examples** + +``` +character_auras +character_bandolier +character_buffs +character_disciplines +``` + +When defining an object or model in the code, our source is inconsistent everywhere, but trend to use the singular name of an entity as an object and the table name as plural + +For example I have a class representing a `Door` and a table named `doors` + +## Column Naming + +Like **Table Names** columns also adhere to **lowercase** and `snake_case` appropriations. The column itself should very easily describe the purpose of the column itself without abbreviations as much as possible. + +For example, instead of `p_cp`, it is far easier for new server operators and developers to understand `player_copper`, don't be lazy and don't be afraid to be verbose. + +## Foreign Key Consistency + +If your column has a relationship to another table, make sure that it prefixes the table name with id + +**Example** + +I'm making a new table called `keyring` and the schema looks like this + +``` +id - int(11) pri - key +character_id - int(11) +item_id - int(11) +``` + +We easily know that we have a loose foreign key relationship to the `character_data` table (Which currently breaks convention and should be called `characters`) + +We also know that we have a loose relationship to the `items` table and we resolve to `items:id` + +# Have an Integer Primary Key + +At minimum, add the standard `id` column with an auto-incrementing integer. This makes sequencing easier + +# Store Datetimes as Datetimes + +We can easily convert to and from unix using datetime, use this as a standard practice + +# Indexes + +A simple index can go a long way for performance if you have data that is being looked up frequently especially in the case of strings. + +For example, we have a table called `saylink` (should be plural) that contains `phrase` which gets looked up frequently when a saylink is clicked or when saylinks are being parsed inside of a `quest::say` context, this lookup and scan gets expensive when there is no index on the column itself. What ends up happening is that the MySQL engine ends up having to do full table scans to find the phrase corresponding to the requested record to see if it exists or lookup and ID associated to said saylink + +If your table's primary method of lookup is through `id` - you already get indexing out of the box, there is no additional indexes required + +# Unsigned Versus Signed + +Only use what you intend to use for your integer space, if you don't plan on having negative values, make your field unsigned and corresponding C/C++ datatype to match. Or, use a bigger data integer type as signed to store your unsigned value + +# Soft Deletes + +If your table or feature uses the concept of soft deleting an object, please use `deleted_at` in a `datetime` field to mark that entity as deleted and then make sure you use queries that take into consideration where `deleted_at` is null (An index may be appropriate on this field) +