<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mark Drake</title>
    <description>The latest articles on Forem by Mark Drake (@mdrakedo).</description>
    <link>https://forem.com/mdrakedo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F138605%2F82ed9b83-9700-4d14-9595-502d50cc69e0.jpg</url>
      <title>Forem: Mark Drake</title>
      <link>https://forem.com/mdrakedo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mdrakedo"/>
    <language>en</language>
    <item>
      <title>How To Manage a Redis Database: A Free eBook</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Fri, 17 Jul 2020 20:37:48 +0000</pubDate>
      <link>https://forem.com/digitalocean/how-to-manage-a-redis-database-a-free-ebook-5acm</link>
      <guid>https://forem.com/digitalocean/how-to-manage-a-redis-database-a-free-ebook-5acm</guid>
      <description>&lt;p&gt;We at &lt;a href="https://dev.to/digitalocean"&gt;DigitalOcean&lt;/a&gt; are excited to share with you a free eBook to support you as you explore Redis. &lt;em&gt;How To Manage a Redis Database&lt;/em&gt; is available for download in &lt;a href="https://do.co/redis-book-pdf"&gt;PDF&lt;/a&gt; or &lt;a href="https://do.co/redis-book-epub"&gt;EPUB&lt;/a&gt; format.&lt;/p&gt;

&lt;h2&gt;
  
  
  About this Book
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://redis.io/"&gt;Redis&lt;/a&gt; is an open-source, in-memory key-value data store known for its flexibility, performance, and broad language support. A NoSQL database, Redis doesn't use &lt;a href="https://en.wikipedia.org/wiki/SQL"&gt;&lt;em&gt;structured query language&lt;/em&gt;&lt;/a&gt; (otherwise known as &lt;em&gt;SQL&lt;/em&gt;) to store, manipulate, and retrieve data. Redis instead comes with its own set of commands for managing and accessing data.&lt;/p&gt;

&lt;p&gt;The chapters in this book cover a broad range of Redis commands, but they generally focus on connecting to a Redis database, managing a variety of data types, and troubleshooting and debugging problems, along with a few other more specific functions. You're encouraged to jump to whichever chapter is relevant to the task you're trying to complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation for this Book
&lt;/h2&gt;

&lt;p&gt;Every available Redis command is covered and thoroughly explained in the &lt;a href="https://redis.io/commands"&gt;official Redis command documentation&lt;/a&gt;, as well as in numerous other resources in print and online. However, many resources tend to silo each command off from one another with little tying them together.&lt;/p&gt;

&lt;p&gt;This book aims to provide an approachable introduction to Redis concepts by outlining many of the key-value store's commands so readers can learn their patterns and syntax, thus building up readers' understanding gradually. This book covers topics ranging from connecting to a Redis data store, to managing a variety of Redis data types, troubleshooting errors, and more. &lt;/p&gt;

&lt;h2&gt;
  
  
  Learning Goals and Outcomes
&lt;/h2&gt;

&lt;p&gt;The goal for this book is to serve as an introduction to Redis for those interested in getting started with it, or key-value stores in general. For more experienced users, this book can function as a collection of helpful cheat sheets and in-depth reference. Each chapter is self-contained and can be followed independently of the others. By reading through and following along with each chapter, you'll become acquainted with many of Redis's most widely used commands, which will help you as you begin to build applications that take advantage of its power and speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download the eBook
&lt;/h2&gt;

&lt;p&gt;You can download the eBook in either the EPUB or PDF format by following the links below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://do.co/redis-book-epub"&gt;&lt;em&gt;How To Manage a Redis Database&lt;/em&gt; eBook in EPUB format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://do.co/redis-book-pdf"&gt;&lt;em&gt;How To Manage a Redis Database&lt;/em&gt; eBook in PDF format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/books/details?id=rL3xDwAAQBAJ"&gt;&lt;em&gt;How To Manage a Redis Database&lt;/em&gt; eBook on Google Books&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AO5LGuc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/redis_eBook/Redis_Book_Cover.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AO5LGuc_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/redis_eBook/Redis_Book_Cover.jpg" alt='"How To Manage a Redis Database" eBook cover image' width="800" height="1231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To learn more about the book, check out our&lt;/strong&gt; &lt;a href="https://www.digitalocean.com/community/books/how-to-manage-a-redis-database-ebook"&gt;&lt;strong&gt;book landing page&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>redis</category>
      <category>database</category>
      <category>ebooks</category>
      <category>digitalocean</category>
    </item>
    <item>
      <title>The DigitalOcean Community Monthly: Kubernetes Curriculum, Community Tools, a Contest for Student Developers, and More!</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Wed, 04 Dec 2019 16:21:44 +0000</pubDate>
      <link>https://forem.com/digitalocean/the-digitalocean-community-monthly-kubernetes-curriculum-community-tools-a-contest-for-student-developers-and-more-4go7</link>
      <guid>https://forem.com/digitalocean/the-digitalocean-community-monthly-kubernetes-curriculum-community-tools-a-contest-for-student-developers-and-more-4go7</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;The DOCOM Monthly&lt;/strong&gt;, your monthly digest featuring some of the best content published in and around the &lt;a href="https://digitalocean.com/community"&gt;DigitalOcean Community&lt;/a&gt; over the last month. &lt;/p&gt;

&lt;p&gt;I'm Mark Drake, a Technical Writer on DigitalOcean's Developer Education team. This month's roundup includes a new Kubernetes curriculum, some exciting new Community tools, a special contest for student developers, and more!&lt;/p&gt;

&lt;p&gt;Here are this month's featured posts:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/curriculums/kubernetes-for-full-stack-developers"&gt;Kubernetes for Full-Stack Developers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tJE4n5qf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/k8s_header/kubernetes_tutorials.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tJE4n5qf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/k8s_header/kubernetes_tutorials.png" alt="Kubernetes header image" width="750" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DigitalOcean Community team launched its first curriculum targeted towards developers. This curriculum contains a selection of DigitalOcean technical tutorials and conceptual articles, curated to help developers learn what Kubernetes is and how to use it. &lt;a href="https://www.digitalocean.com/community/curriculums/kubernetes-for-full-stack-developers"&gt;Check out the curriculum&lt;/a&gt; or read our &lt;a href="https://blog.digitalocean.com/closing-the-kubernetes-skills-gap-with-developer-first-learning/"&gt;announcement blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/imperative-vs-declarative-kubernetes-management-a-digitalocean-comic"&gt;Imperative vs. Declarative Kubernetes Management: A DigitalOcean Comic&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Speaking of Kubernetes, we're excited to share this comic by &lt;a href="https://www.digitalocean.com/community/users/daisyt"&gt;Daisy Tsang&lt;/a&gt; which visualizes two different strategies for deploying infrastructure with Kubernetes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HLWOb_oH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://assets.digitalocean.com/articles/comics/imperative-declarative-k8s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HLWOb_oH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://assets.digitalocean.com/articles/comics/imperative-declarative-k8s.jpg" alt='"Imperative vs. Declarative Kubernetes Management" comic' width="800" height="1130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-build-an-inspirational-quote-application-using-adonisjs-and-mysql"&gt;How To Build an Inspirational Quote Application Using AdonisJs and MySQL&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In this tutorial, &lt;a href="https://twitter.com/yemiwebby"&gt;Oluyemi Olususi&lt;/a&gt; outlines how to build applications with &lt;a href="https://adonisjs.com/"&gt;AdonisJS&lt;/a&gt;, a Node.js web framework written in JavaScript. Having written this guide for the &lt;a href="https://do.co/w4do-cta"&gt;Write for DOnations&lt;/a&gt; program, Oluyemi selected the &lt;a href="https://www.brightfunds.org/funds/tech-education"&gt;Tech Education Fund&lt;/a&gt; to receive a donation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-build-and-install-go-programs"&gt;How To Build and Install Go Programs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yrOyaL9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://assets.digitalocean.com/articles/k8s_header/go_header.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yrOyaL9l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://assets.digitalocean.com/articles/k8s_header/go_header.png" alt="Go header image" width="750" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of our &lt;a href="https://www.digitalocean.com/community/tutorial_series/how-to-code-in-go"&gt;How To Code in Go&lt;/a&gt; series, this tutorial from &lt;a href="https://www.digitalocean.com/community/users/gopherguides"&gt;Gopher Guides&lt;/a&gt; outlines how to turn Go source code into a binary executable (in other words, &lt;em&gt;build&lt;/em&gt; it) and then put it into an executable file path so you can run it from anywhere on your system (or, &lt;em&gt;install&lt;/em&gt; it). &lt;/p&gt;

&lt;h2&gt;
  
  
  New DigitalOcean Community Developer Tools
&lt;/h2&gt;

&lt;p&gt;We have a large collection of tools which help developers build things on DigitalOcean. With over 200 such tools built and maintained by members of the Community, we launched the following open-source tools built internally by DigitalOcean's Community team in November:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://do.co/dns-lookup"&gt;&lt;strong&gt;DNS Lookup&lt;/strong&gt;&lt;/a&gt;: Returns the &lt;a href="https://en.wikipedia.org/wiki/Domain_Name_System"&gt;DNS&lt;/a&gt; records of a given domain &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://do.co/spf-explainer"&gt;&lt;strong&gt;SPF Explainer&lt;/strong&gt;&lt;/a&gt;: Explains a given domain's &lt;a href="https://en.wikipedia.org/wiki/Sender_Policy_Framework"&gt;SPF&lt;/a&gt; records&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://do.co/nginxconfig"&gt;&lt;strong&gt;NGINX Config&lt;/strong&gt;&lt;/a&gt;: Helps generate configuration files for performant, secure, and stable NGINX servers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tools/glob"&gt;&lt;strong&gt;Glob Tool&lt;/strong&gt;&lt;/a&gt;: Tests &lt;a href="https://en.wikipedia.org/wiki/Glob_(programming)"&gt;globs&lt;/a&gt; against sets of test strings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check out &lt;a href="https://www.digitalocean.com/community/tools"&gt;all of our Community tools&lt;/a&gt; or even &lt;a href="https://www.digitalocean.com/community/tools/new"&gt;submit your own&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  DigitalOcean on the Web
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://blog.powertofly.com/interning-at-digitalocean-2641228224.html"&gt;an interview with PowerToFly&lt;/a&gt;, Varsha Varadarajan discusses her experience as both a summer intern and then as a part-time engineering intern at DigitalOcean. She recounts what initially drew her to working at DigitalOcean, how she balances her job with her graduate studies, and what makes DigitalOcean a great place for young engineers to work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dOUkKukP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.rebelmouse.io/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbWFnZSI6Imh0dHBzOi8vYXNzZXRzLnJibC5tcy8yMjA2MDkwNi9vcmlnaW4ucG5nIiwiZXhwaXJlc19hdCI6MTU3ODc4NDc5M30.QR2t_ZtoM0uJX__igTKRV-Iovwp8n4s58ErZqMpqQdM/img.png%3Fwidth%3D1200%26height%3D628" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dOUkKukP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.rebelmouse.io/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbWFnZSI6Imh0dHBzOi8vYXNzZXRzLnJibC5tcy8yMjA2MDkwNi9vcmlnaW4ucG5nIiwiZXhwaXJlc19hdCI6MTU3ODc4NDc5M30.QR2t_ZtoM0uJX__igTKRV-Iovwp8n4s58ErZqMpqQdM/img.png%3Fwidth%3D1200%26height%3D628" alt="Varsha Varadarajan interview splash" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Daniel Zaltsman, DigitalOcean's Senior Developer Relations manager, wrote &lt;a href="https://blog.digitalocean.com/recapping-hacktoberfest-6/"&gt;a retrospective of the sixth annual Hacktoberfest event&lt;/a&gt;. Here are some of the highlights:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1194272582507339777-599" src="https://platform.twitter.com/embed/Tweet.html?id=1194272582507339777"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1194272582507339777-599');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1194272582507339777&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;In this tutorial, DEV user &lt;a href="https://dev.to/zavrelj"&gt;Jan Zavrel&lt;/a&gt; explains how to set up a PHP development environment with Docker and Docker Compose, and then deploy an application using GitHub and Digitalocean:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/zavrelj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sb3iYh_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--B_jP3cWZ--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/277072/289987bf-d79e-47b7-9b7f-ab762ad6e2b1.jpeg" alt="zavrelj"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/zavrelj/docker-and-docker-compose-for-php-development-with-github-and-digital-ocean-deployment-52k9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Docker and Docker Compose for PHP Development with GitHub and Digital Ocean Deployment&lt;/h2&gt;
      &lt;h3&gt;Jan Zavrel ・ Nov 25 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#docker&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#php&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#github&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#digitalocean&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;In a blog post, &lt;a href="https://nickjanetakis.com/"&gt;Nick Janetakis&lt;/a&gt; shares his experiences &lt;a href="https://nickjanetakis.com/blog/lessons-learned-from-building-a-podcast-platform-in-2-weekends"&gt;building a podcasting platform with Jekyll and DigitalOcean&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community IRL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6kxZQQLu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/TIDE_2019/do_tide_2019.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6kxZQQLu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.digitalocean.com/articles/TIDE_2019/do_tide_2019.JPG" alt="DigitalOcean Tide Mumbai 2019" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last month, DigitalOcean organized and hosted the seventh edition of our &lt;a href="https://go.digitalocean.com/tide-mumbai"&gt;TIDE Mumbai confernece&lt;/a&gt;. Over 250 people came to learn more about DigitalOcean, listen to talks and panel discussions, attend hands-on technical demonstrations, and network with others.&lt;/p&gt;

&lt;p&gt;The DigitalOcean team had a busy week at &lt;a href="https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/"&gt;Kubecon North America&lt;/a&gt;. There, &lt;a href="https://www.eventbrite.com/e/san-diego-mixer-meet-the-digitalocean-kubernetes-team-kick-off-kubecon-tickets-76347761209#"&gt;we met and chatted with developers&lt;/a&gt;, &lt;a href="https://twitter.com/eddiezane/status/1197613931398758400"&gt;gave a few talks&lt;/a&gt;, and announced DigitalOcean's new &lt;a href="https://www.digitalocean.com/products/container-registry/"&gt;Container Registry&lt;/a&gt; which aims to make it easier for developers to manage container images. Read about this new service, as well as updates to some other Kubernetes-related DigitalOcean products, in our &lt;a href="https://blog.digitalocean.com/making-kubernetes-easier-with-digitalocean-container-registry-and-1-click-apps/"&gt;announcement blog post&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Finally, DigitalOcean's Cambridge office hosted an event coordinated by the Boston chapter of &lt;a href="http://wimlds.org/"&gt;Women in Machine Learning and Data Science&lt;/a&gt;. The event featured a talk by &lt;a href="https://twitter.com/francescadomin8"&gt;Francesca Dominici&lt;/a&gt;, co-director of the Harvard Data Science Initiative and professor of biostatistics, titled "How Data Science Can Tackle Climate Change." You can watch the full talk here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/6_y-1osvNLE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;&lt;em&gt;That's all for this month. Thanks for reading, and happy coding!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>digitalocean</category>
      <category>news</category>
      <category>docom</category>
      <category>docommonthly</category>
    </item>
    <item>
      <title>How To Install WordPress with a Managed Database on Ubuntu 18.04</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Tue, 20 Aug 2019 15:02:09 +0000</pubDate>
      <link>https://forem.com/digitalocean/how-to-install-wordpress-with-a-managed-database-on-ubuntu-18-04-3knc</link>
      <guid>https://forem.com/digitalocean/how-to-install-wordpress-with-a-managed-database-on-ubuntu-18-04-3knc</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://wordpress.org/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt; is the most popular CMS (content management system) on the internet. It's a great choice for getting a website up and running quickly, and after the initial setup, almost all administration can be done through the web frontend.&lt;/p&gt;

&lt;p&gt;WordPress is designed to pull content – including posts, comments, user profiles, and other data – from a database backend. As a website grows and must satisfy more and more traffic, it can eventually outgrow its initial database. To resolve this, one can scale up their database by migrating their data to a machine with more RAM or CPU, but this is a tedious process that runs the risk of data loss or corruption. This is why some WordPress developers choose to build their websites on &lt;a href="https://www.digitalocean.com/community/tutorials/understanding-managed-databases" rel="noopener noreferrer"&gt;managed databases&lt;/a&gt;, which allow users to scale their database automatically with a far lower risk of data loss.&lt;/p&gt;

&lt;p&gt;In this guide, we'll focus on setting up a WordPress instance with a managed &lt;a href="https://www.mysql.com/" rel="noopener noreferrer"&gt;MySQL&lt;/a&gt; database and an Ubuntu 18.04 server. This will require you to install &lt;a href="https://www.php.net/" rel="noopener noreferrer"&gt;PHP&lt;/a&gt; and &lt;a href="https://httpd.apache.org/" rel="noopener noreferrer"&gt;Apache&lt;/a&gt; to serve the content over the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In order to complete this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access to an Ubuntu 18.04 server&lt;/strong&gt;: This server should have a non-&lt;strong&gt;root&lt;/strong&gt; sudo-enabled user and a firewall configured. You can set this up by following our &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="noopener noreferrer"&gt;Ubuntu 18.04 initial server setup guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A managed MySQL database&lt;/strong&gt;: To provision a Managed Database from DigitalOcean, see our &lt;a href="https://www.digitalocean.com/docs/databases/mysql/quickstart/#create-mysql-database-clusters" rel="noopener noreferrer"&gt;Managed Databases product documentation&lt;/a&gt;. Note that this guide will refer to DigitalOcean Managed Databases in examples, but the instructions provided here should generally work for managed databases from other cloud providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A LAMP stack installed on your server&lt;/strong&gt;: In addition to a database, WordPress requires a web server and PHP to function correctly. Setting up a complete LAMP stack (Linux, Apache, MySQL, and PHP) fulfills all of these requirements. Follow &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-ubuntu-18-04" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to install and configure this software. As you follow this guide, make sure that you &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-ubuntu-18-04#step-4-%E2%80%94-setting-up-virtual-hosts-(recommended)" rel="noopener noreferrer"&gt;set up a virtual host&lt;/a&gt; to point to a domain name that you own. Additionally, be sure to &lt;strong&gt;skip Step 2&lt;/strong&gt;, as installing &lt;code&gt;mysql-server&lt;/code&gt; on your machine will make your managed database instance redundant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS/SSL security implemented for your site&lt;/strong&gt;: If you have a domain name, the easiest way to secure your site is with Let's Encrypt, which provides free, trusted certificates. Follow our &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-18-04" rel="noopener noreferrer"&gt;Let's Encrypt guide for Apache&lt;/a&gt; to set this up. Note that this will also require you to obtain a domain name and set up DNS records on your server. Follow &lt;a href="https://www.digitalocean.com/docs/networking/dns/" rel="noopener noreferrer"&gt;this introduction to DigitalOcean DNS&lt;/a&gt; for details on how to configure this. Altneratively, if you don't have a domain name, you &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-in-ubuntu-18-04" rel="noopener noreferrer"&gt;use a self-signed certificate&lt;/a&gt; for your site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you are finished with the setup steps, log into your server as your non-&lt;strong&gt;root&lt;/strong&gt; user and continue below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 – Adding the MySQL Software Repository and Installing &lt;code&gt;mysql-client&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In order to configure your managed MySQL instance, you will need to install a client that will allow you to access the database from your server. This step will walk you through the process of installing the &lt;code&gt;mysql-client&lt;/code&gt; package. &lt;/p&gt;

&lt;p&gt;In many cases, you can just install &lt;code&gt;mysql-client&lt;/code&gt; with the &lt;code&gt;apt&lt;/code&gt; command, but if you're using the default Ubuntu repositories this will install version 5.7 of the program. In order to access a DigitalOcean Managed MySQL database, you will need to install version 8.0 or above. To do so, you must first add the MySQL software repository before installing the package.&lt;/p&gt;

&lt;p&gt;Begin by navigating to &lt;a href="https://dev.mysql.com/downloads/repo/apt/" rel="noopener noreferrer"&gt;the &lt;strong&gt;MySQL APT Repository&lt;/strong&gt; page&lt;/a&gt; in your web browser. Find the &lt;strong&gt;Download&lt;/strong&gt; button in the lower-right corner and click through to the next page. This page will prompt you to log in or sign up for an Oracle web account. You can skip that and instead look for the link that says &lt;strong&gt;No thanks, just start my download&lt;/strong&gt;. Right-click the link and select &lt;strong&gt;Copy Link Address&lt;/strong&gt; (this option may be worded differently, depending on your browser).&lt;/p&gt;

&lt;p&gt;Now you're ready to download the file. On your server, move to a directory you can write to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the file using &lt;code&gt;curl&lt;/code&gt;, remembering to paste the address you just copied in place of the highlighted portion of the following command. You also need to pass two command line flags to &lt;code&gt;curl&lt;/code&gt;. &lt;code&gt;-O&lt;/code&gt; instructs &lt;code&gt;curl&lt;/code&gt; to output to a file instead of standard output. The &lt;code&gt;L&lt;/code&gt; flag makes &lt;code&gt;curl&lt;/code&gt; follow HTTP redirects, which is necessary in this case because the address you copied actually redirects to another location before the file downloads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -OL https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file should now be downloaded in your current directory. List the files to make sure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the filename listed in the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql-apt-config_0.8.13-1_all.deb
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can add the MySQL APT repository to your system's repository list. The &lt;code&gt;dpkg&lt;/code&gt; command is used to install, remove, and inspect &lt;code&gt;.deb&lt;/code&gt; software packages. The following command includes the &lt;code&gt;-i&lt;/code&gt; flag, indicating that you'd like to install from the specified file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dpkg -i mysql-apt-config*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the installation, you'll be presented with a configuration screen where you can specify which version of MySQL you'd prefer, along with an option to install repositories for other MySQL-related tools. The defaults will add the repository information for the latest stable version of MySQL and nothing else. This is what we want, so use the down arrow to navigate to the &lt;code&gt;Ok&lt;/code&gt; menu option and hit &lt;code&gt;ENTER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fpma_managed_db%2Fdpkg_mysql_apt_config_alt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fpma_managed_db%2Fdpkg_mysql_apt_config_alt2.png" alt="Selecting mysql-apt-config configuration options"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Following that, the package will finish adding the repository. Refresh your &lt;code&gt;apt&lt;/code&gt; package cache to make the new software packages available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you can clean up your system a bit and delete the file you downloaded, as you won't need it in the future:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm mysql-apt-config*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you ever need to update the configuration of these repositories, just run the following command to select your new options:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dpkg-reconfigure mysql-apt-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;After selecting your new options, run the following command to refresh your package cache:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you've added the MySQL repositories, you're ready to install the actual MySQL client software. Do so with the following &lt;code&gt;apt&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install mysql-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that command finishes, check the software version number to ensure that you have the latest release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql  Ver 8.0.17-cluster for Linux on x86_64 (MySQL Community Server - GPL)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're now able to connect to your managed database and begin preparing it to function with WordPress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 – Creating a MySQL Database and User for WordPress
&lt;/h2&gt;

&lt;p&gt;WordPress uses MySQL to manage and store site and user information. Assuming you have completed all the prerequisite tutorials, you will have already provisioned a managed MySQL instance. Here, we'll take the preparatory step of creating a database and a user for WordPress to use.&lt;/p&gt;

&lt;p&gt;Most managed database providers provide a &lt;a href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier" rel="noopener noreferrer"&gt;&lt;em&gt;uniform resource identifier&lt;/em&gt;&lt;/a&gt; (URI) used for connecting to the database instance. If you're using a DigitalOcean Managed Database, you can find the relevant connection information in your Cloud Control Panel.&lt;/p&gt;

&lt;p&gt;First, click &lt;strong&gt;Databases&lt;/strong&gt; in the left-hand sidebar menu and select the MySQL database you want to use for your WordPress installation. Scroll down to the &lt;strong&gt;Connection Details&lt;/strong&gt; section and copy the link in the &lt;strong&gt;host&lt;/strong&gt; field. Then paste this link into the following command, replacing &lt;code&gt;host_uri&lt;/code&gt; with the information you just copied. Likewise, copy the port number in the &lt;strong&gt;port&lt;/strong&gt; field – which will be &lt;code&gt;25060&lt;/code&gt; on a DigitalOcean Managed Database – and replace &lt;code&gt;port&lt;/code&gt; with that number. Additionally, if this is your first time connecting to your managed database and you've not created your own administrative MySQL user, copy the value in the &lt;strong&gt;username&lt;/strong&gt; field and paste it into the command, replacing &lt;code&gt;user&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql -u user -p -h host_uri -P port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command includes the &lt;code&gt;-p&lt;/code&gt; flag, which will prompt you for the password of the MySQL user you specified. For a DigitalOcean Managed Database's default &lt;strong&gt;doadmin&lt;/strong&gt; user, you can find this by clicking the &lt;strong&gt;show&lt;/strong&gt; link in the &lt;strong&gt;Connection Details&lt;/strong&gt; section to reveal the password. Copy and paste it into your terminal when prompted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you are not using a DigitalOcean Managed Database, your connection options may differ. If that's the case, you should consult your provider's documentation for instructions on connecting third party applications to your database.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From the MySQL prompt, create a new database that WordPress will control. You can call this whatever you would like, but we will use the name &lt;strong&gt;wordpress&lt;/strong&gt; in this guide to keep it simple. Create the database for WordPress by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; Every MySQL statement must end in a semi-colon (&lt;code&gt;;&lt;/code&gt;). Check to make sure this is present if you are running into any issues.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, create a new MySQL user account that you will use exclusively to operate on the new database. Creating single-purpose databases and accounts is a good idea from a management and security standpoint. We will use the name &lt;strong&gt;wordpressuser&lt;/strong&gt; in this guide, but feel free to change this if you'd like.&lt;/p&gt;

&lt;p&gt;Run the following command, but replace &lt;code&gt;your_server_ip&lt;/code&gt; with your Ubuntu server's IP address. Be aware, though, that this will limit &lt;strong&gt;wordpressuser&lt;/strong&gt; to only be able to connect from your LAMP server; if you plan to manage WordPress from your local computer, you should enter that machine's IP address instead. Additionally, choose a strong password for your database user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER 'wordpressuser'@your_server_ip IDENTIFIED WITH mysql_native_password BY 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you do not know what your server's public IP address is, there are a number of ways you can find it. Usually, this is the address you use to connect to your server through SSH.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One method is to use the &lt;code&gt;curl&lt;/code&gt; utility to contact an outside party to tell you how &lt;em&gt;it&lt;/em&gt; sees your server. For example, you can use &lt;code&gt;curl&lt;/code&gt; to contact an IP-checking tool like ICanHazIP:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://icanhazip.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This command will return your server's public IP address in your output.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then grant this user access to the database you just created. Do so by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRANT ALL ON wordpress.* TO 'wordpressuser'@your_server_ip;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have a database and user account, each made specifically for WordPress. Go ahead and exit out of MySQL by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That takes care of configuring your managed MySQL database to function with WordPress. In the next step, you will install a few PHP extensions in order to get more functionality out of the CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 – Installing Additional PHP Extensions
&lt;/h2&gt;

&lt;p&gt;Assuming you followed the &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-ubuntu-18-04" rel="noopener noreferrer"&gt;prerequisite LAMP stack tutorial&lt;/a&gt;, you will have installed a few extensions intended to get PHP to properly communicate with MySQL. WordPress and many of its plugins leverage additional PHP extensions to add additional functionalities.&lt;/p&gt;

&lt;p&gt;To download and install some of the more popular PHP extensions for use with WordPress, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each WordPress plugin has its own set of requirements. Some may require you to install additional PHP packages. Check your plugin documentation to see which extensions it requires. If they are available, they can be installed with &lt;code&gt;apt&lt;/code&gt; as demonstrated above.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You will restart Apache to load these new extensions in the next section. If you're returning here to install additional plugins, though, you can restart Apache now by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, continue on to Step 4. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 – Adjusting Apache's Configuration to Allow for .htaccess Overrides and Rewrites
&lt;/h2&gt;

&lt;p&gt;In order for Apache to be able to properly serve your WordPress installation, you must make a few minor adjustments to your Apache configuration. &lt;/p&gt;

&lt;p&gt;If you followed the prerequisite tutorials, you should already have a configuration file for your site in the &lt;code&gt;/etc/apache2/sites-available/&lt;/code&gt; directory. We'll use &lt;code&gt;/etc/apache2/sites-available/your_domain.conf&lt;/code&gt; as an example here, &lt;strong&gt;but you should substitute the path to your configuration file where appropriate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, we will use &lt;code&gt;/var/www/your_domain&lt;/code&gt; as the root directory in this example WordPress install. &lt;strong&gt;You should use the web root specified in your own configuration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; It's possible you are using the &lt;code&gt;000-default.conf&lt;/code&gt; default configuration (with &lt;code&gt;/var/www/html&lt;/code&gt; as your web root). This is fine to use if you're only going to host one website on this server. If not, it's best to split the necessary configuration into logical chunks, one file per site.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Currently, the use of &lt;code&gt;.htaccess&lt;/code&gt; files is disabled. WordPress and many WordPress plugins use these files extensively for in-directory tweaks to the web server's behavior.&lt;/p&gt;

&lt;p&gt;Open the Apache configuration file for your website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/apache2/sites-available/your_domain.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To allow &lt;code&gt;.htaccess&lt;/code&gt; files, you need to set the &lt;code&gt;AllowOverride&lt;/code&gt; directive within a &lt;code&gt;Directory&lt;/code&gt; block pointing to your document root. Add the following block of text inside the &lt;code&gt;VirtualHost&lt;/code&gt; block in your configuration file, being sure to use the correct web root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Directory /var/www/your_domain&amp;gt;
    AllowOverride All
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you are finished, save and close the file.&lt;/p&gt;

&lt;p&gt;Next, enable &lt;code&gt;mod_rewrite&lt;/code&gt; so that you can employ the WordPress permalink feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo a2enmod rewrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before implementing the changes you've just made, check to make sure there aren't any syntax errors in your configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apache2ctl configtest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output might have a message that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wish to suppress the top line, just add a &lt;code&gt;ServerName&lt;/code&gt; directive to your main (global) Apache configuration file at &lt;code&gt;/etc/apache2/apache2.conf&lt;/code&gt;. The &lt;code&gt;ServerName&lt;/code&gt; can be your server's domain or IP address. However, this is just a message; it doesn't affect the functionality of your site and as long as the output contains &lt;code&gt;Syntax OK&lt;/code&gt;, you're all set to continue.&lt;/p&gt;

&lt;p&gt;Restart Apache to implement the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, you're ready to download and set up WordPress itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 – Downloading WordPress
&lt;/h2&gt;

&lt;p&gt;Now that your server software is configured, you can install and configure WordPress. For security reasons, it is always recommended to get the latest version of WordPress from their site.&lt;/p&gt;

&lt;p&gt;First, navigate to into a writable directory. &lt;code&gt;/tmp&lt;/code&gt; will work for the purposes of this step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then download the compressed release by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -O https://wordpress.org/latest.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Extract the compressed file to create the WordPress directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tar xzvf latest.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will move these files into your document root momentarily. Before doing so, add a dummy &lt;code&gt;.htaccess&lt;/code&gt; file so that this will be available for WordPress to use later.&lt;/p&gt;

&lt;p&gt;Create the file by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch /tmp/wordpress/.htaccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, copy over the sample configuration file to the filename that WordPress actually reads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an &lt;code&gt;upgrade&lt;/code&gt; directory, so that WordPress won't run into permissions issues when trying to do this on its own following an update to its software:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir /tmp/wordpress/wp-content/upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then copy the entire contents of the directory into your document root. The following command uses a period at the end of the source directory to indicate that everything within the directory should be copied, including hidden files (like the &lt;code&gt;.htaccess&lt;/code&gt; file you just created):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp -a /tmp/wordpress/. /var/www/your_domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That takes care of downloading WordPress onto your server. At this point, though, you still won't be able to access the WordPress setup interface in your browser. To fix that, you'll need to make a few changes to your server's WordPress configuration. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 – Configuring the WordPress Directory
&lt;/h2&gt;

&lt;p&gt;Before going through the web-based WordPress setup, you need to adjust some items in your WordPress directory. One important configuration change involves setting up reasonable file permissions and ownership.&lt;/p&gt;

&lt;p&gt;Start by giving ownership of all the files to the &lt;strong&gt;www-data&lt;/strong&gt; user and group. This is the user that the Apache web server runs as on Debian and Ubuntu systems, and Apache will need to be able to read and write WordPress files in order to serve the website and perform automatic updates.&lt;/p&gt;

&lt;p&gt;Update the ownership of your web root directory with &lt;code&gt;chown&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown -R www-data:www-data /var/www/your_domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next run the following two &lt;code&gt;find&lt;/code&gt; commands to set the correct permissions on the WordPress directories and files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo find /var/www/your_domain/ -type d -exec chmod 750 {} \;
sudo find /var/www/your_domain/ -type f -exec chmod 640 {} \;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These should be a reasonable permissions set to start with. Be aware, though, that some plugins and procedures might require additional updates.&lt;/p&gt;

&lt;p&gt;Now, you need to make some changes to the main WordPress configuration file.&lt;/p&gt;

&lt;p&gt;When you open the file, the first order of business will be to replace some secret keys to provide security for your installation. WordPress provides a secure generator for these values so that you do not have to try to come up with good values on your own. These are only used internally, so it won't hurt usability to have complex, secure values here.&lt;/p&gt;

&lt;p&gt;To grab secure values from the WordPress secret key generator, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s https://api.wordpress.org/secret-key/1.1/salt/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get back unique values that look something like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Warning!&lt;/strong&gt; It is important that you request unique values each time. Do &lt;strong&gt;NOT&lt;/strong&gt; copy the values shown here!&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;define('AUTH_KEY',         '1jl/vqfs&amp;lt;XhdXoAPz9 DO NOT COPY THESE VALUES c_j{iwqD^&amp;lt;+c9.k&amp;lt;J@4H');
define('SECURE_AUTH_KEY',  'E2N-h2]Dcvp+aS/p7X DO NOT COPY THESE VALUES {Ka(f;rv?Pxf})CgLi-3');
define('LOGGED_IN_KEY',    'W(50,{W^,OPB%PB&amp;lt;JF DO NOT COPY THESE VALUES 2;y&amp;amp;,2m%3]R6DUth[;88');
define('NONCE_KEY',        'll,4UC)7ua+8&amp;lt;!4VM+ DO NOT COPY THESE VALUES #`DXF+[$atzM7 o^-C7g');
define('AUTH_SALT',        'koMrurzOA+|L_lG}kf DO NOT COPY THESE VALUES  07VC*Lj*lD&amp;amp;?3w!BT#-');
define('SECURE_AUTH_SALT', 'p32*p,]z%LZ+pAu:VY DO NOT COPY THESE VALUES C-?y+K0DK_+F|0h{!_xY');
define('LOGGED_IN_SALT',   'i^/G2W7!-1H2OQ+t$3 DO NOT COPY THESE VALUES t6**bRVFSD[Hi])-qS`|');
define('NONCE_SALT',       'Q6]U:K?j4L%Z]}h^q7 DO NOT COPY THESE VALUES 1% ^qUswWgn+6&amp;amp;xqHN&amp;amp;%');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are configuration lines that you can paste directly into your configuration file to set secure keys. Copy the output you received now.&lt;/p&gt;

&lt;p&gt;Then, open the WordPress configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /var/www/your_domain/wp-config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the section that contains the dummy values for those settings. It will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete those lines and paste in the values you copied from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .

define('AUTH_KEY',         'VALUES COPIED FROM THE COMMAND LINE');
define('SECURE_AUTH_KEY',  'VALUES COPIED FROM THE COMMAND LINE');
define('LOGGED_IN_KEY',    'VALUES COPIED FROM THE COMMAND LINE');
define('NONCE_KEY',        'VALUES COPIED FROM THE COMMAND LINE');
define('AUTH_SALT',        'VALUES COPIED FROM THE COMMAND LINE');
define('SECURE_AUTH_SALT', 'VALUES COPIED FROM THE COMMAND LINE');
define('LOGGED_IN_SALT',   'VALUES COPIED FROM THE COMMAND LINE');
define('NONCE_SALT',       'VALUES COPIED FROM THE COMMAND LINE');

. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next you need to modify some of the database connection settings at the beginning of the file. First, update the &lt;code&gt;'DB_NAME'&lt;/code&gt;, &lt;code&gt;'DB_USER'&lt;/code&gt;, and &lt;code&gt;'DB_PASSWORD'&lt;/code&gt; fields to point to the database name, database user, and the associated password that you configured within MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpressuser');

/** MySQL database password */
define('DB_PASSWORD', 'password');

. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will also need to replace &lt;code&gt;localhost&lt;/code&gt; in the &lt;code&gt;'DB_HOST'&lt;/code&gt; field with your managed database's host. Additionally, append a colon (&lt;code&gt;:&lt;/code&gt;) and your database's port number to the host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .

/** MySQL hostname */
define( 'DB_HOST', 'managed_database_host:managed_database_port' );

. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last change you need to make is to set the method that WordPress will use to write to the filesystem. Since you've already given the web server permission to write where it needs to, you can explicitly set the filesystem method to &lt;code&gt;direct&lt;/code&gt; port. Failure to set this with your current settings would result in WordPress prompting for FTP credentials when you perform certain actions.&lt;/p&gt;

&lt;p&gt;This setting can be added below the database connection settings, or anywhere else in the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .

define('FS_METHOD', 'direct');
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;After making those changes, you're all set to finish the process of installing WordPress in your web browser. However, there's one more step that we recommend you complete to add an extra layer of security to your configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7 – (Recommended) Configuring WordPress to Communicate with MySQL Over TLS/SSL
&lt;/h2&gt;

&lt;p&gt;At this point, your WordPress installation is communicating with your managed MySQL database. However, there's no guarantee that data transfers between the two machines are secure. In this step, we will configure WordPress to communicate with your MySQL instance over a TLS/SSL connection to ensure secure communications between the two machines.&lt;/p&gt;

&lt;p&gt;To do so, you'll need your managed database's CA certificate. For a DigitalOcean Managed Database, you can find this by once again navigating to the &lt;strong&gt;Databases&lt;/strong&gt; tab in your &lt;strong&gt;Control Panel&lt;/strong&gt;. Click on your database, and find the &lt;strong&gt;Connection Details&lt;/strong&gt; section. There will be a button there that reads &lt;strong&gt;Download the CA certificate&lt;/strong&gt;. Click this button to download the certificate to your local machine.&lt;/p&gt;

&lt;p&gt;Then transfer this file to your WordPress server. If your local machine is running Linux or macOS, you can use a tool like &lt;code&gt;scp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scp /path/to/file/ca-certificate.crt sammy@your_server_ip:/tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your local machine is running Windows, you can use an alternative tool like &lt;a href="https://winscp.net/eng/index.php" rel="noopener noreferrer"&gt;WinSCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once the CA certificate is on your server, move it to the &lt;code&gt;/user/local/share/ca-certificates/&lt;/code&gt; directory, Ubuntu's trusted certificate store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mv /tmp/ca-certificate.crt /usr/local/share/ca-certificates/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following this, run the &lt;code&gt;update-ca-certificates&lt;/code&gt; command. This program looks for certificates within &lt;code&gt;/usr/local/share/ca-certificates&lt;/code&gt;, adds any new ones to the &lt;code&gt;/etc/ssl/certs/&lt;/code&gt; directory, and generates a list of trusted SSL certificates based on its contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo update-ca-certificates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, reopen your &lt;code&gt;wp-config.php&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /var/www/your_domain/wp-config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Somewhere in the file, add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . .
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
. . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file.&lt;/p&gt;

&lt;p&gt;Following that, WordPress will securely communicate with your managed MySQL database. &lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8 – Completing the Installation Through the Web Interface
&lt;/h2&gt;

&lt;p&gt;Now that the server configuration is complete, you can complete the installation through the WordPress web interface.&lt;/p&gt;

&lt;p&gt;In your web browser, navigate to your server's domain name or public IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://server_domain_or_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming there aren't any errors in your WordPress or Apache configurations, you'll see the WordPress language selection splash page. Select the language you would like to use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Flanguage_selection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Flanguage_selection.png" alt="WordPress language selection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting your language, you will see the main setup page.&lt;/p&gt;

&lt;p&gt;Select a name for your WordPress site and choose a username (it is recommended not to choose something like "admin" for security purposes). A strong password is generated automatically. Save this password or enter an alternative strong password.&lt;/p&gt;

&lt;p&gt;Enter your email address and select whether you want to discourage search engines from indexing your site:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Fsetup_installation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Fsetup_installation.png" alt="WordPress setup installation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click ahead, you will be taken to a page that prompts you to log in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Flogin_prompt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Flogin_prompt.png" alt="WordPress login prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you log in, you will be taken to the WordPress administration dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Fadmin_screen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fwordpress_lamp_1604%2Fadmin_screen.png" alt="WordPress login prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, you can begin customizing your new WordPress site and start publishing content. If this is your first time using WordPress, we encourage you to explore the interface a bit to get acquainted with your new CMS.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Warning:&lt;/strong&gt; Depending on your managed database provider, you may need to adjust which &lt;em&gt;SQL modes&lt;/em&gt; the database is using. SQL modes define how MySQL validates data and the syntax it supports, and certain SQL modes can negatively impact WordPress's performance. For instance, the default SQL modes on DigitalOcean Managed MySQL Databases enable MySQL's &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-strict" rel="noopener noreferrer"&gt;&lt;em&gt;strict mode&lt;/em&gt;&lt;/a&gt; which can cause errors in a WordPress database.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are a number of SQL modes that can affect WordPress's performance, as well as a number of ways to disable strict mode, so you should review &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html" rel="noopener noreferrer"&gt;the official MySQL documentation on the subject&lt;/a&gt; to determine which settings are best suited to your needs. If you're using a DigitalOcean Managed Database, see our &lt;a href="https://www.digitalocean.com/docs/databases/mysql/how-to/set-sql-mode" rel="noopener noreferrer"&gt;Managed MySQL product documentation&lt;/a&gt; for details on how to change the default SQL mode settings.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By completing this guide, you will have WordPress installed and ready to use on your server. Additionally, your WordPress installation is dynamically pulling posts, pages, and other content from your managed MySQL database. &lt;/p&gt;

&lt;p&gt;Some common next steps are to choose the permalinks setting for your posts. This setting can be found under &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Permalinks&lt;/strong&gt;. You could also select a new theme in &lt;strong&gt;Appearance&lt;/strong&gt; &amp;gt; &lt;strong&gt;Themes&lt;/strong&gt;. Once you start loading some content into your site, you could also &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-speed-up-wordpress-asset-delivery-using-digitalocean-spaces-cdn" rel="noopener noreferrer"&gt;configure a CDN to speed up your site's asset delivery&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>wordpress</category>
      <category>mysql</category>
      <category>digitalocean</category>
    </item>
    <item>
      <title>The DigitalOcean Community Weekly: Debian 10, Galera, Hacktoberfest, and more!</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Fri, 12 Jul 2019 14:15:19 +0000</pubDate>
      <link>https://forem.com/digitalocean/the-digitalocean-community-weekly-debian-10-galera-hacktoberfest-and-more-4fom</link>
      <guid>https://forem.com/digitalocean/the-digitalocean-community-weekly-debian-10-galera-hacktoberfest-and-more-4fom</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;The DOCOM Weekly&lt;/strong&gt;, your weekly roundup of some of the best content published &lt;em&gt;in&lt;/em&gt; and &lt;em&gt;around&lt;/em&gt; the &lt;a href="https://digitalocean.com/community" rel="noopener noreferrer"&gt;DigitalOcean Community&lt;/a&gt; this past week.&lt;/p&gt;

&lt;p&gt;Hello there, I'm Mark, a Technical Writer on DigitalOcean's Developer Education team. Today's digest includes our rundown of new features in the latest Debian release, a tutorial on how to build a highly-available database cluster, an exciting talk on &lt;a href="https://hacktoberfest.digitalocean.com/" rel="noopener noreferrer"&gt;Hacktoberfest&lt;/a&gt;, and more!&lt;/p&gt;

&lt;p&gt;Here are this week's featured posts from the DigitalOcean Community:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/what-s-new-in-debian-10-buster" rel="noopener noreferrer"&gt;What's New in Debian 10 Buster&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2FDebian_10_Buster_Social-SQUISH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2FDebian_10_Buster_Social-SQUISH.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Debian 10 (also known by its codename, "Buster") was released this past weekend. In this post, &lt;a href="https://www.digitalocean.com/community/users/bboucheron" rel="noopener noreferrer"&gt;Brian Boucheron&lt;/a&gt; goes over some of the changes that come with this new version.&lt;/p&gt;

&lt;p&gt;We're continuing to publish tutorials for this release, but you can find all of our latest Debian 10 content &lt;a href="https://www.digitalocean.com/community/tags/debian-10?type=tutorials" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-prometheus-grafana-and-alertmanager-monitoring-stack-on-digitalocean-kubernetes" rel="noopener noreferrer"&gt;How to Set Up a Prometheus, Grafana and Alertmanager Monitoring Stack on DigitalOcean Kubernetes&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This latest tutorial from &lt;a href="https://www.digitalocean.com/community/users/hjet" rel="noopener noreferrer"&gt;Hanif Jetha&lt;/a&gt; shows how to deploy a monitoring stack consisting of Prometheus, Grafana, and Alertmanager on Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-configure-a-galera-cluster-with-mariadb-on-centos-7-servers" rel="noopener noreferrer"&gt;How To Configure a Galera Cluster with MariaDB on CentOS 7 Servers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This tutorial was written by &lt;a href="https://www.digitalocean.com/community/users/bsder" rel="noopener noreferrer"&gt;bsder&lt;/a&gt;, one of our wonderful Community authors, as part of our &lt;a href="https://www.digitalocean.com/write-for-donations/" rel="noopener noreferrer"&gt;Write for DOnations program&lt;/a&gt;. It describes how to set up a database clustering solution with Galera and MariaDB, giving you a highly-available database with synchronous replication.&lt;/p&gt;

&lt;p&gt;If you'd like to contribute high-quality technical content to the DigitalOcean Community, get paid for your efforts, and designate a tech-related charity to receive a matching donation, apply to write for us &lt;a href="https://www.digitalocean.com/write-for-donations/#anchor--apply-now" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Featured Q&amp;amp;A
&lt;/h2&gt;

&lt;p&gt;Here are some of our favorite questions and answers that have been posted to our Community in the past week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/how-to-install-ruby-on-rails-onto-an-existing-apache-server" rel="noopener noreferrer"&gt;How to install Ruby on Rails onto an existing Apache server?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/configuring-volumes" rel="noopener noreferrer"&gt;Configuring Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/how-set-up-automatic-update-of-let-s-encrypt-certificate" rel="noopener noreferrer"&gt;How Set-Up Automatic Update of Let's Encrypt Certificate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You, too, can get involved in the &lt;a href="https://www.digitalocean.com/community/questions" rel="noopener noreferrer"&gt;Community Q&amp;amp;A&lt;/a&gt;. Ask questions about challenges you encounter and share your expertise with other members!&lt;/p&gt;

&lt;h2&gt;
  
  
  Community IRL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2Flblf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2Flblf.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week, DigitalOcean hosted a Pride celebration event titled &lt;a href="https://www.eventbrite.com/e/looking-back-loving-forward-in-tech-digitaloceans-pride-celebration-panel-tickets-64630250820" rel="noopener noreferrer"&gt;Looking Back, Loving Forward&lt;/a&gt;. A panel of LGBTQ+ technologists visited us at our headquarters in NYC and led an insightful discussion on issues facing the LGBTQ+ tech community. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2Flblf_panel.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Fdevto%2Flblf_panel.jpg" alt="Looking Back, Loving Forward discussion panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DigitalOcean Startup team was at RISEConf in Hong Kong last week. There, they met with hundreds of developers and entrepreneurs to talk about the cloud, passed out some cool Sammy swag, and also led a few talks. Stay tuned for more news about what they were up to in Hong Kong.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1148751194225106945-155" src="https://platform.twitter.com/embed/Tweet.html?id=1148751194225106945"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1148751194225106945-155');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1148751194225106945&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Daniel Zaltsman — Senior Developer Relations Manager at DigitalOcean — was recently in San Francisco attending DevRelCon. There, he gave a talk on &lt;a href="https://devrel.net/community/what-you-can-learn-from-hacktoberfest-daniel-zaltsman" rel="noopener noreferrer"&gt;What You Can Learn From Hacktoberfest&lt;/a&gt;, an annual program that opens up opportunities for both aspiring and experienced developers to contribute to open-source projects. Check out the video here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/c1FikzqXWn8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Lastly, DigitalOcean's Director of Developer Relations, Tim Falls, was interviewed for &lt;a href="https://www.infoq.com/engineering-culture-podcast/" rel="noopener noreferrer"&gt;InfoQ's Engineering Culture podcast&lt;/a&gt;. He and host Shane Hastie discussed developer relations, the importance of open-source software, the need for ethics in education, and more. Listen here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="100%" height="166" src="https://w.soundcloud.com/player/?url=https://soundcloud.com/infoq-engineering-culture/tim-falls-on-developer-relations-open-source-free-education-and-ethics&amp;amp;auto_play=false&amp;amp;color=%23000000&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We'll be back with another roundup next week. Until then, thanks for reading and Happy Hacking!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>digitalocean</category>
      <category>news</category>
      <category>docom</category>
      <category>docomweekly</category>
    </item>
    <item>
      <title>Understanding Managed Databases</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Mon, 29 Apr 2019 13:53:29 +0000</pubDate>
      <link>https://forem.com/digitalocean/understanding-managed-databases-43a9</link>
      <guid>https://forem.com/digitalocean/understanding-managed-databases-43a9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Secure, reliable data storage is a must for nearly every modern application. However, the infrastructure needed for a self-managed, on-premises database can be prohibitively expensive for many teams. Similarly, employees who have the skills and experience needed to maintain a production database effectively can be difficult to come by.&lt;/p&gt;

&lt;p&gt;The spread of cloud computing services has lowered the barriers to entry associated with provisioning a database, but many developers still lack the time or expertise needed to manage and tune a database to suit their needs. For this reason, many businesses are turning to &lt;em&gt;managed database services&lt;/em&gt; to help them build and scale their databases in line with their growth.&lt;/p&gt;

&lt;p&gt;In this conceptual article, we will go over what managed databases are and how they can be beneficial to many organizations. We will also cover some practical considerations one should make before building their next application on top of a managed database solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managed Databases in a Nutshell
&lt;/h2&gt;

&lt;p&gt;A managed database is a cloud computing service in which the end user pays a cloud service provider for access to a database. Unlike a typical database, users don't have to set up or maintain a managed database on their own; rather, it's the provider's responsibility to oversee the database's infrastructure. This allows the user to focus on building their application instead of spending time configuring their database and keeping it up to date.&lt;/p&gt;

&lt;p&gt;The process of provisioning a managed database varies by provider, but in general it's similar to that of any other cloud-based service. After registering an account and logging in to the dashboard, the user reviews the available database options — such as the database engine and cluster size — and then chooses the setup that's right for them. After you provision the managed database, you can connect to it through a GUI or client and can then begin loading data and and integrating the database with your application.&lt;/p&gt;

&lt;p&gt;Managed data solutions simplify the process of provisioning and maintaining a database. Instead of running commands from a terminal to install and set one up, you can deploy a production-ready database with just a few clicks in your browser. By simplifying and automating database management, cloud providers make it easier for anyone, even novice database users, to build data-driven applications and websites. This was the result of a decades-long trend towards simplifying, automating, and abstracting various database management tasks, which was itself a response to pain points long felt by database administrators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pain Points of On-Premises and Self-Managed Databases
&lt;/h2&gt;

&lt;p&gt;Prior to the rise of the cloud computing model, any organization in need of a data center had to supply all the time, space, and resources that went into setting one up. Once their database was up and running, they also had to maintain the hardware, keep its software updated, hire a team to manage the database, and train their employees on how to use it.&lt;/p&gt;

&lt;p&gt;As cloud computing services grew in popularity in the 2000s, it became easier and more affordable to provision server infrastructure, since the hardware and the space required for it no longer had to be owned or managed by those using it. Likewise, setting up a database entirely within the cloud became far less difficult; a business or developer would just have to requisition a server, install and configure their chosen database management system, and begin storing data.&lt;/p&gt;

&lt;p&gt;While cloud computing did make the process of setting up a traditional database easier, it didn't address all of its problems. For instance, in the cloud it can still be difficult to pinpoint the ideal size of a database's infrastructure footprint before it begins collecting data. This is important because cloud consumers are charged based on the resources they consume, and they risk paying for more than what they require if the server they provision is larger than necessary. Additionally, as with traditional on-premises databases, managing one's database in the cloud can be a costly endeavor. Depending on your needs, you may still need to hire an experienced database administrator or spend a significant amount of time and money training your existing staff to manage your database effectively.&lt;/p&gt;

&lt;p&gt;Many of these issues are compounded for smaller organizations and independent developers. While a large business can usually afford to hire employees with a deep knowledge of databases, smaller teams usually have fewer resources available, leaving them with only their existing institutional knowledge. This makes tasks like replication, migrations, and backups all the more difficult and time consuming, as they can require a great deal of on-the-job learning as well as trial and error.&lt;/p&gt;

&lt;p&gt;Managed databases help to resolve these pain points with a host of benefits to businesses and developers. Let's walk through some of these benefits and how they can impact development teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Managed Databases
&lt;/h2&gt;

&lt;p&gt;Managed database services can help to reduce many of the headaches associated with provisioning and managing a database. For one thing, developers build applications on top of managed database services to drastically speed up the process of provisioning a database server. With a self-managed solution, you must obtain a server (either on-premises or in the cloud), connect to it from a client or terminal, configure and secure it, and then install and set up the database management software before you can begin storing data. With a managed database, you only have to decide on the initial size of the database server, configure any additional provider-specific options, and you'll have a new database ready to integrate with your app or website. This can usually be done in just a few minutes through the provider's user interface.&lt;/p&gt;

&lt;p&gt;Another appeal of managed databases is automation. Self-managed databases can consume a large amount of an organization's resources because its employees have to perform every administrative task — from scaling to performing updates, running migrations, and creating backups — manually. With a managed database, however, these and other tasks are done either automatically or on-demand, which markedly reduces the risk of human error.&lt;/p&gt;

&lt;p&gt;This relates to the fact that managed database services help to streamline the process of database scaling. Scaling a self-managed database can be very time- and resource-intensive. Whether you choose sharding, replication, load balancing, or something else as your scaling strategy, if you manage the infrastructure yourself then you're responsible for ensuring that no data is lost in the process and that the application will continue to work properly. If you integrate your application with a managed database service, however, you can scale the database cluster on demand. Rather than having to work out the optimal server size or CPU usage beforehand, you can quickly provision more resources on-the-fly. This helps you avoid using unnecessary resources, meaning you also won't pay for what you don't need.&lt;/p&gt;

&lt;p&gt;Managed solutions tend to have built-in high-availability. In the context of cloud computing, a service is said to be &lt;em&gt;highly available&lt;/em&gt; if it is stable and likely to run without failure for long periods of time. Most reputable cloud providers' products come with a &lt;em&gt;service level agreement (SLA)&lt;/em&gt;, a commitment between the provider and its customers that guarantees the availability and reliability of their services. A typical SLA will specify how much downtime the customer should expect, and many also define the compensation for customers if these service levels are not met. This provides assurance for the customer that their database won't crash and, if it does, they can at least expect some kind of reparation from the provider.&lt;/p&gt;

&lt;p&gt;In general, managed databases simplify the tasks associated with provisioning and maintaining a database. Depending on the provider, you or your team will still likely need some level of experience working with databases in order to provision a database and interact with it as you build and scale your application. Ultimately, though, the database-specific experience needed to administer a managed database will be much less than with self-managed solution.&lt;/p&gt;

&lt;p&gt;Of course, managed databases aren't able to solve every problem, and may prove to be a less-than-ideal choice for some. Next, we'll go over a few of the potential drawbacks one should consider before provisioning a managed database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Considerations
&lt;/h2&gt;

&lt;p&gt;A managed database service can ease the stress of deploying and maintaining a database, but there are still a few things to keep in mind before committing to one. Recall that a principal draw of managed databases is that they abstract away most of the more tedious aspects of database administration. To this end, a managed database provider aims to deliver a rudimentary database that will satisfy the most common use cases. Accordingly, their database offerings won't feature tons of customization options or the unique features included in more specialized database software. Because of this, you won't have as much freedom to tailor your database and you'll be limited to what the cloud provider has to offer.&lt;/p&gt;

&lt;p&gt;A managed database is almost always more expensive than a self-managed one. This makes sense, since you're paying for the cloud provider to support you in managing the database, but it can be a cause for concern for teams with limited resources. Moreover, pricing for managed databases is usually based on how much storage and RAM the database uses, how many reads it handles, and how many backups of the database the user creates. Likewise, any application using a managed database service that handle large amounts of data or traffic will be more expensive than if it were to use a self-managed cloud database.&lt;/p&gt;

&lt;p&gt;One should also reflect on the impact switching to a managed database will have on their internal workflows and whether or not they'll be able to adjust to those changes. Every provider differs, and depending on their SLA they may shoulder responsibility for only some administration tasks, which would be problematic for developers looking for a full-service solution. On the other hand, some providers could have a prohibitively restrictive SLA or make the customer entirely dependent on the provider in question, a situation known as &lt;a href="https://en.wikipedia.org/wiki/Vendor_lock-in" rel="noopener noreferrer"&gt;vendor lock-in&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lastly, and perhaps most importantly, one should carefully consider whether or not any managed database service they're considering using will meet their security needs. All databases, including on-premises databases, are prone to certain security threats, like SQL injection attacks or data leaks. However, the security dynamic is far different for databases hosted in the cloud. Managed database users can't control the physical location of their data or who has access to it, nor can they ensure compliance with specific security standards. This can be especially problematic if your client has heightened security needs.&lt;/p&gt;

&lt;p&gt;To illustrate, imagine that you're hired by a bank to build an application where its clients can access financial records and make payments. The bank may stipulate that the app must have &lt;a href="https://en.wikipedia.org/wiki/Data_at_rest#Encryption" rel="noopener noreferrer"&gt;data at rest encryption&lt;/a&gt; and appropriately scoped user permissions, and that it must be compliant with certain regulatory standards like &lt;a href="https://en.wikipedia.org/wiki/Payment_Card_Industry_Data_Security_Standard" rel="noopener noreferrer"&gt;PCI DSS&lt;/a&gt;. Not all managed database providers adhere to the same regulatory standards or maintain the same security practices, and they're unlikely to adopt new standards or practices for just one of their customers. For this reason, it's critical that you ensure any managed database provider you rely on for such an application is able to meet your security needs as well as the needs of your clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Managed databases have many features that appeal to a wide variety of businesses and developers, but a managed database may not solve every problem or suit everyone's needs. Some may find that a managed database's limited feature set and configuration options, increased cost, and reduced flexibility outweigh any of its potential advantages. However, compelling benefits like ease of use, scalability, automated backups and upgrades, and high availability have led to increased adoption of managed database solutions in a variety of industries.&lt;/p&gt;

&lt;p&gt;If you're interested in learning more about DigitalOcean Managed Databases, we encourage you to check out our Managed Databases &lt;a href="https://www.digitalocean.com/docs/databases" rel="noopener noreferrer"&gt;product documentation&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9dopc8jjbnew6l2xc2j.png" alt="CC 4.0 License"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This work is licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>scaling</category>
      <category>cloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>An Introduction to Queries in PostgreSQL</title>
      <dc:creator>Mark Drake</dc:creator>
      <pubDate>Thu, 21 Feb 2019 23:47:47 +0000</pubDate>
      <link>https://forem.com/digitalocean/-an-introduction-to-queries-in-postgresql-44la</link>
      <guid>https://forem.com/digitalocean/-an-introduction-to-queries-in-postgresql-44la</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Databases are a key component of many websites and applications, and are at the core of how data is stored and exchanged across the internet. One of the most important aspects of database management is the practice of retrieving data from a database, whether it's on an ad hoc basis or part of a process that's been coded into an application. There are several ways to retrieve information from a database, but one of the most commonly-used methods is performed through submitting &lt;em&gt;queries&lt;/em&gt; through the command line.&lt;/p&gt;

&lt;p&gt;In relational database management systems, a &lt;em&gt;query&lt;/em&gt; is any command used to retrieve data from a table. In Structured Query Language (SQL), queries are almost always made using the &lt;code&gt;SELECT&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;In this guide, we will discuss the basic syntax of SQL queries as well as some of the more commonly-employed functions and operators. We will also practice making SQL queries using some sample data in a PostgreSQL database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;, often shortened to "Postgres," is a relational database management system with an object-oriented approach, meaning that information can be represented as objects or classes in PostgreSQL schemas. PostgreSQL aligns closely with standard SQL, although it also includes some features not found in other relational database systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;In general, the commands and concepts presented in this guide can be used on any Linux-based operating system running any SQL database software. However, it was written specifically with an Ubuntu 18.04 server running PostgreSQL in mind. To set this up, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  An Ubuntu 18.04 machine with a non-root user with sudo privileges. This can be set up using our &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;Initial Server Setup guide for Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  PostgreSQL installed on the machine. For help with setting this up, follow the "Installing PostgreSQL" section of our guide on &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-18-04#installing-postgresql?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;How To Install and Use PostgreSQL on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this setup in place, we can begin the tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Sample Database
&lt;/h2&gt;

&lt;p&gt;Before we can begin making queries in SQL, we will first create a database and a couple tables, then populate these tables with some sample data. This will allow you to gain some hands-on experience when you begin making queries later on.&lt;/p&gt;

&lt;p&gt;For the sample database we'll use throughout this guide, imagine the following scenario:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You and several of your friends all celebrate your birthdays with one another. On each occasion, the members of the group head to the local bowling alley, participate in a friendly tournament, and then everyone heads to your place where you prepare the birthday-person's favorite meal.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now that this tradition has been going on for a while, you've decided to begin tracking the records from these tournaments. Also, to make planning dinners easier, you decide to create a record of your friends' birthdays and their favorite entrees, sides, and desserts. Rather than keep this information in a physical ledger, you decide to exercise your database skills by recording it in a PostgreSQL database.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To begin, open up a PostgreSQL prompt as your &lt;strong&gt;postgres&lt;/strong&gt; superuser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo -u postgres psql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you followed all the steps of the prerequisite tutorial on &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-18-04?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;Installing PostgreSQL on Ubuntu 18.04&lt;/a&gt;, you may have configured a new role for your PostgreSQL installation. In this case, you can connect to the Postgres prompt with the following command, substituting &lt;code&gt;sammy&lt;/code&gt; with your own username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo -u sammy psql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the database by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE DATABASE birthdays;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then select this database by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\c birthdays
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create two tables within this database. We'll use the first table to track your friends' records at the bowling alley. The following command will create a table called &lt;code&gt;tourneys&lt;/code&gt; with columns for the &lt;code&gt;name&lt;/code&gt; of each of your friends, the number of tournaments they've won (&lt;code&gt;wins&lt;/code&gt;), their all-time &lt;code&gt;best&lt;/code&gt; score, and what size bowling shoe they wear (&lt;code&gt;size&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE tourneys ( 
name varchar(30), 
wins real, 
best real, 
size real 
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you run the &lt;code&gt;CREATE TABLE&lt;/code&gt; command and populate it with column headings, you’ll receive the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
CREATE TABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Populate the &lt;code&gt;tourneys&lt;/code&gt; table with some sample data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO tourneys (name, wins, best, size) 
VALUES ('Dolly', '7', '245', '8.5'), 
('Etta', '4', '283', '9'), 
('Irma', '9', '266', '7'), 
('Barbara', '2', '197', '7.5'), 
('Gladys', '13', '273', '8');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll receive the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
INSERT 0 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following this, create another table within the same database which we'll use to store information about your friends' favorite birthday meals. The following command creates a table named &lt;code&gt;dinners&lt;/code&gt; with columns for the &lt;code&gt;name&lt;/code&gt; of each of your friends, their &lt;code&gt;birthdate&lt;/code&gt;, their favorite &lt;code&gt;entree&lt;/code&gt;, their preferred &lt;code&gt;side&lt;/code&gt; dish, and their favorite &lt;code&gt;dessert&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE dinners ( 
name varchar(30), 
birthdate date, 
entree varchar(30), 
side varchar(30), 
dessert varchar(30) 
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly for this table, you’ll receive feedback verifying that the table was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
CREATE TABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Populate this table with some sample data as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO dinners (name, birthdate, entree, side, dessert) 
VALUES ('Dolly', '1946-01-19', 'steak', 'salad', 'cake'), 
('Etta', '1938-01-25', 'chicken', 'fries', 'ice cream'), 
('Irma', '1941-02-18', 'tofu', 'fries', 'cake'), 
('Barbara', '1948-12-25', 'tofu', 'salad', 'ice cream'), 
('Gladys', '1944-05-28', 'steak', 'fries', 'ice cream');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
INSERT 0 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that command completes successfully, you're done setting up your database. Next, we'll go over the basic command structure of &lt;code&gt;SELECT&lt;/code&gt; queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding SELECT Statements
&lt;/h2&gt;

&lt;p&gt;As mentioned in the introduction, SQL queries almost always begin with the &lt;code&gt;SELECT&lt;/code&gt; statement. &lt;code&gt;SELECT&lt;/code&gt; is used in queries to specify which columns from a table should be returned in the result set. Queries also almost always include &lt;code&gt;FROM&lt;/code&gt;, which is used to specify which table the statement will query.&lt;/p&gt;

&lt;p&gt;Generally, SQL queries follow this syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT column_to_select FROM table_to_select WHERE certain_conditions_apply;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By way of example, the following statement will return the entire &lt;code&gt;name&lt;/code&gt; column from the &lt;code&gt;dinners&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   
---------
 Dolly
 Etta
 Irma
 Barbara
 Gladys
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can select multiple columns from the same table by separating their names with a comma, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, birthdate FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | birthdate  
---------+------------
 Dolly   | 1946-01-19
 Etta    | 1938-01-25
 Irma    | 1941-02-18
 Barbara | 1948-12-25
 Gladys  | 1944-05-28
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of naming a specific column or set of columns, you can follow the &lt;code&gt;SELECT&lt;/code&gt; operator with an asterisk (&lt;code&gt;*&lt;/code&gt;) which serves as a placeholder representing all the columns in a table. The following command returns every column from the &lt;code&gt;tourneys&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | wins | best | size 
---------+------+------+------
 Dolly   |    7 |  245 |  8.5
 Etta    |    4 |  283 |    9
 Irma    |    9 |  266 |    7
 Barbara |    2 |  197 |  7.5
 Gladys  |   13 |  273 |    8
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WHERE&lt;/code&gt; is used in queries to filter records that meet a specified condition, and any rows that do not meet that condition are eliminated from the result. A &lt;code&gt;WHERE&lt;/code&gt; clause typically follows this syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;. . . WHERE column_name comparison_operator value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comparison operator in a &lt;code&gt;WHERE&lt;/code&gt; clause defines how the specified column should be compared against the value. Here are some common SQL comparison operators:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for equality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for inequality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for less-than&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for greater-than&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for less-than or equal-to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for greater-than or equal-to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BETWEEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests whether a value lies within a given range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests whether a row's value is contained in a set of specified values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EXISTS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests whether rows exist, given the specified conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LIKE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests whether a value matches a specified string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IS NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for &lt;code&gt;NULL&lt;/code&gt; values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IS NOT NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tests for all values other than &lt;code&gt;NULL&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example, if you wanted to find Irma's shoe size, you could use the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT size FROM tourneys WHERE name = 'Irma';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 size 
------
    7
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQL allows the use of wildcard characters, and these are especially handy when used in &lt;code&gt;WHERE&lt;/code&gt; clauses. Percentage signs (&lt;code&gt;%&lt;/code&gt;) represent zero or more unknown characters, and underscores (&lt;code&gt;_&lt;/code&gt;) represent a single unknown character. These are useful if you're trying to find a specific entry in a table, but aren't sure of what that entry is exactly. To illustrate, let's say that you've forgotten the favorite entree of a few of your friends, but you're certain this particular entree starts with a "t." You could find its name by running the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT entree FROM dinners WHERE entree LIKE 't%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 entree  
-------
 tofu
 tofu
(2 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on the output above, we see that the entree we have forgotten is &lt;code&gt;tofu&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There may be times when you're working with databases that have columns or tables with relatively long or difficult-to-read names. In these cases, you can make these names more readable by creating an alias with the &lt;code&gt;AS&lt;/code&gt; keyword. Aliases created with &lt;code&gt;AS&lt;/code&gt; are temporary, and only exist for the duration of the query for which they're created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name AS n, birthdate AS b, dessert AS d FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
    n    |     b      |     d     
---------+------------+-----------
 Dolly   | 1946-01-19 | cake
 Etta    | 1938-01-25 | ice cream
 Irma    | 1941-02-18 | cake
 Barbara | 1948-12-25 | ice cream
 Gladys  | 1944-05-28 | ice cream
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have told SQL to display the &lt;code&gt;name&lt;/code&gt; column as &lt;code&gt;n&lt;/code&gt;, the &lt;code&gt;birthdate&lt;/code&gt; column as &lt;code&gt;b&lt;/code&gt;, and the &lt;code&gt;dessert&lt;/code&gt; column as &lt;code&gt;d&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The examples we've gone through up to this point include some of the more frequently-used keywords and clauses in SQL queries. These are useful for basic queries, but they aren't helpful if you're trying to perform a calculation or derive a &lt;em&gt;scalar value&lt;/em&gt; (a single value, as opposed to a set of multiple different values) based on your data. This is where aggregate functions come into play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregate Functions
&lt;/h2&gt;

&lt;p&gt;Oftentimes, when working with data, you don't necessarily want to see the data itself. Rather, you want information &lt;em&gt;about&lt;/em&gt; the data. The SQL syntax includes a number of functions that allow you to interpret or run calculations on your data just by issuing a &lt;code&gt;SELECT&lt;/code&gt; query. These are known as &lt;em&gt;aggregate functions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;COUNT&lt;/code&gt; function counts and returns the number of rows that match a certain criteria. For example, if you'd like to know how many of your friends prefer tofu for their birthday entree, you could issue this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(entree) FROM dinners WHERE entree = 'tofu';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 count 
-------
     2
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AVG&lt;/code&gt; function returns the average (mean) value of a column. Using our example table, you could find the average best score amongst your friends with this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT AVG(best) FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output  
 avg  
-------
 252.8
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SUM&lt;/code&gt; is used to find the total sum of a given column. For instance, if you'd like to see how many games you and your friends have bowled over the years, you could run this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT SUM(wins) FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output 
 sum 
-----
  35
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;AVG&lt;/code&gt; and &lt;code&gt;SUM&lt;/code&gt; functions will only work correctly when used with numeric data. If you try to use them on non-numerical data, it will result in either an error or just &lt;code&gt;0&lt;/code&gt;, depending on which RDBMS you're using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT SUM(entree) FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
ERROR:  function sum(character varying) does not exist
LINE 1: select sum(entree) from dinners;
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;MIN&lt;/code&gt; is used to find the smallest value within a specified column. You could use this query to see what the worst overall bowling record is so far (in terms of number of wins):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT MIN(wins) FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output 
 min 
-----
   2
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, &lt;code&gt;MAX&lt;/code&gt; is used to find the largest numeric value in a given column. The following query will show the best overall bowling record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT MAX(wins) FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 max 
-----
  13
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike &lt;code&gt;SUM&lt;/code&gt; and &lt;code&gt;AVG&lt;/code&gt;, the &lt;code&gt;MIN&lt;/code&gt; and &lt;code&gt;MAX&lt;/code&gt; functions can be used for both numeric and alphabetic data types. When run on a column containing string values, the &lt;code&gt;MIN&lt;/code&gt; function will show the first value alphabetically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT MIN(name) FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
   min   
---------
 Barbara
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Likewise, when run on a column containing string values, the &lt;code&gt;MAX&lt;/code&gt; function will show the last value alphabetically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT MAX(name) FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 max  
------
 Irma
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aggregate functions have many uses beyond what was described in this section. They're particularly useful when used with the &lt;code&gt;GROUP BY&lt;/code&gt; clause, which is covered in the next section along with several other query clauses that affect how result sets are sorted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manipulating Query Outputs
&lt;/h2&gt;

&lt;p&gt;In addition to the &lt;code&gt;FROM&lt;/code&gt; and &lt;code&gt;WHERE&lt;/code&gt; clauses, there are several other clauses which are used to manipulate the results of a &lt;code&gt;SELECT&lt;/code&gt; query. In this section, we will explain and provide examples for some of the more commonly-used query clauses.&lt;/p&gt;

&lt;p&gt;One of the most frequently-used query clauses, aside from &lt;code&gt;FROM&lt;/code&gt; and &lt;code&gt;WHERE&lt;/code&gt;, is the &lt;code&gt;GROUP BY&lt;/code&gt; clause. It's typically used when you're performing an aggregate function on one column, but in relation to matching values in another.&lt;/p&gt;

&lt;p&gt;For example, let's say you wanted to know how many of your friends prefer each of the three entrees you make. You could find this info with the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(name), entree FROM dinners GROUP BY entree;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 count | entree  
-------+---------
     1 | chicken
     2 | steak
     2 | tofu
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ORDER BY&lt;/code&gt; clause is used to sort query results. By default, numeric values are sorted in ascending order, and text values are sorted in alphabetical order. To illustrate, the following query lists the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;birthdate&lt;/code&gt; columns, but sorts the results by birthdate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, birthdate FROM dinners ORDER BY birthdate;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | birthdate  
---------+------------
 Etta    | 1938-01-25
 Irma    | 1941-02-18
 Gladys  | 1944-05-28
 Dolly   | 1946-01-19
 Barbara | 1948-12-25
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the default behavior of &lt;code&gt;ORDER BY&lt;/code&gt; is to sort the result set in ascending order. To reverse this and have the result set sorted in descending order, close the query with &lt;code&gt;DESC&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, birthdate FROM dinners ORDER BY birthdate DESC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | birthdate  
---------+------------
 Barbara | 1948-12-25
 Dolly   | 1946-01-19
 Gladys  | 1944-05-28
 Irma    | 1941-02-18
 Etta    | 1938-01-25
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned previously, the &lt;code&gt;WHERE&lt;/code&gt; clause is used to filter results based on specific conditions. However, if you use the &lt;code&gt;WHERE&lt;/code&gt; clause with an aggregate function, it will return an error, as is the case with the following attempt to find which sides are the favorite of at least three of your friends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(name), side FROM dinners WHERE COUNT(name) &amp;gt;= 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
ERROR:  aggregate functions are not allowed in WHERE
LINE 1: SELECT COUNT(name), side FROM dinners WHERE COUNT(name) &amp;gt;= 3...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;HAVING&lt;/code&gt; clause was added to SQL to provide functionality similar to that of the &lt;code&gt;WHERE&lt;/code&gt; clause while also being compatible with aggregate functions. It's helpful to think of the difference between these two clauses as being that &lt;code&gt;WHERE&lt;/code&gt; applies to individual records, while &lt;code&gt;HAVING&lt;/code&gt; applies to group records. To this end, any time you issue a &lt;code&gt;HAVING&lt;/code&gt; clause, the &lt;code&gt;GROUP BY&lt;/code&gt; clause must also be present.&lt;/p&gt;

&lt;p&gt;The following example is another attempt to find which side dishes are the favorite of at least three of your friends, although this one will return a result without error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(name), side FROM dinners GROUP BY side HAVING COUNT(name) &amp;gt;= 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 count | side  
-------+-------
     3 | fries
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aggregate functions are useful for summarizing the results of a particular column in a given table. However, there are many cases where it's necessary to query the contents of more than one table. We'll go over a few ways you can do this in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying Multiple Tables
&lt;/h2&gt;

&lt;p&gt;More often than not, a database contains multiple tables, each holding different sets of data. SQL provides a few different ways to run a single query on multiple tables.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;JOIN&lt;/code&gt; clause can be used to combine rows from two or more tables in a query result. It does this by finding a related column between the tables and sorts the results appropriately in the output.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT&lt;/code&gt; statements that include a &lt;code&gt;JOIN&lt;/code&gt; clause generally follow this syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT table1.column1, table2.column2
FROM table1
JOIN table2 ON table1.related_column=table2.related_column;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that because &lt;code&gt;JOIN&lt;/code&gt; clauses compare the contents of more than one table, the previous example specifies which table to select each column from by preceding the name of the column with the name of the table and a period. You can specify which table a column should be selected from like this for any query, although it's not necessary when selecting from a single table, as we've done in the previous sections. Let's walk through an example using our sample data.&lt;/p&gt;

&lt;p&gt;Imagine that you wanted to buy each of your friends a pair of bowling shoes as a birthday gift. Because the information about your friends' birthdates and shoe sizes are held in separate tables, you could query both tables separately then compare the results from each. With a &lt;code&gt;JOIN&lt;/code&gt; clause, though, you can find all the information you want with a single query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT tourneys.name, tourneys.size, dinners.birthdate 
FROM tourneys 
JOIN dinners ON tourneys.name=dinners.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | size | birthdate  
---------+------+------------
 Dolly   |  8.5 | 1946-01-19
 Etta    |    9 | 1938-01-25
 Irma    |    7 | 1941-02-18
 Barbara |  7.5 | 1948-12-25
 Gladys  |    8 | 1944-05-28
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;JOIN&lt;/code&gt; clause used in this example, without any other arguments, is an &lt;em&gt;inner&lt;/em&gt; &lt;code&gt;JOIN&lt;/code&gt; clause. This means that it selects all the records that have matching values in both tables and prints them to the results set, while any records that aren't matched are excluded. To illustrate this idea, let's add a new row to each table that doesn't have a corresponding entry in the other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO tourneys (name, wins, best, size) 
VALUES ('Bettye', '0', '193', '9');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO dinners (name, birthdate, entree, side, dessert) 
VALUES ('Lesley', '1946-05-02', 'steak', 'salad', 'ice cream');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, re-run the previous &lt;code&gt;SELECT&lt;/code&gt; statement with the &lt;code&gt;JOIN&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT tourneys.name, tourneys.size, dinners.birthdate 
FROM tourneys 
JOIN dinners ON tourneys.name=dinners.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | size | birthdate  
---------+------+------------
 Dolly   |  8.5 | 1946-01-19
 Etta    |    9 | 1938-01-25
 Irma    |    7 | 1941-02-18
 Barbara |  7.5 | 1948-12-25
 Gladys  |    8 | 1944-05-28
(5 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that, because the &lt;code&gt;tourneys&lt;/code&gt; table has no entry for Lesley and the &lt;code&gt;dinners&lt;/code&gt; table has no entry for Bettye, those records are absent from this output.&lt;/p&gt;

&lt;p&gt;It is possible, though, to return all the records from one of the tables using an &lt;em&gt;outer&lt;/em&gt; &lt;code&gt;JOIN&lt;/code&gt; clause. Outer &lt;code&gt;JOIN&lt;/code&gt; clauses are written as either &lt;code&gt;LEFT JOIN&lt;/code&gt;, &lt;code&gt;RIGHT JOIN&lt;/code&gt;, or &lt;code&gt;FULL JOIN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;LEFT JOIN&lt;/code&gt; clause returns all the records from the “left” table and only the matching records from the right table. In the context of outer joins, the left table is the one referenced by the &lt;code&gt;FROM&lt;/code&gt; clause, and the right table is any other table referenced after the &lt;code&gt;JOIN&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;Run the previous query again, but this time use a &lt;code&gt;LEFT JOIN&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT tourneys.name, tourneys.size, dinners.birthdate 
FROM tourneys 
LEFT JOIN dinners ON tourneys.name=dinners.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will return every record from the left table (in this case, &lt;code&gt;tourneys&lt;/code&gt;) even if it doesn't have a corresponding record in the right table. Any time there isn't a matching record from the right table, it's returned as a blank value or &lt;code&gt;NULL&lt;/code&gt;, depending on your RDBMS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | size | birthdate  
---------+------+------------
 Dolly   |  8.5 | 1946-01-19
 Etta    |    9 | 1938-01-25
 Irma    |    7 | 1941-02-18
 Barbara |  7.5 | 1948-12-25
 Gladys  |    8 | 1944-05-28
 Bettye  |    9 | 
(6 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the query again, this time with a &lt;code&gt;RIGHT JOIN&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT tourneys.name, tourneys.size, dinners.birthdate 
FROM tourneys 
RIGHT JOIN dinners ON tourneys.name=dinners.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return all the records from the right table (&lt;code&gt;dinners&lt;/code&gt;). Because Lesley's birthdate is recorded in the right table, but there is no corresponding row for her in the left table, the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;size&lt;/code&gt; columns will return as blank values in that row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | size | birthdate  
---------+------+------------
 Dolly   |  8.5 | 1946-01-19
 Etta    |    9 | 1938-01-25
 Irma    |    7 | 1941-02-18
 Barbara |  7.5 | 1948-12-25
 Gladys  |    8 | 1944-05-28
         |      | 1946-05-02
(6 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that left and right joins can be written as &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; or &lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt;, although the &lt;code&gt;OUTER&lt;/code&gt; part of the clause is implied. Likewise, specifying &lt;code&gt;INNER JOIN&lt;/code&gt; will produce the same result as just writing &lt;code&gt;JOIN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a fourth join clause called &lt;code&gt;FULL JOIN&lt;/code&gt; available for some RDBMS distributions, including PostgreSQL. A &lt;code&gt;FULL JOIN&lt;/code&gt; will return all the records from each table, including any null values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT tourneys.name, tourneys.size, dinners.birthdate 
FROM tourneys 
FULL JOIN dinners ON tourneys.name=dinners.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   | size | birthdate  
---------+------+------------
 Dolly   |  8.5 | 1946-01-19
 Etta    |    9 | 1938-01-25
 Irma    |    7 | 1941-02-18
 Barbara |  7.5 | 1948-12-25
 Gladys  |    8 | 1944-05-28
 Bettye  |    9 | 
         |      | 1946-05-02
(7 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As of this writing, the &lt;code&gt;FULL JOIN&lt;/code&gt; clause is not supported by either MySQL or MariaDB.  &lt;/p&gt;

&lt;p&gt;As an alternative to using &lt;code&gt;FULL JOIN&lt;/code&gt; to query all the records from multiple tables, you can use the &lt;code&gt;UNION&lt;/code&gt; clause.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;UNION&lt;/code&gt; operator works slightly differently than a &lt;code&gt;JOIN&lt;/code&gt; clause: instead of printing results from multiple tables as unique columns using a single &lt;code&gt;SELECT&lt;/code&gt; statement, &lt;code&gt;UNION&lt;/code&gt; combines the results of two &lt;code&gt;SELECT&lt;/code&gt; statements into a single column.&lt;/p&gt;

&lt;p&gt;To illustrate, run the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name FROM tourneys UNION SELECT name FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will remove any duplicate entries, which is the default behavior of the &lt;code&gt;UNION&lt;/code&gt; operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   
---------
 Irma
 Etta
 Bettye
 Gladys
 Barbara
 Lesley
 Dolly
(7 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To return all entries (including duplicates) use the &lt;code&gt;UNION ALL&lt;/code&gt; operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name FROM tourneys UNION ALL SELECT name FROM dinners;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name   
---------
 Dolly
 Etta
 Irma
 Barbara
 Gladys
 Bettye
 Dolly
 Etta
 Irma
 Barbara
 Gladys
 Lesley
(12 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The names and number of the columns in the results table reflect the name and number of columns queried by the first &lt;code&gt;SELECT&lt;/code&gt; statement. Note that when using &lt;code&gt;UNION&lt;/code&gt; to query multiple columns from more than one table, each &lt;code&gt;SELECT&lt;/code&gt; statement must query the same number of columns, the respective columns must have similar data types, and the columns in each &lt;code&gt;SELECT&lt;/code&gt; statement must be in the same order. The following example shows what might result if you use a &lt;code&gt;UNION&lt;/code&gt; clause on two &lt;code&gt;SELECT&lt;/code&gt; statements that query a different number of columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name FROM dinners UNION SELECT name, wins FROM tourneys;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
ERROR:  each UNION query must have the same number of columns
LINE 1: SELECT name FROM dinners UNION SELECT name, wins FROM tourne...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another way to query multiple tables is through the use of &lt;em&gt;subqueries&lt;/em&gt;. Subqueries (also known as &lt;em&gt;inner&lt;/em&gt; or &lt;em&gt;nested queries&lt;/em&gt;) are queries enclosed within another query. These are useful in cases where you're trying to filter the results of a query against the result of a separate aggregate function.&lt;/p&gt;

&lt;p&gt;To illustrate this idea, say you want to know which of your friends have won more matches than Barbara. Rather than querying how many matches Barbara has won then running another query to see who has won more games than that, you can calculate both with a single query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, wins FROM tourneys 
WHERE wins &amp;gt; (
SELECT wins FROM tourneys WHERE name = 'Barbara'
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name  | wins 
--------+------
 Dolly  |    7
 Etta   |    4
 Irma   |    9
 Gladys |   13
(4 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The subquery in this statement was run only once; it only needed to find the value from the &lt;code&gt;wins&lt;/code&gt; column in the same row as &lt;code&gt;Barbara&lt;/code&gt; in the &lt;code&gt;name&lt;/code&gt; column, and the data returned by the subquery and outer query are independent of one another. There are cases, though, where the outer query must first read every row in a table and compare those values against the data returned by the subquery in order to return the desired data. In this case, the subquery is referred to as a &lt;em&gt;correlated subquery&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The following statement is an example of a correlated subquery. This query seeks to find which of your friends have won more games than is the average for those with the same shoe size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, size FROM tourneys AS t 
WHERE wins &amp;gt; (
SELECT AVG(wins) FROM tourneys WHERE size = t.size
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order for the query to complete, it must first collect the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;size&lt;/code&gt; columns from the outer query. Then, it compares each row from that result set against the results of the inner query, which determines the average number of wins for individuals with identical shoe sizes. Because you only have two friends that have the same shoe size, there can only be one row in the result set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
 name | size 
------+------
 Etta |    9
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned earlier, subqueries can be used to query results from multiple tables. To illustrate this with one final example, say you wanted to throw a surprise dinner for the group's all-time best bowler. You could find which of your friends has the best bowling record and return their favorite meal with the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, entree, side, dessert 
FROM dinners 
WHERE name = (SELECT name FROM tourneys 
WHERE wins = (SELECT MAX(wins) FROM tourneys));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output
  name  | entree | side  |  dessert  
--------+--------+-------+-----------
 Gladys | steak  | fries | ice cream
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this statement not only includes a subquery, but also contains a subquery within that subquery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Issuing queries is one of the most commonly-performed tasks within the realm of database management. There are a number of database administration tools, such as &lt;a href="https://www.phpmyadmin.net/" rel="noopener noreferrer"&gt;phpMyAdmin&lt;/a&gt; or &lt;a href="https://www.pgadmin.org/" rel="noopener noreferrer"&gt;pgAdmin&lt;/a&gt;, that allow you to perform queries and visualize the results, but issuing &lt;code&gt;SELECT&lt;/code&gt; statements from the command line is still a widely-practiced workflow that can also provide you with greater control.&lt;/p&gt;

&lt;p&gt;If you're new to working with SQL, we encourage you to use our &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-manage-sql-database-cheat-sheet?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;SQL Cheat Sheet&lt;/a&gt; as a reference and to review the &lt;a href="https://www.postgresql.org/docs/10/static/index.html" rel="noopener noreferrer"&gt;official PostgreSQL documenation&lt;/a&gt;. Additionally, if you'd like to learn more about SQL and relational databases, the following tutorials may be of interest to you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/understanding-sql-and-nosql-databases-and-different-database-models?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;Understanding SQL And NoSQL Databases And Different Database Models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-logical-replication-with-postgresql-10-on-ubuntu-18-04?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;How To Set Up Logical Replication with PostgreSQL 10 on Ubuntu 18.04&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-postgresql-against-automated-attacks?utm_source=devto&amp;amp;utm_medium=display&amp;amp;utm_campaign=DO_Dev_Awareness_Cold_Devto_2019" rel="noopener noreferrer"&gt;How To Secure PostgreSQL Against Automated Attacks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9dopc8jjbnew6l2xc2j.png" alt="CC 4.0 License"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This work is licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>postgres</category>
      <category>database</category>
    </item>
  </channel>
</rss>
