{"id":21,"date":"2011-07-13T10:56:33","date_gmt":"2011-07-13T08:56:33","guid":{"rendered":"http:\/\/arturicast.co.za\/blogs\/?p=21"},"modified":"2024-05-13T13:31:06","modified_gmt":"2024-05-13T11:31:06","slug":"why-normalise","status":"publish","type":"post","link":"https:\/\/arturicast.co.za\/blogs\/2011\/07\/13\/why-normalise\/","title":{"rendered":"Why Normalise Database Tables?"},"content":{"rendered":"<p>Many GUI and web developers I have spoken to, do not fully understand the value to be gained from normalising their database designs. It is, after all, easier to build the tables to look exactly like the form or web page they are building.<\/p>\n<p>The question that usually arises when we as database &#8220;specialists&#8221; question them is: but what is wrong with that design? my code works, doesn&#8217;t it?<\/p>\n<p>The obvious answer to this would be &#8220;yes, your code works&#8221;, but does it really?<\/p>\n<p>Designing tables in this manner will eventually have serious drawbacks, including, but not limited to, redundancy, wasted space and loss of data integrity.<\/p>\n<p>As an example, we will use an extract of one table, from a failed company (the reason for it&#8217;s eventual failure will become apparent in due course).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-228 size-full\" src=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/OrderTableDefinition.jpg\" alt=\"Definition Of Order Table\" width=\"498\" height=\"582\" srcset=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/OrderTableDefinition.jpg 498w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/OrderTableDefinition-257x300.jpg 257w\" sizes=\"auto, (max-width: 498px) 100vw, 498px\" \/><\/p>\n<p>Now the referenced programmers defend their design, stating that it is normalised, as it does have a primary key, so the rows are uniquely identifyable.<\/p>\n<p>OK, let us look at that statement.<\/p>\n<p>Yes, there is a primary key. Now, does having a primary key make a table Normalised?<\/p>\n<p>The answer is yes, provided it also complies to First Normal Form (1NF) and Second Normal Form (2NF) rules. This table does not comply to 1NF rules, which state that:<\/p>\n<p>&gt; the table is a faithful representation of a relation<br \/>\n&gt; it is free of repeating groups<\/p>\n<p>(see here for a definition of <a title=\"1NF\" href=\"http:\/\/en.wikipedia.org\/wiki\/First_normal_form\" target=\"_blank\" rel=\"noopener\">1NF<\/a>)<\/p>\n<p>So, How do we go about normalising this data set?<\/p>\n<p>&gt; First, let us eliminate the repeating columns, by placing all these columns in their own table, which will look as follows once complete:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-230\" src=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/FirstNotmalForm.jpg\" alt=\"Remove Repeating Columns\" width=\"680\" height=\"418\" srcset=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/FirstNotmalForm.jpg 680w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/FirstNotmalForm-300x184.jpg 300w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" \/><\/p>\n<p>Now, looking at the resulting tables, we can see they comply to 1NF.<\/p>\n<p>Now, let us check that they comply to 2NF, which states:<\/p>\n<p>&gt; Identify a candidate key;<br \/>\n&gt; Ensure those records are\u00a0supportive of said candidate key, i.e. those that are dependent on the candidate key, with no partial dependencies.<\/p>\n<p>for Orders, a good candidate key would be OrderNumber (which we will make into a Primary Key, as it must, of needs, remain unique) and for PartsPerOrder, OrderNumber and Part make a good choice for candidate key (we will create a surrogate key (viz. PartPerOrderID) as the primary key, with a non clustered index covering the candidate key(s) (along with the respective foreign keys)<\/p>\n<p>Thus the structure now complies to\u00a02NF .<\/p>\n<p>(see here for a definition of <a title=\"2NF\" href=\"http:\/\/en.wikipedia.org\/wiki\/Second_normal_form\" target=\"_blank\" rel=\"noopener\">2NF<\/a>)<\/p>\n<p>Now we need to go further.\u00a0Are there any fields in the tables that do not belong (i.e. do not describe the record in the table)?<\/p>\n<p>The PartPerOrder table still has a field for the Sales Person&#8217;s mobile phone. If the salesperson changes their Mobile number, this will need to be updated in each and every order that person was involved in. That could (and quite possibly will) lead to data anomalies.<\/p>\n<p>How do we now eliminate this data?<br \/>\nBy applying the rules for Third Normal Form (3NF).<\/p>\n<p>We can ask if this data may already exist in another table. Shouldn&#8217;t the salesperson contact information therefore\u00a0be stored\u00a0in the Staff table?<\/p>\n<p>Checking the Staff table, we do indeed find a column labelled &#8220;MobilePhone&#8221;, which should, presuming it has been completed correctly, contain the person&#8217;s correct mobile number.<\/p>\n<p>Removing this and using the column in the Staff table gives us the following:<\/p>\n<p><a href=\"http:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/3NF.bmp\"><img decoding=\"async\" class=\"alignnone size-full wp-image-43\" title=\"3rd Normal Form\" src=\"http:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/3NF.bmp\" alt=\"\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-233\" src=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/thirdNornamForm.jpg\" alt=\"\" width=\"1065\" height=\"432\" srcset=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/thirdNornamForm.jpg 1065w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/thirdNornamForm-300x122.jpg 300w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/thirdNornamForm-1024x415.jpg 1024w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/thirdNornamForm-768x312.jpg 768w\" sizes=\"auto, (max-width: 1065px) 100vw, 1065px\" \/><\/a><\/p>\n<p>Now there\u00a0are no redundant data columns in the tables, which gives a much cleaner design (see here for a definition of <a title=\"3rd Normal Form\" href=\"http:\/\/en.wikipedia.org\/wiki\/Third_normal_form\" target=\"_blank\" rel=\"noopener\">3NF<\/a>).<\/p>\n<p>Is it possible to improve the data?<br \/>\nYes, we can proceed to the next level of Normalisation.<br \/>\nThis next level of normalisation is termed Boyce-Codd Normal Form (BCNF) (also called 3.5 Normal Form (3.5NF) by some theorists).<\/p>\n<p>The aim here is to ask if a column really describes the table and, if not, move it to another table (and, in so doing, probably eliminate existing nullable columns).<\/p>\n<p>In the Staff table, there are columns that do not explicitly describe the staff member as a person, viz. their contact details (Extension and MobilePhone).<\/p>\n<p>We therefore create a new table to carry the staff member&#8217;s contact information, and remove them from the Staff table. This could be called StaffContactDetails and will appear as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-235\" src=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/BCNF.jpg\" alt=\"\" width=\"1051\" height=\"428\" srcset=\"https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/BCNF.jpg 1051w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/BCNF-300x122.jpg 300w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/BCNF-1024x417.jpg 1024w, https:\/\/arturicast.co.za\/blogs\/wp-content\/uploads\/2011\/07\/BCNF-768x313.jpg 768w\" sizes=\"auto, (max-width: 1051px) 100vw, 1051px\" \/><\/p>\n<p>Now there are really no redundant data columns visible, and the number of nullable columns is greatly reduced (see here for a definition of <a title=\"Boyce-Codd Normal Form\" href=\"http:\/\/en.wikipedia.org\/wiki\/Boyce%E2%80%93Codd_normal_form\" target=\"_blank\" rel=\"noopener\">BCNF<\/a>).<\/p>\n<p>The nullable columns that are left add value where they are, as they do describe the tables and will, eventually, be filled in (e.g. when an order is finalised and paid).<\/p>\n<p>We could, however, normalise this design\u00a0further, but we need to ask ourselves if this will add value in terms of both storage space and performance (for details of the other levels of normalisation, refer to <a title=\"Fourth Normal Form\" href=\"http:\/\/en.wikipedia.org\/wiki\/Fourth_normal_form\" target=\"_blank\" rel=\"noopener\">Fourth Normal Form (4NF)<\/a>, <a title=\"Fifth Normal Form\" href=\"http:\/\/en.wikipedia.org\/wiki\/Fifth_normal_form\" target=\"_blank\" rel=\"noopener\">Fifth Normal Form (5NF)<\/a>\u00a0and <a title=\"Sixth Normal Form\" href=\"http:\/\/en.wikipedia.org\/wiki\/Sixth_normal_form\" target=\"_blank\" rel=\"noopener\">Sixth Normal Form (6NF)<\/a>).<\/p>\n<p>The programmer would now scream and shout, stating that his code will not work, he cannot represent this &#8220;shattered&#8221; data in his front-end, he will have to start all over again, etc., etc. ad nausium.<\/p>\n<p>Whereupon we, as the database &#8220;guys&#8221; will simply answer: &#8220;Haven&#8217;t you ever heard of a view or stored procedure?&#8221;.<\/p>\n<p>In any event, using our example, why did the company fail?<br \/>\n&gt; what happens when a client has a large order, wherein they request numerous different parts (substantially more that 5)?<br \/>\n&#8211; There will be one order generated and paid for for each 5 parts required. If the client required 100 different parts, there will be 20 orders completed, each one have to be settled independently.<br \/>\n&#8211; This is expensive and time-consuming, not to mention frustrating.<\/p>\n<p>&#8211; Most people will rather go to a competitor, who has a simpler and more streamlined process (with a well designed database), who can process all parts in one order, with one payment.<\/p>\n<p>When the developer was asked why it was done this way, he replied that management assured him no-one would order more that 5 parts at a time &#8211; this points back to:<br \/>\n&gt; not understanding the business nor the environment in which the client operates, and<br \/>\n&gt; poor requirement gathering skills.<\/p>\n<p>Requirement elicitation will be handled in a future post to this blog&#8230;..<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many GUI and web developers I have spoken to, do not fully understand the value to be gained from normalising their database designs. It is, after all, easier to build the tables to look exactly like the form or web page they are building. The question that usually arises when we as database &#8220;specialists&#8221; question [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[24,26],"class_list":["post-21","post","type-post","status-publish","format-standard","hentry","category-database","tag-normalise","tag-sql"],"_links":{"self":[{"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/posts\/21","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/comments?post=21"}],"version-history":[{"count":3,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/posts\/21\/revisions"}],"predecessor-version":[{"id":236,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/posts\/21\/revisions\/236"}],"wp:attachment":[{"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/media?parent=21"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/categories?post=21"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arturicast.co.za\/blogs\/wp-json\/wp\/v2\/tags?post=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}