<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ metadata - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ metadata - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 05:06:40 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/metadata/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Configure Metadata for a Single-Page Application ]]>
                </title>
                <description>
                    <![CDATA[ By Scott Gary Why Metadata Matters Metadata is an integral part of any modern web app, because it's inherently tethered to search engine optimization (SEO).  Search engines and their respective results page (SERPS) rely on metadata to properly index ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/configure-metadata-in-single-page-applications/</link>
                <guid isPermaLink="false">66d460f0bd438296f45cd3b6</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metadata ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SEO ]]>
                    </category>
                
                    <category>
                        <![CDATA[  Single Page Applications  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 20 Sep 2022 17:20:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/meta-data-for-spa-seo.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Scott Gary</p>
<h2 id="heading-why-metadata-matters">Why Metadata Matters</h2>
<p>Metadata is an integral part of any modern web app, because it's inherently tethered to search engine optimization (SEO). </p>
<p>Search engines and their respective results page (SERPS) rely on metadata to properly index and display relative information for each site.</p>
<p>Also, meta tags are relied upon to properly display content from your site on a given social media platform, such as articles or items for sale.</p>
<p>For this reason, it's crucial to understand how metadata is configured in a modern web app.</p>
<p>The single page application (SPA) is a modern web app implementation that is incredibly popular. Most frameworks today utilize it in some way. Configuring metadata in today’s most popular SPA frameworks will be the focus of this tutorial.</p>
<h2 id="heading-the-single-page-application-and-metadata">The Single Page Application and Metadata</h2>
<p>The nature of SPAs make configuring metadata a less straightforward process than classic multiple page applications. I'm going to try to clarify this topic by describing the following key concepts:</p>
<ol>
<li>The structure of an SPA.</li>
<li>The problem with modifying metadata in an SPA.</li>
<li>Available metadata solutions using what are probably the three most popular SPA frameworks: React, Svelte, and Vue.</li>
</ol>
<p>You should have a basic understanding of HTML, metadata, and one of the three SPA frameworks to understand the concepts we’ll be going over. But, I’ll be keeping things beginner friendly, so don’t worry!</p>
<h2 id="heading-how-single-page-applications-work">How Single Page Applications Work</h2>
<p>Before diving in, you need a firm grasp of what constitutes an SPA. </p>
<p>As the name implies, a single page application literally consists of a single HTML page sent down from the server. This page is just an empty HTML shell, and will look something like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Home | Demystifying SPA Metadata<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"How to configure popular SPA             frameworks to maintain quality site metadata."</span>/&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"./stylesheet.css"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span>             /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/bundle.min.js"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>&gt;</span>                    <span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>You might be wondering how an entire website is derived from this empty HTML shell.</p>
<p>This is possible because along with the HTML page will be extensive client-side JavaScript code that generates the content for each page. This code is included in the page via the </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Creating a Custom React Hook for Gatsby Site Metadata ]]>
                </title>
                <description>
                    <![CDATA[ By Scott Spence Hooks ahoy! Ok, let's get it on with the new hotness in Reactland, React Hooks!This is a guide covering using the Gatsby custom React hook forStaticQuery which it is now replacing with useStaticQuery. If you haven't used Gatsby before... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/creating-a-custom-react-hook-for-gatsby-site-metadata/</link>
                <guid isPermaLink="false">66d852228acc348be2a441c8</guid>
                
                    <category>
                        <![CDATA[ Gatsby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metadata ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 24 Mar 2019 17:14:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/cover-5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Scott Spence</p>
<h2 id="heading-hooks-ahoy">Hooks ahoy!</h2>
<p>Ok, let's get it on with the new hotness in Reactland, React Hooks!<br>This is a guide covering using the Gatsby custom React hook for<br><code>StaticQuery</code> which it is now replacing with <code>useStaticQuery</code>.</p>
<p>If you haven't used Gatsby before <code>StaticQuery</code> is just that, a way to<br>query data in a Gatsby component (i.e. a react component) or a Gatsby<br>page where the query input doesn't change. This is a great use case<br>for data that doesn't change a great deal, like your site metadata.</p>
<h2 id="heading-tldr">tl;dr</h2>
<p>Here's me trying to <a target="_blank" href="https://youtu.be/8ruJBKFrRCk?t=93">even</a> with <a target="_blank" href="https://codesandbox.io">codesandbox.io</a> whilst I convert some<br>of the Gatsby default starter that's on <a target="_blank" href="https://codesandbox.io">codesandbox.io</a> to use the<br><code>useSiteMetadata</code> custom hook.</p>
<p>Using <a target="_blank" href="https://codesandbox.io">codesandbox.io</a> we take a look at implementing a custom react<br>hook for getting site metadata in Gatsby.</p>
<p><strong>Here's a video:</strong></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/qWay-LjXwbk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>The <code>StaticQuery</code> component uses the <a target="_blank" href="https://reactjs.org/docs/render-props.html">render props</a> pattern, which<br>means it takes in a function and returns/renders based off of that.</p>
<p>I have detailed this pattern before in a post about <a target="_blank" href="http://localhost:8899/react-context-api-getting-started">using the react</a><br><a target="_blank" href="http://localhost:8899/react-context-api-getting-started">context api</a>, it's a component that you pass a function to, to render<br>a component.</p>
<p>Think of it like this:</p>
<pre><code class="lang-jsx">&lt;Component&gt;
 {<span class="hljs-function">() =&gt;</span> ()}
&lt;/Component&gt;
</code></pre>
<p>The first parenthesis is the arguments/variables and the second is<br>what gets rendered, so in the case of the Gatsby <code>StaticQuery</code> you<br>pass a query with a <code>graphql</code> tag and then the <code>data</code> that comes back<br>from that is what is used in the render of that component. So you have<br>your wrapping component that returns and renders a child component,<br>like this.</p>
<pre><code class="lang-jsx">&lt;WrappingComponent&gt;
  {<span class="hljs-function"><span class="hljs-params">args</span> =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ComponentToRender</span> <span class="hljs-attr">propsForComponent</span>=<span class="hljs-string">{args.propNeeded}</span> /&gt;</span></span>}
&lt;/WrappingComponent&gt;
</code></pre>
<p>Here's a cut down version of the <code>StaticQuery</code> component being used in<br>the Gatsby default starter on <a target="_blank" href="https://codesandbox.io">codesandbox.io</a></p>
<p>I've taken out the styling to make it a bit shorter:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Layout = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">StaticQuery</span>
    <span class="hljs-attr">query</span>=<span class="hljs-string">{graphql</span>`
      <span class="hljs-attr">query</span> <span class="hljs-attr">SiteTitleQuery</span> {
        <span class="hljs-attr">site</span> {
          <span class="hljs-attr">siteMetadata</span> {
            <span class="hljs-attr">title</span>
          }
        }
      }
    `}
    <span class="hljs-attr">render</span>=<span class="hljs-string">{data</span> =&gt;</span> (
      <span class="hljs-tag">&lt;&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> <span class="hljs-attr">siteTitle</span>=<span class="hljs-string">{data.site.siteMetadata.title}</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">footer</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/&gt;</span></span>
    )}
  /&gt;
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Layout;
</code></pre>
<p>The <code>StaticQuery</code> takes in two props, the <code>query</code> and what you want to<br>render with <code>render</code>, this is where you can destructure the data you<br>need out of the <code>data</code> prop returned from the query.</p>
<p>I was never really a fan of doing it that way so I adopted a similar<br>pattern but with the component contained on it's own and then added to<br>the <code>StaticQuery</code> separately. Like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Layout = <span class="hljs-function">(<span class="hljs-params">{ children, data }</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> <span class="hljs-attr">siteTitle</span>=<span class="hljs-string">{data.site.siteMetadata.title}</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">footer</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/&gt;</span></span>
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> props =&gt; (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">StaticQuery</span>
    <span class="hljs-attr">query</span>=<span class="hljs-string">{graphql</span>`
      <span class="hljs-attr">query</span> <span class="hljs-attr">SiteTitleQuery</span> {
        <span class="hljs-attr">site</span> {
          <span class="hljs-attr">siteMetadata</span> {
            <span class="hljs-attr">title</span>
          }
        }
      }
    `}
    <span class="hljs-attr">render</span>=<span class="hljs-string">{data</span> =&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">Layout</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{data}</span> {<span class="hljs-attr">...props</span>} /&gt;</span>}
  /&gt;</span>
);
</code></pre>
<p>I found this more acceptable because you didn't have to have all the<br>code bunched into the <code>StaticQuery</code> component.</p>
<p><strong>That all make sense?</strong></p>
<p>Good, now forget about all of that! It's time to use the new<br><code>useStaticQuery</code> hotness in Gatsby. ?</p>
<h2 id="heading-versions">Versions:</h2>
<p><strong>This guide is being used with the following dependency versions.</strong></p>
<ul>
<li>gatsby: 2.1.31</li>
<li>react: 16.8.4</li>
<li>react-dom: 16.8.4</li>
</ul>
<p>You can also check out the <a target="_blank" href="https://codesandbox.io/s/1vnvko0zqj">example code</a>.</p>
<hr>
<p>The <a target="_blank" href="https://www.gatsbyjs.org/docs/use-static-query/">Gatsby documentation</a> covers the use of it and also how to make<br>your own custom react hook to use <code>useStaticQuery</code>, here's the one I<br>use in the video.</p>
<p><em>useSiteMetadata.js</em></p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { graphql, useStaticQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'gatsby'</span>;

<span class="hljs-keyword">const</span> useSiteMetadata = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { site } = useStaticQuery(
    graphql<span class="hljs-string">`
      query SITE_METADATA_QUERY {
        site {
          siteMetadata {
            title
            description
            author
          }
        }
      }
    `</span>
  );
  <span class="hljs-keyword">return</span> site.siteMetadata;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> useSiteMetadata;
</code></pre>
<p>This can now be implemented in the rest of the code as a function<br>call:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { title, description, author } = useSiteMetadata();
</code></pre>
<h2 id="heading-lets-implement-it">Let's implement it!</h2>
<p>In the <code>layout</code> component import the <code>useSiteMetadata</code> hook then we<br>can go about removing the <code>StaticQuery</code> component and destructuring<br><code>title</code> from the <code>useSiteMetadata</code> hook.</p>
<p>It should look something like this, I have taken the styling out for<br>brevity:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
<span class="hljs-keyword">import</span> useSiteMetadata <span class="hljs-keyword">from</span> <span class="hljs-string">'./useSiteMetadata'</span>;

<span class="hljs-keyword">import</span> Header <span class="hljs-keyword">from</span> <span class="hljs-string">'./header'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./layout.css'</span>;

<span class="hljs-keyword">const</span> Layout = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> { title } = useSiteMetadata();
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> <span class="hljs-attr">siteTitle</span>=<span class="hljs-string">{title}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
          © {new Date().getFullYear()}, Built with
          {` `}
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.gatsbyjs.org"</span>&gt;</span>Gatsby<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
};
Layout.propTypes = {
  <span class="hljs-attr">children</span>: PropTypes.node.isRequired,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Layout;
</code></pre>
<p>Here's the comparison:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/compareLayout.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On now to the <code>seo</code> component, same again, remove <code>StaticQuery</code> and<br>use <code>useSiteMetadata</code> in it's place.</p>
<p>Here's the comparison:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/compareSEO.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you want to check out the code the example is available here:<br><a target="_blank" href="https://codesandbox.io/s/1vnvko0zqj">example code</a></p>
<h2 id="heading-wrap-up">Wrap up!</h2>
<p>That's it! Wh have gone from using the awesome <code>StaticQuery</code> render<br>props pattern used in Gatsby over to the even more awesome<br><code>useStaticQuery</code> React hooks, hook.</p>
<p><strong>Thanks for reading</strong> ?</p>
<p>Please take a look at my other content if you enjoyed this.</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/spences10">Twitter</a> or <a target="_blank" href="https://github.com/spences10/ama">Ask Me Anything</a> on GitHub.</p>
<blockquote>
<p><strong>You can read other articles like this on <a target="_blank" href="https://thelocalhost.blog/">my blog</a>.</strong></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Normal Forms aren’t just for databases ]]>
                </title>
                <description>
                    <![CDATA[ By Jeff M Lowery You can apply similar rules to data object types, too. You probably learned the term Normal Form in the context of defining schemas for relational databases. Database normalization strives to reduce data redundancy in table rows and ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/normal-forms-arent-just-for-databases-2443741bd627/</link>
                <guid isPermaLink="false">66d45f80264384a65d5a9576</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metadata ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 08 Jul 2018 22:48:15 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*19XklLfx0ufFE97NSzwBng.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jeff M Lowery</p>
<h4 id="heading-you-can-apply-similar-rules-to-data-object-types-too"><em>You can apply similar rules to data object types, too.</em></h4>
<p>You probably learned the term <a target="_blank" href="https://en.wikipedia.org/wiki/Database_normalization#Normal_forms">Normal Form</a> in the context of defining schemas for relational databases. Database normalization strives to reduce data redundancy in table rows and columns. Consequently, data anomalies are less likely to occur.</p>
<h4 id="heading-whats-a-data-anomaly">What’s a data anomaly?</h4>
<p>Suppose we had this situation:</p>
<blockquote>
<p>Table A contains values for properties X, Y, Z for a row identified by the id of <strong>x</strong>; these are <strong><em>assertions</em></strong> <em>about x.</em> Let’s say Y in row <strong>x</strong> is asserted to be the value 3.  </p>
<p>Table B also contains the same assertions about why Y for <strong>x</strong>  </p>
<p>Table A is told later, “Facts have changed. Y is now 4”  </p>
<p>Table B is later queried, and says Y is still 3.  </p>
<p>Now A and B assert two different facts about Y, depending on which table you query.</p>
</blockquote>
<p>That’s a data anomaly: two different assertions about a fact. And facts do matter in computer systems.</p>
<h3 id="heading-the-what-and-whyfors-of-normal-forms">The what and whyfors of Normal Forms</h3>
<p>I’ll use the term <strong>type</strong> to denote the meta data of an object. This could be implemented by a <a target="_blank" href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html">class</a> definition, <a target="_blank" href="https://www.culttt.com/2015/07/08/working-with-mixins-in-ruby/">mixin</a>, <a target="_blank" href="http://php.net/manual/en/language.oop5.traits.php">trait</a>, <a target="_blank" href="https://medium.com/javascript-scene/introducing-the-stamp-specification-77f8911c2fee">stamp</a>, or whatever mechanism your preference and language of choice supports. I’ll also be focusing on <strong>data objects</strong><em>,</em> such as <a target="_blank" href="https://spring.io/understanding/POJO">POJOs</a>, <a target="_blank" href="https://benatkin.com/2012/11/10/podo-generalization-of-pojo/">PODOs</a>, JSON and similar simple objects.</p>
<p>Stated informally, the first three normal forms <a target="_blank" href="http://www.andrewrollins.com/2009/08/11/database-normalization-first-second-and-third-normal-forms/">are described as follows</a>:</p>
<blockquote>
<p>First Normal Form (1NF): No repeating elements or groups of elements  </p>
<p>Second Normal Form (2NF): All Non-key Attributes are Dependent on All of Key  </p>
<p>Third Normal Form (3NF): No dependencies on non-key attributes</p>
</blockquote>
<p>That’s pretty dry reading. But applying these principles to object type definitions is actually pretty intuitive. Once you’ve internalized these rules, you won’t even think about them consciously again.</p>
<h3 id="heading-objects-are-relational-too">Objects are relational, too</h3>
<p>Relational databases support <strong>associations</strong> by way of Primary and Foreign Key constraints. Hierarchies are implicit, if they exist at all. Associations are looser than hierarchies and taxonomies, but also harder to think about.</p>
<p>In a hierarchy, you have parent-child relationships. There is often a hierarchy of data types as well (class-subclass) which is also modeled. Relationships in a object containment hierarchy are more constrained, generally one-way (parent to child), but also easier to grasp than a more general (and flexible) association.</p>
<h4 id="heading-1nf-no-repeating-elements-or-groups-of-elements">1NF: No repeating elements or groups of elements</h4>
<p>Say we have the following contact information:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/K6MgfQspOPhM3PLOSTXy5R07r-kZHXmENGgZ" alt="Image" width="118" height="241" loading="lazy"></p>
<p>Where are the repeating elements?</p>
<ol>
<li>Name attributes: this could be considered a one-to-many relationship, where the number of names is indeterminate (such as British royalty). In practice, though, first, last, and possibly middle name are sufficient for most application domains, so there’s no real need to normalize these fields.</li>
<li>phones: The repetition of phone attributes does look like a potential problem: is two phones enough? And what if further information is later associated with the phone number, like time available?</li>
<li>address lines: again, are two enough? In some countries, street addresses can be four lines long, but that’s the limit. Since they are simple strings, it’s no tragedy if one or two more address lines are added later.</li>
</ol>
<p>Here’s a possible model, with Contact and Phone types:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9U5kybRDlVxzkYsQAakm-4UKr6Ag8jLedftT" alt="Image" width="268" height="202" loading="lazy"></p>
<h4 id="heading-2nf-all-non-key-attributes-are-dependent-on-all-of-key">2NF: All Non-key Attributes are Dependent on All of Key</h4>
<p>What does this mean in plain English? In a database, it means that all columns in a row should be directly dependent on any <a target="_blank" href="https://en.wikipedia.org/wiki/Second_normal_form">candidate keys</a> of that row.</p>
<p>So let’s take a look at Contact again:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XUzKdMHD4qLCfsrcFuVnAjnbt4jW4P52iNnL" alt="Image" width="120" height="205" loading="lazy"></p>
<p>Here the key is a generated id value, sometimes referred to as a surrogate key. Are the address attributes dependent on Contact ID? Well…</p>
<p><strong>It all depends on the domain.</strong></p>
<p>The six address properties are surely not attributes of the Contact, but are rather means of identifying a physical location. It is possible a contact could have many addresses, and perhaps an address has many contacts.</p>
<p>Should this be modeled as a many-to-many relationship, with some ContactAddress object type that has a Contact ID and an Address ID? It is going to depend on what is important to your application domain. Some application may treat Contacts as strong entities, independent of Address, but Addresses as weak entities, dependent on a Contact for existence. In that case, one contact can have many addresses, and each address refers to a contact, like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/fR5nqYyCmC8BomUNDq8wl514ZiFl41UOWe-K" alt="Image" width="119" height="167" loading="lazy"></p>
<p>There is a potential data anomaly: if you change the address for one contact, you don’t change that same address for all contacts. If Contact is your primary source of reference, then that may be the desired behavior: your contact moves (to another organization, say) and the remaining Contacts stay in place.</p>
<h4 id="heading-3nf-no-dependencies-on-non-key-attributes">3NF: No dependencies on non-key attributes</h4>
<p>Looking at Address again, you might spot the two dependent fields, <strong>region</strong> and <strong>country.</strong> A country may or may not have regions, but a region does have a country: you don’t want to mix them up.</p>
<p>One way of ensuring that the region belongs to the correct country is to create an identifier for each (country, region) pair, then have the address refer to the identifier rather than to region and country independently:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/iILOA2dV6A3xU--R6yv4Raa80jsHU0KRh55L" alt="Image" width="264" height="193" loading="lazy"></p>
<h4 id="heading-a-word-about-generated-identifiers">A word about generated identifiers</h4>
<p>In my opinion, generated identifiers are an implementation detail, and are really only needed by client code when modifying or deleting a back-end record (such as a row in a database), but never as part of a read-only query. They should also never be seen by the user of the system, because they are meaningless.</p>
<h3 id="heading-table-per-type-table-per-type-hierarchy">Table per Type, Table per Type Hierarchy</h3>
<p>The neat thing about normalized object types is that they map easily to relational database tables. For a relational database implementation, tables mirror the object types (<a target="_blank" href="https://blog.devart.com/table-per-type-vs-table-per-hierarchy-inheritance.html">Table per Type</a>) or at least contain information for multiple types derived from a base type (<a target="_blank" href="https://www.codeproject.com/Articles/545395/A-Beginners-Tutorial-on-Understanding-Table-Per-Ty">Table per Type Hierarchy</a>). This may sound like I’m advocating <a target="_blank" href="https://en.wikipedia.org/wiki/Object-relational_mapping">Object-Relational Mapping</a>, but no… I am merely saying that it is beneficial to have your <a target="_blank" href="https://www.1keydata.com/datawarehousing/logical-data-model.html">Logical Model</a> share the same characteristics of the <a target="_blank" href="https://www.1keydata.com/datawarehousing/physical-data-model.html">Physical Model</a> at a <strong>conceptual</strong> level. Implementation is another subject entirely.</p>
<h3 id="heading-references"><strong>References</strong></h3>
<p>There are ample resources about normalization of relation database schemas:</p>
<p><a target="_blank" href="http://www.andrewrollins.com/2009/08/11/database-normalization-first-second-and-third-normal-forms/"><strong>Database Normalization: First, Second, and Third Normal Forms - Andrew Rollins</strong></a><br><a target="_blank" href="http://www.andrewrollins.com/2009/08/11/database-normalization-first-second-and-third-normal-forms/"><em>I read a great explanation of first, second, and third normal form a few weeks ago. For those that know what database…</em></a><br><a target="_blank" href="http://www.andrewrollins.com/2009/08/11/database-normalization-first-second-and-third-normal-forms/">www.andrewrollins.com</a></p>
<p><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-10-database-second-normal-form-explained-in-simple-english/"><strong>Database Second Normal Form Explained in Simple English</strong></a><br><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-10-database-second-normal-form-explained-in-simple-english/"><em>The second post focused on the first normal form , its definition, and examples to hammer it home. Now it is time to…</em></a><br><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-10-database-second-normal-form-explained-in-simple-english/">www.essentialsql.com</a></p>
<p><a target="_blank" href="https://www.techopedia.com/definition/21980/second-normal-form-2nf"><strong>What is Second Normal Form (2NF)? - Definition from Techopedia</strong></a><br><a target="_blank" href="https://www.techopedia.com/definition/21980/second-normal-form-2nf"><em>Second Normal Form 2NF Definition - Second normal form (2NF) is the second step in normalizing a database. 2NF builds…</em></a><br><a target="_blank" href="https://www.techopedia.com/definition/21980/second-normal-form-2nf">www.techopedia.com</a></p>
<p><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-11-database-third-normal-form-explained-in-simple-english/"><strong>Database Third Normal Form Explained in Simple English</strong></a><br><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-11-database-third-normal-form-explained-in-simple-english/"><em>The third post focused on the second normal form, its definition, and examples to hammer it home. Once a table is in…</em></a><br><a target="_blank" href="https://www.essentialsql.com/get-ready-to-learn-sql-11-database-third-normal-form-explained-in-simple-english/">www.essentialsql.com</a></p>
<p>Also, when researching this post, I came across a somewhat different take on how to apply normalization rules to object types.</p>
<p><a target="_blank" href="http://www.agiledata.org/essays/classNormalization.html"><strong>Introduction to Class Normalization</strong></a><br><a target="_blank" href="http://www.agiledata.org/essays/classNormalization.html">www.agiledata.org</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
