{"id":112978,"date":"2026-11-04T12:00:00","date_gmt":"2026-11-04T12:00:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=112978"},"modified":"2026-10-22T13:32:19","modified_gmt":"2026-10-22T13:32:19","slug":"2nf-and-bcnf-explained-the-whole-key-nothing-but-the-key","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/2nf-and-bcnf-explained-the-whole-key-nothing-but-the-key\/","title":{"rendered":"2NF and BCNF explained: the whole key, nothing but the key"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>&#8216;Normal Forms&#8217; are database normalization rules designed to prevent data duplication and editing anomalies in relational databases. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>&#8216;Second Normal Form&#8217; (2NF) requires every column to depend on the <em>entire<\/em> table key, not just part of it, while &#8216;Boyce-Codd Normal Form&#8217; (BCNF) tightens this further so no column depends on anything other than the key. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The classic mnemonic \u2014 &#8220;the key, the whole key, and nothing but the key&#8221; \u2014 captures all three normal forms in one line. This guide breaks down what each rule <em>actually<\/em> means, using worked examples you can apply to your own schema.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-are-normal-forms-and-why-do-they-matter\">What are normal forms, and why do they matter?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Proper data modeling is crucial when designing a new database, and the first step in modeling is applying a set of table-structuring rules we call the &#8216;<strong>Normal Forms<\/strong>&#8216;. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These rules promote referential integrity, remove data redundancy, allow efficient querying, and help prevent editing anomalies. We covered the first of these rules, the aptly-named &#8216;<strong>First Normal Form<\/strong>&#8216;, in <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/first-normal-form-1nf-breaking-the-unbreakable-rule-in-database-design\/\" target=\"_blank\" rel=\"noreferrer noopener\">part one<\/a> of this series.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>This is part two of <a href=\"https:\/\/www.red-gate.com\/simple-talk\/collections\/the-normal-forms-set-of-database-design-rules-complete-guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">Lee Asher&#8217;s complete guide series to the &#8216;Normal Forms&#8217; set of database design rules<\/a>.<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While &#8216;First Normal Form&#8217; (1NF) is fairly easy to remember, the higher-order forms have formal definitions that seem designed to confuse. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The goal of this article is twofold: first, to give you an easy, unforgettable way to remember these rules, and \u2013 more importantly \u2013 to show specifically <em>why <\/em>these rules exist, and the problems you can avoid by following them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To recall these normal-form rules, just remember a simple mnemonic phrase, one that will be immediately familiar to any fan of legal dramas:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>The Key, the Whole Key, and Nothing But the Key<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This phrase has three parts, representing three different rules. We&#8217;ll discuss each separately.<\/p>\n\n\n\n<div id=\"callout-block_728454876ac1f78630fd81201351798d\" class=\"callout alignnone\">\n    <div class=\"child-last:mb-0 child-first:mt-0 bg-gray-50 dark:bg-gray-950 p-4xl my-3xl\">\n\n<p class=\"wp-block-paragraph\"><strong>You may also be interested in&#8230;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/normalforms\/#boyce-codd-normal-form-bcnf\" target=\"_blank\" rel=\"noreferrer noopener\">Joe Celko&#8217;s guide to database &#8216;Normal Forms&#8217;<\/a><\/p>\n\n<\/div>\n<\/div> \n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-key-every-key-must-depend-on-the-table-s-key\">The Key (every key must depend on the table&#8217;s key)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>&#8216;The Key&#8217; rule simply means that every table needs a key, and every column in the table must depend on that key. In other words, the key value determines the value of all other data in the row.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider this table in a simple POS (point of sale) database, recording purchases at a retail shop:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"171\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-23.gif\" alt=\"An image showing a table of a simple POS database recording purchases at a retail shop.\" class=\"wp-image-112979\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, <code>sale_id<\/code> is the table&#8217;s primary key, and <code>sale_amount<\/code>,\u00a0<code>tax_amount<\/code>, and <code>total<\/code> depend <em>directly<\/em> on that key. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the <code>tax_rate<\/code> column does <em>not<\/em> depend on the key. Static facts like this should be removed into a separate fact table, rather than duplicating that data throughout the entire table.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This first rule is so simple it barely merits mention. The next one is a bit more complex.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-whole-key-second-normal-form-2nf-explained\">The Whole Key: Second Normal Form (2NF) explained<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The &#8216;Whole Key&#8217; rule requires that every table column must depend on the <em>entire<\/em> key.<\/strong> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That, in turn, only makes sense when a key has multiple parts &#8211; which brings us to the subject of <strong>multi-part keys<\/strong>. We&#8217;ll illustrate this with the table below, representing college course enrollments and final grades:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"633\" height=\"170\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-24.gif\" alt=\"An image showing a table representing college course enrollments and final grades.\" class=\"wp-image-112980\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Since a student can take the same course multiple times (once per term), the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/theory-and-design\/uniqueness-keys-and-identity\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>unique key<\/strong><\/a> for each row is the combination of three different columns: <code>student_id<\/code>, <code>course_id<\/code>, and <code>term<\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A student&#8217;s grade depends on all three of these, so it complies with our rule &#8211; but the <code>instructor<\/code> column is <em>only<\/em> dependent on two of them: <code>course_id<\/code> and <code>term<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see from the repeated instructor name, this causes duplication of data and generates what&#8217;s known as an <strong><a href=\"https:\/\/www.red-gate.com\/blog\/update-anomalies\/\" target=\"_blank\" rel=\"noreferrer noopener\">update anomaly<\/a><\/strong>. To change one fact \u2013 the instructor for each class \u2013 multiple rows must be edited. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This impacts performance but, more importantly, raises the possibility that two rows referring to the same class might disagree on <code>instructor<\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The bottom line: a fact should only be stored in one location &#8211; referred to in data modeling as the <strong>&#8216;single source of truth&#8217; (SSOT).<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;We can solve this problem by decomposing the original table into two new ones:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1008\" height=\"173\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-3.png\" alt=\"an image showing the two tables merged.\" class=\"wp-image-113007\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-3.png 1008w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-3-300x51.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-3-768x132.png 768w\" sizes=\"auto, (max-width: 1008px) 100vw, 1008px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This &#8216;Whole Key&#8217; rule is formally known as <strong>&#8216;2NF: Second Normal Form&#8217;.<\/strong> Now, you&#8217;ll never forget it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The three-part key for this table is rather cumbersome to use, so most shops would also add a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/the-secret-life-of-database-keys\/#:~:text=from%20all%20others.-,Why%20use%20a%20surrogate%20database%20key%3F,-Some%20tables%20lack\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>surrogate key<\/strong><\/a> to identify each row (perhaps <code>enrollment_id<\/code> or something similar). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In fact, some shops add surrogates for <em>all<\/em> tables, even when they have a <strong><a href=\"https:\/\/www.ibm.com\/docs\/no\/iis\/11.7.0?topic=analysis-identifying-single-column-natural-key\" target=\"_blank\" rel=\"noreferrer noopener\">single-column natural key<\/a>.<\/strong> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, that doesn&#8217;t change the fundamental point that a <strong>surrogate key stands in for the natural key; it doesn&#8217;t alter the column dependencies.<\/strong><\/p>\n\n\n\n<div id=\"callout-block_728454876ac1f78630fd81201351798d\" class=\"callout alignnone\">\n    <div class=\"child-last:mb-0 child-first:mt-0 bg-gray-50 dark:bg-gray-950 p-4xl my-3xl\">\n\n<p class=\"wp-block-paragraph\"><strong>You may also be interested in&#8230;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/dependencies-and-references-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to find and track object references in SQL Server (guide to dependencies)<\/a><\/p>\n\n<\/div>\n<\/div> \n\n\n<h2 class=\"wp-block-heading\" id=\"h-nothing-but-the-key-bryce-codd-normal-form-bcnf-explained\">Nothing But the Key: Bryce-Codd Normal Form (BCNF) explained<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The &#8216;Nothing But the Key&#8217; rule requires that table columns <em>only<\/em> depend on the table key itself.<\/strong> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This time, we&#8217;ll start with a table that <em>does<\/em> correctly conform to the rule. Our example is a medical research firm wishing to perform statistical analysis on the blood type of people who&#8217;ve been diagnosed with certain types of cancer. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For each case, they store the patient blood type:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"275\" height=\"165\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-26.gif\" alt=\"an image showing the table of the stored patient blood type.\" class=\"wp-image-112981\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Expressed in the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Functional_dependency\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>functional dependencies<\/strong><\/a> of data modeling language, the rule for this table is simply:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>case_id<\/code>\u00a0\u00a0\u00a0\u00a0>>>\u00a0\u00a0 <code>blood_type<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Don&#8217;t be put off by the notation here. The arrow simply means the value on the left determines the value on the right. So, if you know the <code>case_id<\/code>, you also know the patient&#8217;s age.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The firm later expands their database to include patient name and address to enable direct contact with the patient. They add two new columns to the table:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"170\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-25.gif\" alt=\"An image showing the expanded table, with two new columns: patient_name and patient_address.\" class=\"wp-image-112984\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This adds two new functional dependencies to the table:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>case_id<\/code>\u00a0\u00a0\u00a0\u00a0>>>\u00a0\u00a0\u00a0<code>patient_name<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>case_id<\/code>\u00a0\u00a0  >>>\u00a0\u00a0<code>patient_address<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, this list isn&#8217;t yet complete. Patient address and blood type also depend on the patient name:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>patient_name<\/code>\u00a0\u00a0 >>>\u00a0\u00a0\u00a0<code>patient_address<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>patient_name<\/code>\u00a0  >>>\u00a0\u00a0\u00a0\u00a0<code>blood_type<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we have columns that are not only dependent on the table key, but also something else &#8211; so our rule is violated. To correct that violation, we must decompose patient data into a separate table. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This rule is formally known as <strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/normalforms\/#boyce-codd-normal-form-bcnf:~:text=time%20it%20is.-,Boyce%2DCodd%20Normal%20Form%20(BCNF),-A%20table%20is\" target=\"_blank\" rel=\"noreferrer noopener\">Boyce-Codd Normal Form (BCNF)<\/a><\/strong>. The latter name refers to <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/theory-and-design\/codds-twelve-rules\/\" target=\"_blank\" rel=\"noreferrer noopener\">Dr. Edgar Codd<\/a>, who first fabricated these normalization rules and is immortalized in the full version of our mnemonic phrase: &#8220;the key, the whole key, and nothing but the key &#8212; so help me Codd&#8221;.<\/p>\n\n\n\n<section id=\"my-first-block-block_c377eddc75fd69b2d42a130b08559bb8\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Subscribe to the Simple Talk newsletter<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            All the latest articles, guides, podcasts, and more &#8211; delivered straight to your inbox.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/simple-talk\/subscribe\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Subscribe now: Subscribe to the Simple Talk newsletter\">Subscribe now<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-update-and-delete-anomalies-bcnf-prevents\">The update and delete anomalies BCNF prevents<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not correcting the violation would result in us having both an <strong>update anomaly<\/strong> <em>and<\/em> a <strong>delete anomaly<\/strong>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The update anomaly would involve a patient whose cancer recurs appear twice in the table (potentially with different data each time).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The delete anomaly, on the other hand, means that deleting a patient&#8217;s case would also remove the association between the patient name, address, and blood type.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-about-third-normal-form\">What about &#8216;Third Normal Form&#8217;?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll notice we covered 2NF and BCNF, but what happened to <strong>&#8216;Third Normal Form&#8217; (3NF)<\/strong>? Well, BCNF is essentially a slightly stricter version of 3NF&#8217;s big brother.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The two forms actually function identically except in the unusual case where a table has multiple overlapping <strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Composite_key\" target=\"_blank\" rel=\"noreferrer noopener\">composite keys<\/a><\/strong>. In brief: <strong>a table in BCNF is by definition in 3NF, and nearly every table in 3NF is <em>also<\/em> BCNF<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-are-the-key-differences-between-bcnf-and-3nf\">What are the key differences between BCNF and 3NF?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The difference between the two forms is really very simple (though you&#8217;d never know it from most college courses on the subject). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>In 3NF, a column isn&#8217;t required to depend on the table key if <em>that column itself is part of another key.<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s visualize this. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A company has a skill-building program it encourages its employees to join, based across various teams. While an employee can join <em>multiple<\/em> teams, they&#8217;re assigned just one mentor, and that mentor can only be assigned to one team &#8211; despite a team potentially having multiple mentors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s some sample data:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"540\" height=\"201\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-29.gif\" alt=\"An image showing a table of sample data.\" class=\"wp-image-112986\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Expressed in the functional dependencies of data modeling language, the constraints for this table are:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>(employee, team)<\/code>\u00a0\u00a0>>>\u00a0\u00a0\u00a0<code>mentor<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>(mentor)<\/code>\u00a0\u00a0\u00a0>>>\u00a0\u00a0\u00a0<code>team<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second one is the problem: the <code>team<\/code> column depends on <code>mentor<\/code>, which is <em>not<\/em> &#8216;the whole key&#8217;. Thus, the table is <em>not<\/em> in BCNF. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It <em>is<\/em>, however, in 3NF, since the team itself is part of a key (a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Candidate_key#:~:text=The%20columns%20in%20a%20candidate%20key%20are%20called%20prime%20attributes\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>&#8216;prime attribute&#8217;<\/strong><\/a> in modeling terms.) So what exactly is the problem with this form, and why would we want to move past it to BCNF? <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Well, the example table has the dreaded <strong>delete anomaly<\/strong>. If employee &#8220;Schrute, D.&#8221; drops from the team &#8220;Office Conflict Resolution&#8221;, the fact that Smith is a mentor for this team is lost. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Decomposing the table into two BCNF-compliant tables solves that problem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-can-every-table-always-reach-bcnf-no-here-s-the-exception\">Can every table <em>always<\/em> reach BCNF? (No &#8211; here&#8217;s the exception)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A table can always be structured to at least the 3NF level, but a table in 3NF can&#8217;t <em>always<\/em> be converted to BCNF without losing a functional dependency. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example hospital shift roster of nurses assigned to patients:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"398\" height=\"144\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-27.gif\" alt=\"image of a table - example hospital shift roster of nurses assigned to patients.\" class=\"wp-image-112983\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Each nurse can have multiple patients, but is assigned to one shift only. Each patient has a single nurse for each shift. In modeling terms, these two functional dependencies are represented as:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>nurse<\/code>\u00a0\u00a0  >>> \u00a0 <code>shift<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>(patient, shift)<\/code>   >>>\u00a0\u00a0 <code>nurse<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The possible <strong><a href=\"https:\/\/www.red-gate.com\/blog\/candidate-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">candidate keys<\/a><\/strong> are <code>(patient, nurse)<\/code> and <code>(patient, shift)<\/code>. See the overlap? <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>This is the only time you\u2019ll see a table in 3NF but <em>not<\/em> in BCNF.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-is-this-table-in-3nf-but-not-in-bcnf\">Why is this table in 3NF but <em>not<\/em> in BCNF?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This table isn&#8217;t BCNF because the <code>shift<\/code> column depends on <code>nurse<\/code>. If you know the value of <code>nurse<\/code>, you also know their shift &#8211; but <code>nurse<\/code> is <em>not<\/em> a possible key for the table. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3NF, however, does allows this, because <code>shift<\/code> is part of the <code>(patient, shift)<\/code> key &#8211; a prime attribute.<\/p>\n\n\n\n<div id=\"callout-block_728454876ac1f78630fd81201351798d\" class=\"callout alignnone\">\n    <div class=\"child-last:mb-0 child-first:mt-0 bg-gray-50 dark:bg-gray-950 p-4xl my-3xl\">\n\n<p class=\"wp-block-paragraph\"><strong>You may also be interested in&#8230;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/primary-key-primer-for-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">Primary Key Primer for SQL Server<\/a><\/p>\n\n<\/div>\n<\/div> \n\n\n<p class=\"wp-block-paragraph\">Now, <strong>watch what happens when we decompose this 3NF table into two <em>separate<\/em> BCNF-compliant tables:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"698\" height=\"148\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-5.png\" alt=\"an image showing what happens when we decompose a 3NF table into two separate BCNF-compliant tables.\" class=\"wp-image-113011\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-5.png 698w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-5-300x64.png 300w\" sizes=\"auto, (max-width: 698px) 100vw, 698px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, the restriction that a patient can only have one nurse per shift is lost. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll notice I&#8217;ve changed the same data slightly, so that patient &#8220;Mallon, Mary&#8221; now has two nurses assigned to the same shift &#8211; something that wasn&#8217;t possible in the original table.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are limitations &#8211; you can only recover and enforce the lost constraint by joining the two tables, for example.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Still, though, that&#8217;s better better than the <strong>redundancy<\/strong> and <strong>delete<\/strong> anomaly caused by leaving the table at 3NF. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To see this, in the original 3NF table, let&#8217;s assign a nurse assigned to three different patients:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"404\" height=\"137\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/09\/image-28.gif\" alt=\"\" class=\"wp-image-112985\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If Nurse Barton changes shifts, three rows will require editing, not just one. This violates the &#8216;single source of truth&#8217; rule as a nurse&#8217;s shift should <em>only<\/em> be stored in one location. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And, if a nurse has no patients, there&#8217;s no way to represent what shift they&#8217;re assigned to in the first place.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-s-next-fourth-normal-form-and-fifth-normal-form\">What&#8217;s next: &#8216;Fourth Normal Form&#8217; and &#8216;Fifth Normal Form&#8217;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The last two rules are <strong>&#8216;Fourth Normal Form&#8217;<\/strong> and <strong>&#8216;Fifth Normal Form&#8217;<\/strong>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These are rarely taught in college data modeling classes, which is a shame because the situations they address crop up quite often in real-world databases. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll cover their use in Part 3 of the series.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Have any thoughts or comments? Feel free to share them down below!<\/em><\/strong><\/p>\n\n\n\n<section id=\"my-first-block-block_0c150a6bd3c16459afbea4fe80783fd7\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Simple Talk is brought to you by Redgate Software<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Take control of your databases with the trusted Database DevOps solutions provider. Automate with confidence, scale securely, and unlock growth through AI.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/solutions\/overview\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Discover how Redgate can help you: Simple Talk is brought to you by Redgate Software\">Discover how Redgate can help you<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. What&#039;s the difference between 2NF and BCNF?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">2NF requires every non-key column to depend on the whole key, not just part of it \u2014 this only matters when a table has a multi-column key. BCNF goes further, requiring that columns depend on nothing except the key at all. Most tables that meet 2NF also meet BCNF, unless a column depends on part of another candidate key.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. Is BCNF the same as third normal form (3NF)?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">Not quite. BCNF is a stricter version of 3NF. They behave identically except when a table has overlapping composite keys \u2014 3NF allows a column to skip depending on the full key if that column is itself part of another key, while BCNF doesn&#8217;t allow this exception at all.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. Can every table be converted to BCNF?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">No. A table can always reach 3NF, but converting some 3NF tables to BCNF loses a functional dependency \u2014 meaning a business rule (like &#8220;one nurse per patient per shift&#8221;) can only be enforced by joining tables back together, not within a single table.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">4. What is an update anomaly in database design?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">An update anomaly happens when the same fact is duplicated across multiple rows, so changing that fact means editing several rows instead of one. This risks rows disagreeing with each other and breaks the &#8220;single source of truth&#8221; principle that normalization is designed to protect.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">5. What does &quot;the key, the whole key, and nothing but the key&quot; mean?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">It&#8217;s a mnemonic for three normalization rules: every column must depend on the table&#8217;s key (1NF\/2NF basics), on the <em>entire<\/em> key when the key has multiple parts (2NF), and on <em>nothing but<\/em> the key (BCNF). The full phrase adds &#8220;so help me Codd,&#8221; honoring Dr. Edgar Codd, who created the rules.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Confused by 2NF and BCNF? Learn database normalization with real examples, so you can spot update and delete anomalies before they cause problems.&hellip;<\/p>\n","protected":false},"author":343663,"featured_media":103888,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143523,53],"tags":[4168,4170,159415],"coauthors":[159110],"class_list":["post-112978","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-databases","category-featured","tag-database","tag-database-administration","tag-normal-forms"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112978","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/343663"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=112978"}],"version-history":[{"count":21,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112978\/revisions"}],"predecessor-version":[{"id":113451,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112978\/revisions\/113451"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/103888"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=112978"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=112978"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=112978"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=112978"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}