<?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>DEV Community: Jimmy Guerrero</title>
    <description>The latest articles on DEV Community by Jimmy Guerrero (@jguerreroyb).</description>
    <link>https://dev.to/jguerreroyb</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%2F354560%2F32ada347-b60f-4f23-8f19-85c4560678cd.png</url>
      <title>DEV Community: Jimmy Guerrero</title>
      <link>https://dev.to/jguerreroyb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jguerreroyb"/>
    <language>en</language>
    <item>
      <title>Enabling pgAudit, pgcrypto and scram-SHA-256 in Distributed SQL</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Wed, 25 Nov 2020 22:03:55 +0000</pubDate>
      <link>https://dev.to/yugabyte/enabling-pgaudit-pgcrypto-and-scram-sha-256-in-distributed-sql-3kjl</link>
      <guid>https://dev.to/yugabyte/enabling-pgaudit-pgcrypto-and-scram-sha-256-in-distributed-sql-3kjl</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a cross-post of my colleague Karthik Ranganathan's blog originally posted on the &lt;a href="https://blog.yugabyte.com/whats-new-in-yugabytedb-2-5-enterprise-grade-security-features/" rel="noopener noreferrer"&gt;Yugabyte blog.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The YugabyteDB 2.5 release adds many critical enterprise-grade security features. This blog post outlines these newly added features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Adding scram-sha-256 authentication
&lt;/h3&gt;

&lt;p&gt;The first notable addition is the addition of a much improved, password-based authentication mechanism called Salted Challenge Response Authentication Mechanism (or simply SCRAM) as described in &lt;a href="https://tools.ietf.org/html/rfc5802" rel="noopener noreferrer"&gt;RFC5802&lt;/a&gt;. This scram-sha-256 authentication mechanism, identical to the most secure PostgreSQL authentication schema, is a challenge-response scheme that prevents password sniffing on untrusted connections and supports storing passwords on the server in a cryptographically hashed form that is thought to be secure. To enable this feature, simply pass the following flag when starting the yb-tserver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yb-tserver 
  &amp;lt;other flags&amp;gt; 
  --ysql_pg_conf="password_encryption=scram-sha-256"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that this is supported only by the YSQL API. Read more about &lt;a href="https://docs.yugabyte.com/latest/secure/authentication/password-authentication/" rel="noopener noreferrer"&gt;scram-sha-256 authentication mechanism in YugabyteDB documentation.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  LDAP authentication
&lt;/h3&gt;

&lt;p&gt;The Lightweight Directory Access Protocol, more commonly abbreviated to LDAP, is an open industry standard for authentication of users. This allows users to use a single password to connect to multiple services, including connecting to databases and running queries against them. With this release, the YSQL API can be configured to authenticate users using LDAP as the password verification method.&lt;/p&gt;

&lt;p&gt;Enabling LDAP authentication in YugabyteDB internally sets up two host-based authentication rules. Configure YugabyteDB to work with an external LDAP directory service for authentication works as follows:&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting up roles and permissions for LDAP users:
&lt;/h4&gt;

&lt;p&gt;The first rule allows connecting to the database as the admin user (which is &lt;code&gt;yugabyte&lt;/code&gt; by default) from the localhost (&lt;code&gt;127.0.0.1&lt;/code&gt;) using password authentication. This allows administrators to immediately log in with the admin user credentials and set up the required roles and permissions for the LDAP users.&lt;/p&gt;

&lt;p&gt;This can be accomplished by starting the yb-tserver processes with the following flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--ysql_hba_conf_csv='host all yugabyte 127.0.0.1/0 password,"host   all all 0.0.0.0/0 ldap ldapserver=&amp;lt;ldap-server-url&amp;gt; ldapprefix=""uid="" ldapsuffix="", dc=example, dc=com"" ldapport=389"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above would generate the following &lt;code&gt;ysql_hba.conf&lt;/code&gt; internal configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This is an autogenerated file, do not edit manually!
host all yugabyte 127.0.0.1/0 trust
host   all         all      0.0.0.0/0  ldap ldapserver=&amp;lt;ldap-server-url&amp;gt; ldapprefix="uid=" ldapsuffix=", dc=example, dc=com" ldapport=389
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure LDAP authentication for all other user/host pairs:
&lt;/h4&gt;

&lt;p&gt;The second rule configures authentication for all other additional user/host pairs by using simple bind with a uid-based username (&lt;code&gt;ldapprefix&lt;/code&gt;) and a suffix defining the domain component (dc). These should be provided by the LDAP provider.&lt;/p&gt;

&lt;p&gt;Connect to the database using &lt;code&gt;ysqlsh&lt;/code&gt; and create one or more of the roles required, as shown in the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE ROLE yb_user WITH LOGIN;
GRANT ALL ON DATABASE yugabyte TO yb_user;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Connect using LDAP authentication:
&lt;/h4&gt;

&lt;p&gt;To test connecting to the database using LDAP, simply connect with an LDAP user, as shown below and enter the password when prompted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bin/ysqlsh -U yb_user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can confirm the current user 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;SELECT current_user;
 current_user
--------------
 yb_user
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LDAP authentication scheme can operate in a simple bind mode or the search-and-bind mode, as well as using a secure connection using TLS encryption between PostgreSQL and the LDAP server using the &lt;code&gt;ldaptls&lt;/code&gt; option. Read more about &lt;a href="https://docs.yugabyte.com/latest/secure/authentication/ldap-authentication/" rel="noopener noreferrer"&gt;using YugabyteDB with LDAP.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit Logging
&lt;/h2&gt;

&lt;p&gt;Audit logging allows administrators and users to track activity related to data access, such as who accessed which portions of data, helping to understand the extent of a breach and sometimes even identify the attackers. Retaining audit logs is also a compliance requirement not only in regulated industries, but also increasingly in scenarios where data privacy laws like GDPR take effect. Audit logging in YugabyteDB will write the output on each node to the standard logging facility, similar to the design of PostgreSQL. These partial log files can subsequently be merged for a global audit trail. This feature is supported for both the YSQL and YCQL APIs. You can read more about &lt;a href="https://docs.yugabyte.com/latest/secure/audit-logging/" rel="noopener noreferrer"&gt;audit logging in YugabyteDB in the documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The YSQL API internally uses the &lt;a href="https://www.pgaudit.org/" rel="noopener noreferrer"&gt;pgAudit extension&lt;/a&gt; to provide detailed session-level and object-level audit logging. It is possible to both filter what gets logged, as well as configure the output format. The extension is preinstalled in YugabyteDB, so using this feature is easy.&lt;/p&gt;

&lt;h3&gt;
  
  
  To configure audit logging:
&lt;/h3&gt;

&lt;p&gt;Pass the following flag to the &lt;code&gt;yb-tserver&lt;/code&gt; as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yb-tserver 
  &amp;lt;other flags&amp;gt; 
  --ysql_pg_conf="pgaudit.log='DDL',pgaudit.log_level=notice"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, this feature can also be configured with the &lt;code&gt;SET&lt;/code&gt; command to change runtime parameters, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET pgaudit.log='DDL'; 
SET pgaudit.log_client=ON;
SET pgaudit.log_level=notice;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  To enable audit logging:
&lt;/h3&gt;

&lt;p&gt;First load the extension by running the following SQL command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE EXTENSION IF NOT EXISTS pgaudit;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing the audit logging feature:
&lt;/h3&gt;

&lt;p&gt;Let us create a table by running the following.&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 test (a int);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following entry should get written to the standard log.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOTICE:  AUDIT: SESSION,4,1,DDL,CREATE TABLE,TABLE,public.tmp,"CREATE TABLE test (a int);",&amp;lt;not logged&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Customizing audit logging:
&lt;/h3&gt;

&lt;p&gt;There are a number of configuration options available to customize this feature, for example specifying the classes of statements that should be logged, the output format, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Column Level Permissions
&lt;/h2&gt;

&lt;p&gt;Column level security can be used to specify the exact set of columns a user can access or modify (&lt;code&gt;SELECT, INSERT, UPDATE&lt;/code&gt; privileges) using the &lt;code&gt;GRANT&lt;/code&gt; command. This would effectively prevent the user from seeing or updating all the other columns. You can learn more about &lt;a href="https://docs.yugabyte.com/latest/secure/authorization/column-level-security/" rel="noopener noreferrer"&gt;column level security in the YugabyteDB documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An example is shown below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create an employee table and insert few sample rows:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# create table employees ( empno int, ename text, address text, salary int, account_number text );
CREATE TABLE

yugabyte=# insert into employees values (1, 'joe', '56 grove st',  20000, 'AC-22001' );
INSERT 0 1
yugabyte=# insert into employees values (2, 'mike', '129 81 st',  80000, 'AC-48901' );
INSERT 0 1
yugabyte=# insert into employees values (3, 'julia', '1 finite loop',  40000, 'AC-77051' );
INSERT 0 1

yugabyte=# select * from employees;
 empno | ename |    address    | salary | account_number
-------+-------+---------------+--------+----------------
     1 | Joe   | 56 grove st   |  20000 | AC-22001
     2 | Mike  | 129 81 st     |  80000 | AC-48901
     3 | Julia | 1 finite loop |  40000 | AC-77051
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a user &lt;code&gt;ybadmin&lt;/code&gt; with column-level privileges on the table above:
&lt;/h3&gt;

&lt;p&gt;Assume we want to prevent this &lt;code&gt;ybadmin&lt;/code&gt; user from viewing sensitivity information of employees, such as &lt;code&gt;salary&lt;/code&gt; and &lt;code&gt;account_number&lt;/code&gt;. This can be done as follows by using the following &lt;code&gt;GRANT&lt;/code&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=&amp;gt; \c yugabyte yugabyte;
You are now connected to database "yugabyte" as user "yugabyte".

yugabyte=# create user ybadmin;
CREATE ROLE

yugabyte=# grant select (empno, ename, address) on employees to ybadmin;
GRANT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify column-level permissions:
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ybadmin&lt;/code&gt; user will now be able to access only the columns to which permissions were granted. This can be verified as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# \c yugabyte ybadmin;
You are now connected to database "yugabyte" as user "ybadmin".

yugabyte=&amp;gt; select empno, ename, address from employees;
 empno | ename |    address
-------+-------+---------------
     1 | joe   | 56 grove st
     3 | julia | 1 finite loop
     2 | mike  | 129 81 st
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ybadmin&lt;/code&gt; will still be denied if user tries to access other columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=&amp;gt; select empno, ename, address, salary from employees;
ERROR:  permission denied for table employees
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Encryption of data
&lt;/h2&gt;

&lt;p&gt;In addition to the natively supporting &lt;a href="https://docs.yugabyte.com/latest/secure/encryption-at-rest/" rel="noopener noreferrer"&gt;encryption of data at rest&lt;/a&gt;, the 2.5 release adds a number of other data encryption related features. YugabyteDB now interoperates with Vormetric Transparent Encryption (VTE) to secure sensitive data allowing users to protect themselves from a wide range of risks from malicious hackers to database administrators with privileged data access. Encrypted backups are now supported by YugabyteDB, enabling backing up sensitive data securely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Column-level encryption
&lt;/h3&gt;

&lt;p&gt;Column-level encryption is also now supported by YugabyteDB (YSQL only). It uses the &lt;a href="https://www.postgresql.org/docs/10/pgcrypto.html" rel="noopener noreferrer"&gt;pgcrypto&lt;/a&gt; module to allow only the columns containing sensitive data to be encrypted before storing them on disk. The client supplies the decryption key and the data is decrypted on the server and then sent to the client. You can read more about &lt;a href="https://docs.yugabyte.com/latest/secure/column-level-encryption/" rel="noopener noreferrer"&gt;column-level encryption&lt;/a&gt; in the YugabyteDB docs.&lt;/p&gt;

&lt;p&gt;Let’s run through an example of symmetric column-level encryption.&lt;/p&gt;

&lt;h4&gt;
  
  
  Enable &lt;code&gt;pgcrypto&lt;/code&gt; extension:
&lt;/h4&gt;

&lt;p&gt;Open the YSQL shell (ysqlsh), specifying the &lt;code&gt;yugabyte&lt;/code&gt; user and prompting for the password.&lt;/p&gt;

&lt;p&gt;$ ./ysqlsh -U yugabyte -W&lt;br&gt;
When prompted for the password, enter the yugabyte password. You should be able to login and see a response like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ysqlsh (11.2-YB-2.5.0.0-b0)
Type "help" for help.
yugabyte=#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable &lt;code&gt;pgcrypto&lt;/code&gt; extension on the YugabyteDB cluster &lt;code&gt;yugabyte=&amp;gt; \c yugabyte yugabyte;&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;You are now connected to database "yugabyte" as user "yugabyte".
yugabyte=# CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Insert using PGP_SYM_ENCRYPT
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;employees&lt;/code&gt; table and insert data into the table using &lt;code&gt;PGP_SYM_ENCRYPT&lt;/code&gt; function for columns that need to be encrypted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# create table employees ( empno int, ename text, address text, salary int, account_number text );
CREATE TABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, account numbers of &lt;code&gt;employees&lt;/code&gt; table will be encrypted using &lt;code&gt;PGP_SYM_ENCRYPT&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# insert into employees values (1, 'joe', '56 grove st',  20000, PGP_SYM_ENCRYPT('AC-22001', 'AES_KEY'));
INSERT 0 1
yugabyte=# insert into employees values (2, 'mike', '129 81 st',  80000, PGP_SYM_ENCRYPT('AC-48901', 'AES_KEY'));
INSERT 0 1
yugabyte=# insert into employees values (3, 'julia', '1 finite loop',  40000, PGP_SYM_ENCRYPT('AC-77051', 'AES_KEY'));
INSERT 0 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Verify column encryption:
&lt;/h4&gt;

&lt;p&gt;Review the encrypted &lt;code&gt;account_number&lt;/code&gt; data, as shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# select ename, account_number from employees limit 1;
 ename |               account_number
-------+-------------------------------------------------
 joe   | \xc30d04070302ee4c6d5f6656ace96ed23901f56c717d4e
 162b6639429f516b5103acebc4bc91ec15df06c30e29e6841f4a5386
 e7698bfebb49a8660f9ae4b3f34fede3f28c9c7bb245bd
(1 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Query using &lt;code&gt;PGP_SYM_DECRYPT&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Decrypt the account numbers using &lt;code&gt;PGP_SYM_DECRYPT&lt;/code&gt; function as shown here. In order to retrieve the encrypted column data, use &lt;code&gt;PGP_SYM_DECRYPT&lt;/code&gt; function to decrypt the data. The Decryption function needs to be used in both &lt;code&gt;SELECT&lt;/code&gt; and &lt;code&gt;WHERE&lt;/code&gt; clause depending on the query.&lt;/p&gt;

&lt;p&gt;To allow the decryption, the field name is also casted to the binary data type with the syntax: &lt;code&gt;account_number:bytea.&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;yugabyte=# select PGP_SYM_DECRYPT(account_number::bytea, 'AES_KEY') as AccountNumber
           from employees;
 accountnumber
---------------
 AC-22001
 AC-48901
 AC-77051
(3 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;We’re very happy to be able to release all of these latest and greatest security features into YugabyteDB 2.5. We invite you to learn more and try it out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register for the upcoming webinar, &lt;a href="https://yugabyte.zoom.us/webinar/register/WN_OFxukOzGTyqa9r8Z7iVWIQ" rel="noopener noreferrer"&gt;"Enterprise Security Features in YugabyteDB,"&lt;/a&gt; taking place on December 8 at 11 am Pacific&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.yugabyte.com/announcing-yugabytedb-2-5/" rel="noopener noreferrer"&gt;Read the YugabyteDB 2.5 release announcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://download.yugabyte.com/" rel="noopener noreferrer"&gt;Install YugabyteDB 2.5&lt;/a&gt; in mere minutes&lt;/li&gt;
&lt;li&gt;&lt;a href="http://yugabyte.com/slack" rel="noopener noreferrer"&gt;Join us in Slack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>sql</category>
      <category>postgres</category>
      <category>security</category>
    </item>
    <item>
      <title>A PostgreSQL-Compatible, Distributed SQL Cheat Sheet: The Basics</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Thu, 01 Oct 2020 19:54:06 +0000</pubDate>
      <link>https://dev.to/yugabyte/a-postgresql-compatible-distributed-sql-cheat-sheet-the-basics-4ep7</link>
      <guid>https://dev.to/yugabyte/a-postgresql-compatible-distributed-sql-cheat-sheet-the-basics-4ep7</guid>
      <description>&lt;p&gt;In this blog post, we’ll highlight how all the basic commands you end up using in the first few minutes after installing PostgreSQL are identical in YugabyteDB. We’ll cover connecting to the database, creating users, databases, schemas, and calling external files from the SQL shell. In the next blog post in this series we’ll tackle querying data to demonstrate that if you know how to query data in PostgreSQL, you already know how to do it in YugabyteDB.&lt;/p&gt;

&lt;p&gt;First things first, for those of you who might be new to either distributed SQL or YugabyteDB…&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or cloud native environments. This is often motivated by the desire to reduce TCO or move away from the horizontal scaling limitations of monolithic RDBMS like Oracle, PostgreSQL, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They must have a SQL API for querying and modeling data, with support for traditional RDBMS features like foreign keys, partial indexes, stored procedures and triggers.&lt;/li&gt;
&lt;li&gt;Smart distributed query execution so that query processing is pushed closer to the data as opposed to data being pushed over the network and thus slowing down query response times.&lt;/li&gt;
&lt;li&gt;Should support automatic and transparent distributed data storage. This includes indexes which should be sharded across multiple nodes of the cluster so that no single node becomes a bottleneck. Data distribution ensures high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What’s YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. &lt;strong&gt;YugabyteDB is PostgreSQL wire compatible&lt;/strong&gt;, cloud native, offers deep integration with GraphQL projects, plus supports advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Got questions? Make sure to ask them in our &lt;a href="https://www.yugabyte.com/slack" rel="noopener noreferrer"&gt;YugabyteDB Slack channel&lt;/a&gt;. Ok, let’s dive in…&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing YugabyteDB
&lt;/h1&gt;

&lt;p&gt;YugabyteDB is only slightly more involved than getting PostgreSQL up and running. At the end of the day it should only take a few minutes or less depending on your environment. Let’s look at a few scenarios:&lt;/p&gt;

&lt;h3&gt;
  
  
  Single Node Installation on Mac
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://downloads.yugabyte.com/yugabyte-2.3.0.0-darwin.tar.gz
$ tar xvfz yugabyte-2.3.0.0-darwin.tar.gz &amp;amp;&amp;amp; cd yugabyte-2.3.0.0/
$ ./bin/yugabyted start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Single Node Installation on Linux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://downloads.yugabyte.com/yugabyte-2.3.0.0-linux.tar.gz
$ tar xvfz yugabyte-2.3.0.0-linux.tar.gz &amp;amp;&amp;amp; cd yugabyte-2.3.0.0/
$ ./bin/post_install.sh
$ ./bin/yugabyted start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you want to run 3 local nodes instead of a single node for either the Mac or Linux setups, just tweak the last command so it reads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bin/yb-ctl --rf 3 create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3 Node Installation on Google Kubernetes Engine
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo add yugabytedb https://charts.yugabyte.com
$ helm repo update
$ kubectl create namespace yb-demo
$ helm install yb-demo yugabytedb/yugabyte --namespace yb-demo --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information on other installation types and prerequisites, check out the &lt;a href="https://docs.yugabyte.com/latest/quick-start/" rel="noopener noreferrer"&gt;Quickstart Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Connecting to a YugabyteDB Cluster
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Connect Locally
&lt;/h3&gt;

&lt;p&gt;Assuming you are in the YugabyteDB install directory, simply execute the following to get to a YSQL shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./bin/ysqlsh

ysqlsh (11.2-YB-2.3.0.0-b0)
Type "help" for help.

yugabyte=#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connecting on GKE
&lt;/h3&gt;

&lt;p&gt;Assuming you are connected to the Kubernetes cluster via the Google Cloud Console, execute the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo

ysqlsh (11.2-YB-2.3.0.0-b0)
Type "help" for help.

yugabyte=# 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the documentation for more information about YugabyteDB’s &lt;a href="https://docs.yugabyte.com/latest/api/ysql/" rel="noopener noreferrer"&gt;PostgreSQL-compatible YSQL API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting via JDBC
&lt;/h3&gt;

&lt;p&gt;Assuming we are using the PostgreSQL JDBC driver to connect to YugabyteDB, the construction of the connect string will be identical to PostgreSQL. For example here’s a snippet for setting up a connection to a database called "northwind" in YugabyteDB using the PostgreSQL driver in Spring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.datasource.url=jdbc:postgresql://11.22.33.44:5433/northwind
spring.datasource.username=yugabyte
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database=POSTGRESQL
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In the example above we assume YugabyteDB’s YSQL API is being accessed at 11.22.33.44 on the default port 5433, using the default user “yugabyte” with the password “password”. For more information about YugabyteDB connectivity options check out the &lt;a href="https://docs.yugabyte.com/latest/reference/drivers/" rel="noopener noreferrer"&gt;Drivers&lt;/a&gt; section of the documentation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Up Users in YugabyteDB
&lt;/h1&gt;

&lt;p&gt;Creating roles/users, and assigning them privileges and passwords is going to be the same in YugabyteDB as it is in PostgreSQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Role with Privileges
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE ROLE felix LOGIN;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Role with a Password
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER felix2 WITH PASSWORD ‘password’;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Role with a Password That Will Expire in the Future
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE ROLE felix3 WITH LOGIN PASSWORD 'password' VALID UNTIL '2020-09-30';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Change a User’s Password
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER ROLE felix WITH PASSWORD 'newpassword';
List All the Users
\du
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information about how YugabyteDB handles users, permissions, security, and encryption check out the &lt;a href="https://docs.yugabyte.com/latest/secure/" rel="noopener noreferrer"&gt;Secure&lt;/a&gt; section of the documentation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating Databases and Schemas in YugabyteDB
&lt;/h1&gt;

&lt;p&gt;Creating databases and schemas in YugabyteDB is identical to how it is done in PostgreSQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Database
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Switch to a Database
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Describe the Database
&lt;/h3&gt;



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

                 List of relations
 Schema |          Name          | Type  |  Owner   
--------+------------------------+-------+----------
 public | categories             | table | yugabyte
 public | customer_customer_demo | table | yugabyte
 public | customer_demographics  | table | yugabyte
 public | customers              | table | yugabyte
 public | employee_territories   | table | yugabyte
 public | employees              | table | yugabyte
 public | order_details          | table | yugabyte
 public | orders                 | table | yugabyte
 public | products               | table | yugabyte
 public | region                 | table | yugabyte
 public | shippers               | table | yugabyte
 public | suppliers              | table | yugabyte
 public | territories            | table | yugabyte
 public | us_states              | table | yugabyte
(14 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Schema
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Schema for a Specific User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE SCHEMA AUTHORIZATION felix;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Objects and Load Data from External Files
&lt;/h3&gt;

&lt;p&gt;If you have DDL or DML scripts that you want to call from within the YSQL shell, the process is the same in YugabyteDB as it is in PostgreSQL. You can find the scripts used in the examples below in the "~/yugabyte-2.3.x.x/share" directory. For information about the sample data sets that ship by default with YugabyteDB, check out the &lt;a href="https://docs.yugabyte.com/latest/sample-data/" rel="noopener noreferrer"&gt;Sample Datasets&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Call an External File to Create Objects
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\i 'northwind_ddl.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F10%2F1-Call-an-external-file-to-create-objects.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F10%2F1-Call-an-external-file-to-create-objects.png" alt="Call an external file to create objects, PostgreSQL YugabyteDB Compatibility tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Call an External File to Load Data into the Objects
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\i 'northwind_data.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F10%2F2-Call-an-external-file-to-load-data-into-the-objects-1024x279.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F10%2F2-Call-an-external-file-to-load-data-into-the-objects-1024x279.png" alt="postgresql and yugabytedb compatibility, Call an external file to load data into the objects" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What’s Next?
&lt;/h1&gt;

&lt;p&gt;Stay tuned for part 2 in this series where we’ll dive into querying data from a YugabyteDB cluster using familiar PostgreSQL syntax.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>yugabytedb</category>
      <category>sql</category>
    </item>
    <item>
      <title>Version Control for Distributed SQL with Flyway’s Maven Plugin</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Wed, 30 Sep 2020 18:01:38 +0000</pubDate>
      <link>https://dev.to/yugabyte/version-control-for-distributed-sql-with-flyway-s-maven-plugin-5a0g</link>
      <guid>https://dev.to/yugabyte/version-control-for-distributed-sql-with-flyway-s-maven-plugin-5a0g</guid>
      <description>&lt;p&gt;&lt;a href="https://flywaydb.org/" rel="noopener noreferrer"&gt;Flyway&lt;/a&gt; is an open source database version control and migration tool that stresses simplicity and convention over configuration. Changes to the database can be written in SQL (and in some database-specific dialects like PL/SQL and T-SQL) or Java. You interact with Flyway using a command-line client, however there are a variety of plugins that can be leveraged, including Maven, Gradle, Spring Boot, and more.&lt;/p&gt;

&lt;p&gt;Supported databases include Oracle, SQL Server, DB2, MySQL, PostgreSQL, and others. Because YugabyteDB is PostgreSQL compatible, most third-party tools and apps will work “out of the box.” Flyway is no exception here. This allows developers to deploy and rollback schema changes to YugabyteDB using Flyway by making use of the PostgreSQL JDBC driver.&lt;/p&gt;

&lt;p&gt;Flyway relies on seven commands to manage database version control.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Migrate:&lt;/strong&gt; Migrates the schema to the latest version. Flyway will create the schema history table automatically if it doesn’t exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean:&lt;/strong&gt; Drops all objects in the configured schemas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Info:&lt;/strong&gt; Prints the details and status information about all the migrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate:&lt;/strong&gt; Validates the applied migrations against the available ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undo:&lt;/strong&gt; Undoes the most recently applied versioned migration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baseline:&lt;/strong&gt; Baselines an existing database, excluding all migrations up to and including baselineVersion.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repair:&lt;/strong&gt; Repairs the schema history table.&lt;br&gt;
In this blog post we’ll walk you though the following steps:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install a 3 node YugabyteDB cluster on Google Kubernetes Platform&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install and configure Flyway locally to work with YugabyteDB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to run migrations using the Maven plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or to cloud native environments. This is often motivated by the desire to reduce TCO or move away from the scaling limitations of monolithic RDBMS like Oracle, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL API for querying and modeling data, with support for traditional RDBMS features like primary keys, foreign keys, indexes, stored procedures, and triggers.&lt;/li&gt;
&lt;li&gt;Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/li&gt;
&lt;li&gt;A distributed SQL database should support automatically distributed data storage. This includes indexes which should be automatically distributed (aka sharded) across multiple nodes of the cluster so that no single node becomes a bottleneck for ensuring high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.
For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;YugabyteDB is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible with support for advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Ok, on with the demo…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on a GKE Cluster using Helm 3
&lt;/h1&gt;

&lt;p&gt;In this section we are going to install YugabyteDB on the cluster. The complete steps are documented &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/oss/helm-chart/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We’ll assume you already have a GKE cluster up and running as a starting point.&lt;/p&gt;

&lt;p&gt;The first thing to do is to add the charts repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo add yugabytedb https://charts.yugabyte.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, fetch the updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a namespace. In this case we’ll call it "yb-demo".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace/yb-demo created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to install YugabyteDB. In the command below we’ll be specifying values for a resource constrained environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm install yb-demo yugabytedb/yugabyte \
--set resource.master.requests.cpu=1,resource.master.requests.memory=1Gi,\
resource.tserver.requests.cpu=1,resource.tserver.requests.memory=1Gi,\
enableLoadBalancer=True --namespace yb-demo --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the status of the cluster, execute the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Note-the-external-IP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Note-the-external-IP.png" alt="Note the external IP, to establish a connection between YugabyteDB and Flyway" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the external-IP for yb-tserver-service which we are going to use to establish a connection between YugabyteDB and Flyway. From the screenshot above we can see that the IP is 35.224.XX.XX and the YSQL port is 5433.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Creating the Northwind sample database
&lt;/h1&gt;

&lt;p&gt;The next step is to download a sample schema and data. You can find a variety of sample databases that are compatible with YugabyteDB in our &lt;a href="https://docs.yugabyte.com/latest/sample-data/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;. For the purposes of this tutorial we are going to use the &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; sample database. The Northwind database contains the sales data for a fictitious company called “Northwind Traders,” which imports and exports specialty foods from around the world. The Northwind database is an excellent tutorial schema for a small-business ERP, with customers, orders, inventory, purchasing, suppliers, shipping, employees, and single-entry accounting.&lt;/p&gt;

&lt;p&gt;Connect to the "yb-tserver-pod" 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;$ kubectl exec -n yb-demo -it yb-tserver-0 /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download the schema and data files, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_ddl.sql

$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_data.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect to the YSQL service exit out of the pod shell and 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;$ exit
$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE northwind;
northwind=# \c northwind;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now create the database objects and load them with data using the files we downloaded to "yb-tserver-pod" using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# \i 'northwind_ddl.sql';
northwind=# \i 'northwind_data.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that the tables are created 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;northwind-# \d

                 List of relations
 Schema |          Name          | Type  |  Owner
--------+------------------------+-------+----------
 public | categories             | table | yugabyte
 public | customer_customer_demo | table | yugabyte
 public | customer_demographics  | table | yugabyte
 public | customers              | table | yugabyte
 public | employee_territories   | table | yugabyte
 public | employees              | table | yugabyte
 public | order_details          | table | yugabyte
 public | orders                 | table | yugabyte
 public | products               | table | yugabyte
 public | region                 | table | yugabyte
 public | shippers               | table | yugabyte
 public | suppliers              | table | yugabyte
 public | territories            | table | yugabyte
 public | us_states              | table | yugabyte
(14 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify we have data by issuing a simple SELECT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# SELECT count(*) FROM products;
 count
-------
    77
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default "yugabyte" user. Specifying one is done the same way you’d do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# ALTER ROLE yugabyte WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Install and configure Flyway
&lt;/h1&gt;

&lt;p&gt;For the purposes of this demo we’ll be installing and configuring Flyway Community Edition. After &lt;a href="https://flywaydb.org/download/" rel="noopener noreferrer"&gt;downloading Flyway&lt;/a&gt;, navigate to the flyway-6.5.2 directory. We are going to want to make a few configuration changes to get Flyway connected to the YugabyteDB database we just deployed.&lt;/p&gt;

&lt;p&gt;In the conf directory locate the flyway.conf file. Uncomment or modify the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flyway.url=jdbc:postgresql://35.224.XX.XX:5433/northwind
flyway.user=yugabyte
flyway.password=password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point Flyway will be able to connect to YugabyteDB running on GKE.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create a project
&lt;/h1&gt;

&lt;p&gt;Create a basic project using the Maven Archetype Plugin by issuing 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;$ mvn archetype:generate -B \
    -DarchetypeGroupId=org.apache.maven.archetypes \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DarchetypeVersion=1.1 \
    -DgroupId=foo \
    -DartifactId=bar \
    -Dversion=1.0-SNAPSHOT \
    -Dpackage=foobar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see a project structure similar to the one below in your IDE of choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-project-structure-example-in-your-IDE-of-choice.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-project-structure-example-in-your-IDE-of-choice.png" alt="See a project in the IDE of your choice YugabyteDB Flyway Maven tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Configure the Flyway integration
&lt;/h1&gt;

&lt;p&gt;Edit the pom.xml and add entries for the Flyway plugin, YugabyteDB (PostgreSQL) connectivity, and PostgreSQL Driver.&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;plugins&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.flywaydb&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;flyway-maven-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;6.5.2&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
         &amp;lt;url&amp;gt;jdbc:postgresql://XX.XX.XX.XX:5433/northwind&amp;lt;/url&amp;gt;
          &amp;lt;user&amp;gt;yugabyte&amp;lt;/user&amp;gt;
          &amp;lt;password&amp;gt;password&amp;lt;/password&amp;gt;
        &amp;lt;/configuration&amp;gt;
        &amp;lt;dependencies&amp;gt;
          &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.postgresql&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;postgresql&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;42.2.2&amp;lt;/version&amp;gt;
          &amp;lt;/dependency&amp;gt;
        &amp;lt;/dependencies&amp;gt;
      &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There are few other configuration options when it comes to Flyway and Maven. You can find them detailed in the &lt;a href="https://flywaydb.org/documentation/maven/" rel="noopener noreferrer"&gt;Flyway Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Create table migration
&lt;/h1&gt;

&lt;p&gt;Create the migration directory ~bar/src/main/resources/db/migration to hold our SQL scripts.&lt;/p&gt;

&lt;p&gt;Create a SQL script in this directory with the following content named V1__create_promotions_table.sql.&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 promotions (
    promotion_id serial PRIMARY KEY,
    supplier_id int2 NOT NULL,
    promotion_name VARCHAR ( 50 ) NOT NULL,
    company_name VARCHAR ( 40 ) NOT NULL,
    start_date DATE NOT NULL,
    stop_date DATE NOT NULL,
    created_on DATE NOT NULL DEFAULT CURRENT_DATE
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-create-a-script-in-the-directory-yugabytedb-flyway-maven-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-create-a-script-in-the-directory-yugabytedb-flyway-maven-example.png" alt="Create a SQL script example YugabyteDB Flyway Maven example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now execute this migration at 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;$ cd /bar
$ mvn flyway:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-execute-this-migration-at-the-command-line-1024x432.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-execute-this-migration-at-the-command-line-1024x432.png" alt="create table migration yugabytedb flyway maven tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can verify that the "promotions" table was indeed built.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-verify-that-the-promotions-table-was-built.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-verify-that-the-promotions-table-was-built.png" alt="Verify that the table was built, step in the YugabyteDB Flyway Maven tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We should also be able to see this migration in the "flyway_schema_history" table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-see-this-migration-in-the-flyway_schema_history-table-1024x47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-see-this-migration-in-the-flyway_schema_history-table-1024x47.png" alt="Verify creation of table in the flyway schema history yugabytedb maven example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Insert data migration
&lt;/h1&gt;

&lt;p&gt;Create the SQL script below, place it in the migration directory with the following and name it "V2__insert_promotions.sql".&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 promotions (supplier_id, promotion_name, company_name, start_date, stop_date, created_on)
VALUES
('28','Buy One Get One Free', 'Gai pâturage', '1996-08-15', '1996-08-30', CURRENT_DATE),
('19', 'Free Shipping', 'New England Seafood Cannery', '1996-10-15', '1996-10-30', CURRENT_DATE),
('16', 'Free T-Shirt With Every Purchase', 'Bigfoot Breweries', '1996-12-15', '1996-12-30', CURRENT_DATE),
('20','10% Off', 'Gula Malacca', '1996-11-15', '1996-11-30', CURRENT_DATE),
('8', '20% Off', 'Specialty Biscuits, Ltd.', '1996-09-15', '1996-09-30', CURRENT_DATE);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F8-create-sql-script-to-insert-promotions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F8-create-sql-script-to-insert-promotions.png" alt="Insert promotions SQL script, flyway maven yugabyte db example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now execute this migration at 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;$ mvn flyway:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F9-execute-migration-flyway-maven-yugabytedb-example-1024x437.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F9-execute-migration-flyway-maven-yugabytedb-example-1024x437.png" alt="command line view migration flyway yugabytedb and maven tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s verify that the data was inserted into the "promotions" table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F10-verify-promotions-inserted-1024x146.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F10-verify-promotions-inserted-1024x146.png" alt="verify promotions were inserted yugabytedb maven plugin for flyway tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We should also be able to see this migration in the "flyway_schema_history" table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F11-verify-inserts-in-flyway-version-control-1024x58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F11-verify-inserts-in-flyway-version-control-1024x58.png" alt="verify in flyway version control, using maven plugin and yugabytedb" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it! You now have a 3 node YugabyteDB cluster on GKE, with versioning control managed by a local installation of Flyway. For more information about how to perform more advanced operations in Flyway using the Java API, Maven, or Gradle, check out their &lt;a href="https://flywaydb.org/documentation/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>maven</category>
      <category>flyway</category>
      <category>database</category>
    </item>
    <item>
      <title>Getting Started with IntelliJ IDEA and Distributed SQL</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Tue, 29 Sep 2020 22:52:43 +0000</pubDate>
      <link>https://dev.to/yugabyte/getting-started-with-intellij-idea-and-distributed-sql-fa5</link>
      <guid>https://dev.to/yugabyte/getting-started-with-intellij-idea-and-distributed-sql-fa5</guid>
      <description>&lt;p&gt;&lt;a href="https://www.jetbrains.com/idea/" rel="noopener noreferrer"&gt;IntelliJ IDEA&lt;/a&gt; is a popular integrated development environment (IDE) written in Java for developing software. It is developed by JetBrains and is available as an Apache 2 licensed community edition and in a proprietary commercial edition. IntelliJ supports a variety of datasources within their IDE. Because YugabyteDB is PostgreSQL compatible, most third-party tools and apps will work “out of the box.” IntelliJ is no exception here.&lt;/p&gt;

&lt;p&gt;In this blog post we’ll walk you though the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install a 3 node YugabyteDB cluster on Google Kubernetes Engine&lt;/li&gt;
&lt;li&gt;Install the Northwind sample database&lt;/li&gt;
&lt;li&gt;Configure IntelliJ to work with YugabyteDB&lt;/li&gt;
&lt;li&gt;Test out some basic IntelliJ database features with YugabyteDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or cloud native environments. This is often motivated by the desire to reduce TCO or move away from the horizontal scaling limitations of monolithic RDBMS like Oracle, PostgreSQL, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They must have a SQL API for querying and modeling data, with support for traditional RDBMS features like foreign keys, partial indexes, stored procedures and triggers.&lt;/li&gt;
&lt;li&gt;Smart distributed query execution so that query processing is pushed closer to the data as opposed to data being pushed over the network and thus slowing down query response times.&lt;/li&gt;
&lt;li&gt;Should support automatic and transparent distributed data storage. This includes indexes which should be sharded across multiple nodes of the cluster so that no single node becomes a bottleneck. Data distribution ensures high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What’s YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. &lt;strong&gt;YugabyteDB is PostgreSQL wire compatible&lt;/strong&gt;, cloud native, offers deep integration with GraphQL projects, plus supports advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Got questions? Make sure to ask them in our YugabyteDB Slack channel. Ok, let’s dive in…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on a GKE Cluster using Helm 3
&lt;/h1&gt;

&lt;p&gt;In this section we are going to install YugabyteDB on the cluster. The complete steps are documented &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/oss/helm-chart/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We’ll assume you already have a GKE cluster up and running as a starting point.&lt;/p&gt;

&lt;p&gt;The first thing to do is to add the charts repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo add yugabytedb https://charts.yugabyte.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, fetch the updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a namespace. In this case we’ll call it yb-demo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace/yb-demo created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to install YugabyteDB. In the command below we’ll be specifying values for a resource constrained environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm install yb-demo yugabytedb/yugabyte \
--set resource.master.requests.cpu=1,resource.master.requests.memory=1Gi,\
resource.tserver.requests.cpu=1,resource.tserver.requests.memory=1Gi,\
enableLoadBalancer=True --namespace yb-demo --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the status of the cluster, execute the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-check-the-status-of-the-cluster-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-check-the-status-of-the-cluster-1.png" alt="IP to establish connection between yugabytedb and intellij tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the external-IP for yb-tserver-service which we are going to use to establish a connection between YugabyteDB and IntelliJ. From the screenshot above we can see that the IP is &lt;strong&gt;35.224.XX.XX&lt;/strong&gt; and the YSQL port is &lt;strong&gt;5433&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the Northwind sample database
&lt;/h1&gt;

&lt;p&gt;The next step is to download a sample schema and data. You can find a variety of sample databases that are compatible with YugabyteDB in our &lt;a href="https://docs.yugabyte.com/latest/sample-data/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;. For the purposes of this tutorial we are going to use the &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; sample database. The Northwind database contains the sales data for a fictitious company called “Northwind Traders,” which imports and exports specialty foods from around the world. The Northwind database is an excellent tutorial schema for a small-business ERP, with customers, orders, inventory, purchasing, suppliers, shipping, employees, and single-entry accounting.&lt;/p&gt;

&lt;p&gt;Connect to the &lt;strong&gt;yb-tserver-pod&lt;/strong&gt; 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;$ kubectl exec -n yb-demo -it yb-tserver-0 /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download the schema and data files, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_ddl.sql

$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_data.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect to the YSQL service exit out of the pod shell and 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;$ exit

$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE northwind;
northwind=# \c northwind;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now create the database objects and load them with data using the files we downloaded to &lt;strong&gt;yb-tserver-pod&lt;/strong&gt; using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# \i 'northwind_ddl.sql';
northwind=# \i 'northwind_data.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that the tables are created 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;northwind-# \d

                 List of relations
 Schema |          Name          | Type  |  Owner
--------+------------------------+-------+----------
 public | categories             | table | yugabyte
 public | customer_customer_demo | table | yugabyte
 public | customer_demographics  | table | yugabyte
 public | customers              | table | yugabyte
 public | employee_territories   | table | yugabyte
 public | employees              | table | yugabyte
 public | order_details          | table | yugabyte
 public | orders                 | table | yugabyte
 public | products               | table | yugabyte
 public | region                 | table | yugabyte
 public | shippers               | table | yugabyte
 public | suppliers              | table | yugabyte
 public | territories            | table | yugabyte
 public | us_states              | table | yugabyte
(14 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify we have data by issuing a simple SELECT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# SELECT count(*) FROM products;
 count
-------
    77
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default yugabyte user. Specifying one is done the same way you’d do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# ALTER ROLE yugabyte WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Configure IntelliJ to work with YugabyteDB
&lt;/h1&gt;

&lt;p&gt;Launch the Database tool window. (View &amp;gt; Tool Windows &amp;gt; Database)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Launch-the-DB-tool-IntelliJ-YugabyteDB-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Launch-the-DB-tool-IntelliJ-YugabyteDB-example.png" alt="launch the database step, IntelliJ and YugabyteDB tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a PostgreSQL data source. (New (+) &amp;gt; Data Source &amp;gt; PostgreSQL)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-Add-a-PostgreSQL-data-source.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-Add-a-PostgreSQL-data-source.png" alt="Add a PostgreSQL data source, IntelliJ and YugabyteDB example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;General&lt;/strong&gt; tab, enter your database’s connection string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Host:&lt;/strong&gt; The external IP that GKE assigned to YugabyteDB in the previous step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port:&lt;/strong&gt; YugabyteDB uses port 5433&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; For our purposes we’ll be connecting to northwind sample database we created in the previous step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User:&lt;/strong&gt; The default YugabyteDB user is yugabyte&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password:&lt;/strong&gt; We’ll use the password password, which we assigned to the default user in the previous step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Driver:&lt;/strong&gt; Select or install the latest PostgreSQL driver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-enter-your-database-connection-string.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-enter-your-database-connection-string.png" alt="Enter your database connection string, IntelliJ YugabyteDB example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For good measure, make sure to test the connect before clicking “Ok.”&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Run a sample query
&lt;/h1&gt;

&lt;p&gt;Next, let’s test the integration by executing the following query in IntelliJ.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-test-the-integration-by-executing-the-following-query-in-IntelliJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-test-the-integration-by-executing-the-following-query-in-IntelliJ.png" alt="IntelliJ YugabyteDB tutorial,  test the integration by executing the following query in IntelliJ" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the output window we should see the following result set.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-In-the-output-window-we-should-see-the-following-result-set-1024x428.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-In-the-output-window-we-should-see-the-following-result-set-1024x428.png" alt="Output example IntelliJ YugabyteDB tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Generate an EXPLAIN PLAN
&lt;/h1&gt;

&lt;p&gt;IntelliJ has the built-in ability to generate EXPLAIN visualizations of your queries. For example, we can get the visualization for our last query by selecting Explain Plan &amp;gt; Show Visualization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-EXPLAIN-visualizations-of-your-queries.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-EXPLAIN-visualizations-of-your-queries.png" alt="get the visualization for our last query by selecting Explain Plan &amp;gt; Show Visualization IntelliJ and YugabyteDB tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Not all of IntelliJ’s database management features are supported with YugabyteDB. If you run into any issues, make sure to drop by our Slack channel and let us know, or you can always open up a GitHub issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it! You now have a 3 node YugabyteDB cluster on GKE, with the sample Northwind database that you can develop against in IntelliJ. For more information about how to work with databases in IntelliJ, check out the &lt;a href="https://www.jetbrains.com/help/idea/relational-databases.html" rel="noopener noreferrer"&gt;IntelliJ documentation&lt;/a&gt;. For more 3rd party integrations that work with YugabyteDB, check out the &lt;a href="https://docs.yugabyte.com/latest/tools/" rel="noopener noreferrer"&gt;YugabyteDB Documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>sql</category>
      <category>kubernetes</category>
      <category>yugabytedb</category>
    </item>
    <item>
      <title>Use Retool to Quickly Build Distributed SQL and React Apps</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Thu, 24 Sep 2020 19:40:25 +0000</pubDate>
      <link>https://dev.to/yugabyte/use-retool-to-quickly-build-distributed-sql-and-react-apps-f3m</link>
      <guid>https://dev.to/yugabyte/use-retool-to-quickly-build-distributed-sql-and-react-apps-f3m</guid>
      <description>&lt;p&gt;&lt;a href="https://retool.com/" rel="noopener noreferrer"&gt;Retool&lt;/a&gt; is a next generation WSIWYG SaaS-based tool that enables you to quickly build React applications for internal consumption from your existing data sources using a variety of pre-built “building blocks.” Developers can choose from over 58 drag and drop components and combine them with custom JavaScript to create applications that can be securely deployed on-premise or hosted environments like Heroku. Retool supports over 30 native integrations including PostgreSQL, GraphQL, AWS S3, and Cassandra. Because YugabyteDB is PostgreSQL compatible, most third-party PostgreSQL tools and apps will work “out of the box.” Retool is no exception here.&lt;/p&gt;

&lt;p&gt;In this blog post we’ll walk you though the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install a 3 node YugabyteDB cluster on Google Kubernetes Platform&lt;/li&gt;
&lt;li&gt;Build the Northwind sample database&lt;/li&gt;
&lt;li&gt;Configure Retool to connect to YugabyteDB via the PostgreSQL driver&lt;/li&gt;
&lt;li&gt;Build a simple React application on top of the Northwind database to help us manage inventory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or to cloud native environments. This is often motivated by the desire to reduce TCO or move away from the scaling limitations of monolithic RDBMS like Oracle, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL API for querying and modeling data, with support for traditional RDBMS features like primary keys, foreign keys, indexes, stored procedures, and triggers.&lt;/li&gt;
&lt;li&gt;Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/li&gt;
&lt;li&gt;A distributed SQL database should support automatically distributed data storage. This includes indexes which should be automatically distributed (aka sharded) across multiple nodes of the cluster so that no single node becomes a bottleneck for ensuring high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.
For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible with support for advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Ok, on with the demo…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on a GKE Cluster using Helm 3
&lt;/h1&gt;

&lt;p&gt;In this section we are going to install YugabyteDB on the cluster. The complete steps are documented &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/oss/helm-chart/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We’ll assume you already have a GKE cluster up and running as a starting point.&lt;/p&gt;

&lt;p&gt;The first thing to do is to add the charts repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo add yugabytedb https://charts.yugabyte.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, fetch the updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a namespace. In this case we’ll call it yb-demo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace/yb-demo created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to install YugabyteDB. In the command below we’ll be specifying values for a resource constrained environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm install yb-demo yugabytedb/yugabyte \
--set resource.master.requests.cpu=1,resource.master.requests.memory=1Gi,\
resource.tserver.requests.cpu=1,resource.tserver.requests.memory=1Gi,\
enableLoadBalancer=True --namespace yb-demo --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the status of the cluster, execute the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-check-the-status-of-the-cluster.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-check-the-status-of-the-cluster.png" alt="check the status of your yugabyte cluster retool demo blog" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the external-IP for yb-tserver-service which we are going to use to establish a connection between YugabyteDB and Flyway. From the screenshot above we can see that the IP is &lt;code&gt;130.211.XX.XX&lt;/code&gt; and the YSQL port is &lt;code&gt;5433&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Creating the Northwind sample database
&lt;/h1&gt;

&lt;p&gt;The next step is to download a sample schema and data. You can find a variety of sample databases that are compatible with YugabyteDB &lt;a href="https://docs.yugabyte.com/latest/sample-data/" rel="noopener noreferrer"&gt;in our Docs&lt;/a&gt;. For the purposes of this tutorial we are going to use the Northwind sample database. The &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; database contains the sales data for a fictitious company called “Northwind Traders,” which imports and exports specialty foods from around the world. The Northwind database is an excellent tutorial schema for a small-business ERP, with customers, orders, inventory, purchasing, suppliers, shipping, employees, and single-entry accounting.&lt;/p&gt;

&lt;p&gt;Connect to the yb-tserver-pod 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;$ kubectl exec -n yb-demo -it yb-tserver-0 /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download the schema and data files, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_ddl.sql
$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_data.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect to the YSQL service exit out of the pod shell and 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;$ exit 
$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE northwind;
northwind=# \c northwind;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now create the database objects and load them with data using the files we downloaded to &lt;code&gt;yb-tserver-pod&lt;/code&gt; using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# \i 'northwind_ddl.sql';
northwind=# \i 'northwind_data.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that the tables are created 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;northwind-# \d

                 List of relations
 Schema |          Name          | Type  |  Owner
--------+------------------------+-------+----------
 public | categories             | table | yugabyte
 public | customer_customer_demo | table | yugabyte
 public | customer_demographics  | table | yugabyte
 public | customers              | table | yugabyte
 public | employee_territories   | table | yugabyte
 public | employees              | table | yugabyte
 public | order_details          | table | yugabyte
 public | orders                 | table | yugabyte
 public | products               | table | yugabyte
 public | region                 | table | yugabyte
 public | shippers               | table | yugabyte
 public | suppliers              | table | yugabyte
 public | territories            | table | yugabyte
 public | us_states              | table | yugabyte
(14 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify we have data by issuing a simple &lt;code&gt;SELECT&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;northwind=# SELECT count(*) FROM products;
 count
-------
    77
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default &lt;code&gt;yugabyte&lt;/code&gt; user. Specifying one is done the same way you’d do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# ALTER ROLE yugabyte WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Configure Retool with YugabyteDB using the Native PostgreSQL Integration
&lt;/h1&gt;

&lt;p&gt;First, head on over to &lt;a href="https://retool.com/" rel="noopener noreferrer"&gt;https://retool.com/&lt;/a&gt; and sign up for the service. Next we’ll work through the wizard to set up our first project, which will be a simple application to help us manage inventory in the Northwind database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Select the PostgreSQL resource
&lt;/h2&gt;

&lt;p&gt;Recall that YugabyteDB is PostgreSQL-compatible and as far as Retool is concerned, it “thinks” it is connecting to a PostgreSQL database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Select-Postgres-resource-type.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-Select-Postgres-resource-type.png" alt="Select Postgres resource type in Retool demo example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Connectivity
&lt;/h2&gt;

&lt;p&gt;Note that we are using the external IP and port number of YugabyteDB detailed in Step 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-Edit-details.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F3-Edit-details.png" alt="Use the IP from step 1 YugabyteDB Distributed SQL and Retool Postgres compatibility demo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test the connection. If successful, proceed to creating an app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-Proceed-to-create-an-app.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F4-Proceed-to-create-an-app.png" alt="Continue to create app Retool YugabyteDB distributed sql demo example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create the Inventory Dashboard with Retool
&lt;/h1&gt;

&lt;p&gt;We are now ready to build a simple React application for our “buyer” to easily search and add new products to the Northwind database. Retool ships with a couple of templates that you can use to learn how the product works or to use a starting point for building your app. I went ahead and took their eCommerce Management sample app and tweaked it for my purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Product Search
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-Inventory-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F5-Inventory-dashboard.png" alt="Create inventory dashboard retool yugabytedb example demo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this particular feature I wanted to make it easy for a “buyer” to search for products so they could check inventory levels.&lt;/p&gt;

&lt;p&gt;To build this feature I used the “Table” component which displays tabular data with pagination. I then assigned this component the required connectivity and the necessary SQL query to retrieve the data in the &lt;code&gt;products&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 products where product_name ilike {{ '%' + product_name_input.value + '%' }} order by product_id desc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although there are a ton of additional options you can specify, I kept it simple for the purposes of this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-assign-connectivity-and-sql-query-to-retrieve-data-simple.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F6-assign-connectivity-and-sql-query-to-retrieve-data-simple.png" alt="table component simple options configured for retool yugabytedb demo tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next component I configured is the “Text Input” component which controls other components or queries with text. A few things to note here in the configuration of this component are that the input type must be “text”, the placeholder text is “Search by name…” and when you submit the text it should trigger the “products” component that we configured in the previous step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-configure-input-type.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F7-configure-input-type.png" alt="Configure text input retool yugabytedb tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add New Product
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F8-AddNewProduct-1024x371.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F8-AddNewProduct-1024x371.png" alt="create add new product component yugabytedb retool tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next feature I wanted to build is one that made it easy to add new products to the Northwind database. To accomplish this I again made use of the “Text Input” component, specified the resource to connect to and the columns that would make up the changeset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F9-use-text-input-and-make-add-product-feature.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F9-use-text-input-and-make-add-product-feature.png" alt="create new add product feature retool yugabyted postgres compatible demo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, here are the details concerning the &lt;code&gt;product_name&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F10-details-re-product-name-field.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F10-details-re-product-name-field.png" alt="details regarding product name field yugabytedb retool tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we’ll want to use the “Form” component to enable a “Add Product” button that will submit all of the text input fields via the “add_product” query we just configured.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F11-form-to-add-product-to-table.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F11-form-to-add-product-to-table.png" alt="form to add product info retool yugabytedb example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, there are a ton of additional options you can specify, but for the purposes of this tutorial I chose to keep it simple.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Test the Inventory Dashboard
&lt;/h1&gt;

&lt;p&gt;We are now ready to test our application. An easy way to do this is to click on the “Share” button on the upper right-hand corner of the Retool UI and share the app via the “Public Access Link.” I’d recommend enabling password protection. We should now be able to interact with our application in our favorite browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F12-test-app-in-our-favorite-browser-1024x791.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F12-test-app-in-our-favorite-browser-1024x791.png" alt="retool yugabytedb example ready to test app in browser" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s find the inventory levels for products which have “lager” in their names. We input the text and click enter. We get two results back from the Northwind database. Looks like the product search feature is working as intended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F13-test-products-that-have-lager-in-name-1024x248.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F13-test-products-that-have-lager-in-name-1024x248.png" alt="example query scenario yugabytedb retool" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next let’s add a new product to the Northwind database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F14-test-add-new-product.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F14-test-add-new-product.png" alt="test add new product to northwind database retool yugabytedb tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking on the “Add Product” button, let’s verify that our new product is now in inventory by searching for products with “soda” in their name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F15-super-awesome-soda-pop-1024x137.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F15-super-awesome-soda-pop-1024x137.png" alt="check for inventory in yugabytedb retool tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like “Super Awesome Soda Pop” is now in our inventory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; We can now also access our inventory app from a mobile device using the same URL. Although not perfect, it is “mobile friendly” enough for our purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F16-mobile-friendly-576x1024.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.yugabyte.com%2Fwp-content%2Fuploads%2F2020%2F09%2F16-mobile-friendly-576x1024.png" alt="demo app is mobile friendly retool yugabytedb tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it! You now have a 3 node YugabyteDB cluster on GKE, with the sample Northwind database and simple inventory application that was built in just a few minutes using Retool.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>distributedsystems</category>
      <category>yugabytedb</category>
    </item>
    <item>
      <title>Distributed SQL Tips and Tricks for PostgreSQL and Oracle DBAs – Sep 9, 2020</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Wed, 09 Sep 2020 21:48:54 +0000</pubDate>
      <link>https://dev.to/yugabyte/distributed-sql-tips-and-tricks-for-postgresql-and-oracle-dbas-sep-9-2020-4i36</link>
      <guid>https://dev.to/yugabyte/distributed-sql-tips-and-tricks-for-postgresql-and-oracle-dbas-sep-9-2020-4i36</guid>
      <description>&lt;p&gt;Welcome to this week’s tips and tricks blog where we explore both beginner and advanced YugabyteDB topics for PostgreSQL and Oracle DBAs. First things first, for those of you who might be new to either distributed SQL or YugabyteDB read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or to cloud native environments. This is often motivated by the desire to reduce TCO or move away from the scaling limitations of monolithic RDBMS like Oracle, MySQL and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL API for querying and modeling data, with support for traditional RDBMS features like primary keys, foregin keys, indexes, stored procedures, and triggers.&lt;/li&gt;
&lt;li&gt;Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/li&gt;
&lt;li&gt;A distributed SQL database should support automatically distributed data storage. This includes indexes which should be automatically distributed (aka sharded) across multiple nodes of the cluster so that no single node becomes a bottleneck for ensuring high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.
For a deeper discussion about what Distributed SQL is, check out, “What is Distributed SQL?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible with support for advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Got questions? Make sure to ask them in our YugabyteDB &lt;a href="https://www.yugabyte.com/slack" rel="noopener noreferrer"&gt;Slack channel&lt;/a&gt;. Please note that most examples in the post make use of the Northwind sample database. Instructions on how to get it installed are &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, let’s dive in…&lt;/p&gt;

&lt;h1&gt;
  
  
  Is there a functional equivalent to Oracle’s NVL in PostgreSQL or YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;In a nutshell, Oracle’s &lt;code&gt;NVL&lt;/code&gt; lets you replace &lt;code&gt;NULL&lt;/code&gt;, which returns as a blank in the results of a query with a string. For example, let’s say we want to return a list of our customers and for those that have &lt;code&gt;NULL&lt;/code&gt; in the &lt;code&gt;region&lt;/code&gt; column, swap in “Not Applicable.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT company_name, country, NVL(region, 'Not Applicable')
FROM customers
ORDER BY country;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-replace-null-with-not-applicable-postgresql-oracle-yugabytedb-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2F1-replace-null-with-not-applicable-postgresql-oracle-yugabytedb-example.png" alt="functional equivalent to Oracle’s NVL in PostgreSQL or YugabyteDB" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve similar results in PostgreSQL and YugabyteDB, we can use the &lt;code&gt;COALESCE&lt;/code&gt; function. So, to start, here’s the partial output of our &lt;code&gt;customers&lt;/code&gt; table. Note that Argentina, Austria and Belgium have &lt;code&gt;NULL&lt;/code&gt; in the region column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-similarly-in-postgresql-and-yugabytedb-use-the-coalesce-function.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2F2-similarly-in-postgresql-and-yugabytedb-use-the-coalesce-function.png" alt="the partial output of our customers table oracle postgresql yugabytedb coalesce example" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;COALESCE&lt;/code&gt; function we can make the swap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT company_name, country, COALESCE (region, 'Not Applicable')
FROM customers 
ORDER BY country;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fusing-coalesce-in-yugabytedb-and-postgresql-tutorial.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fusing-coalesce-in-yugabytedb-and-postgresql-tutorial.png" alt="using the coalesce function in yugabytedb and postgresql to swap null for not applicable" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Does YugabyteDB support PostgreSQL’s Views, Materialized Views, and Rollups?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;VIEW&lt;/code&gt; and &lt;code&gt;ROLLUP&lt;/code&gt; are supported, with materialized view support currently in development. You can track its development with this &lt;a href="https://github.com/YugaByte/yugabyte-db/issues/1131" rel="noopener noreferrer"&gt;GitHub issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;PostgreSQL’s views can be thought of as “virtual tables” that bring together data from one or more tables that can be queried against, just like a regular table. A materialized view on the other hand is not “virtual,” so we don’t have to recompute the view every time we want to access it. This makes materialized views much more efficient to query, with the trade offs of requiring additional storage and when there are updates to the base tables of the view, the materialized view must also be kept updated. &lt;/p&gt;

&lt;p&gt;Finally, PostgreSQL’s &lt;code&gt;ROLLUP&lt;/code&gt; is a subclause of &lt;code&gt;GROUP BY&lt;/code&gt; that allows us to define multiple grouping sets. This is especially useful in analytic use cases where you might want to “rollup” dates, monetary values or other types of data where some calculation might be useful. Let’s walk through each example.&lt;/p&gt;

&lt;p&gt;Creating a &lt;code&gt;VIEW&lt;/code&gt; in YugabyteDB is identical to how it is done in PostgreSQL. In this example, let’s create a &lt;code&gt;VIEW&lt;/code&gt; on the &lt;code&gt;customers&lt;/code&gt; and &lt;code&gt;orders&lt;/code&gt; table. In this scenario a &lt;code&gt;VIEW&lt;/code&gt; is useful because although the &lt;code&gt;customer_id&lt;/code&gt; column exists in both the &lt;code&gt;orders&lt;/code&gt; and &lt;code&gt;customers&lt;/code&gt; tables, &lt;code&gt;company_name&lt;/code&gt; does not exist in the &lt;code&gt;orders&lt;/code&gt; table. We want to make it super simple to get the order details and &lt;code&gt;customer_name&lt;/code&gt; associated with the order in one shot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE VIEW orders_by_company_name AS
SELECT orders.order_id, orders.order_date, customers.company_name, orders.ship_country
FROM orders, customers 
WHERE orders.customer_id = customers.customer_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now issue a simple &lt;code&gt;SELECT&lt;/code&gt; statement to retrieve just the data that we need.&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 orders_by_company_name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fcreating-a-view-in-yugabytedb-is-the-same-as-postgresql-1024x692.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fcreating-a-view-in-yugabytedb-is-the-same-as-postgresql-1024x692.png" alt="yugabytedb and postgresql compatibility - creating a view" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a &lt;code&gt;ROLLUP&lt;/code&gt; in YugabyteDB is identical to how it is done in PostgreSQL. For example, let’s say we want to “rollup” the data in our &lt;code&gt;orders&lt;/code&gt; table so that the data is grouped by &lt;code&gt;customer_id&lt;/code&gt; (who placed the order), &lt;code&gt;employee_id&lt;/code&gt; (who took the order), and the total sum of freight sent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
customer_id,    
COALESCE(employee_id, '0') as employee_id,
    SUM (freight) as "Rollup Sum of Freight by Customer and Employee"
FROM
    orders
GROUP BY
    ROLLUP (customer_id, employee_id)
ORDER BY customer_id, employee_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fcreating-a-rollup-is-the-same-in-yugabytedb-and-postgresql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F09%2Fcreating-a-rollup-is-the-same-in-yugabytedb-and-postgresql.png" alt="yugabytedb postgresql compatibility - creating a rollup" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the output above we can see that the result set sums the freight by &lt;code&gt;customer_id&lt;/code&gt; and &lt;code&gt;employee_id&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Does YugabyteDB support EXPLAIN ANALYZE?
&lt;/h1&gt;

&lt;p&gt;Yes. PostgreSQL’s &lt;code&gt;EXPLAIN&lt;/code&gt; is a useful tool for determining where potential performance tuning opportunities lie with queries being issued against the database. Adding the &lt;code&gt;ANALYZE&lt;/code&gt; option causes the statement to be actually executed, not only planned.&lt;/p&gt;

&lt;p&gt;Let’s issue a simple &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; against the &lt;code&gt;orders&lt;/code&gt; table in the &lt;code&gt;northwind&lt;/code&gt; sample database. In this example we are executing queries against a YugabyteDB cluster with a replication factor of 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EXPLAIN ANALYZE SELECT customer_id, order_id, ship_country 
FROM orders 
WHERE order_date BETWEEN '1997-01-01' and '1999-12-31';

QUERY PLAN                                                                                                 
----------
Foreign Scan on orders
(cost=0.00..105.00 rows=1000 width=82) 
(actual time=4.865..27.046 rows=678 loops=1)

Filter: ((order_date &amp;gt;= '1997-01-01'::date) AND (order_date &amp;lt;= '1999-12-31'::date)

Rows Removed by Filter: 152                                                                             
Planning Time: 31.899 ms                                                                                  
Execution Time: 29.078 ms 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s build an index on the &lt;code&gt;order_date&lt;/code&gt; column and see if we can’t shave some time off the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX idx_order_date 
ON orders(order_date ASC);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We execute the same query and get the following results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUERY PLAN                                                                                                                 
----------
Index Scan using idx_order_date on orders  
(cost=0.00..5.25 rows=10 width=82) 
(actual time=10.350..11.607 rows=678 loops=1)

Index Cond: ((order_date &amp;gt;= '1997-01-01'::date) AND (order_date &amp;lt;= '1999-12-31'::date))                                  
Planning Time: 13.608 ms                                                                                                   Execution Time: 11.913 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we are now able to confirm that by creating the index on the &lt;code&gt;order_date&lt;/code&gt; column we were able to make an improvement on our planning time and execution time. The delta in the example is not dramatic, but you get the idea. With more complex queries and larger datasets, &lt;code&gt;EXPLAIN&lt;/code&gt; and &lt;code&gt;ANALYZE&lt;/code&gt; become essential performance tuning tools.&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>postgres</category>
      <category>sql</category>
      <category>yugabyte</category>
    </item>
    <item>
      <title>Using Envoy Proxy’s PostgreSQL &amp; TCP Filters to Collect Yugabyte SQL Statistics</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Thu, 27 Aug 2020 23:28:37 +0000</pubDate>
      <link>https://dev.to/yugabyte/using-envoy-proxy-s-postgresql-tcp-filters-to-collect-yugabyte-sql-statistics-4o9</link>
      <guid>https://dev.to/yugabyte/using-envoy-proxy-s-postgresql-tcp-filters-to-collect-yugabyte-sql-statistics-4o9</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This is a cross post of my colleague &lt;a href="https://www.linkedin.com/in/sidchoudhury/" rel="noopener noreferrer"&gt;Sid Choundhury's&lt;/a&gt; blog that was originally published &lt;a href="https://blog.yugabyte.com/using-envoy-proxys-postgresql-tcp-filters-to-collect-yugabyte-sql-statistics/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Layer 7 proxies like NGINX and HAProxy have been popular since the mid-2000s. The term “proxy” refers to their role as an intermediary for the traffic between an application client and an application server. The “layer 7” classification comes from the fact that these proxies take routing decisions based on URLs, IPs, TCP/UDP ports, cookies, or any information present in messages sent over a &lt;a href="https://medium.com/@int0x33/day-51-understanding-the-osi-model-f22d5f3df756" rel="noopener noreferrer"&gt;layer 7 (aka application layer) networking protocol&lt;/a&gt; like HTTP and gRPC. Modern applications use these proxies for a variety of needs including load balancing, security, and web acceleration.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Envoy Proxy?
&lt;/h1&gt;

&lt;p&gt;Envoy is a layer 7 proxy and communication bus designed for large modern service oriented architectures. Its &lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;home page&lt;/a&gt; has the following definition:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally built at Lyft, Envoy is a high performance C++ distributed proxy designed for single services and applications, as well as a communication bus and “universal data plane” designed for large microservice “service mesh” architectures. Built on the learnings of solutions such as NGINX, HAProxy, hardware load balancers, and cloud load balancers, Envoy runs alongside every application and abstracts the network by providing common features in a platform-agnostic manner. When all service traffic in an infrastructure flows via an Envoy mesh, it becomes easy to visualize problem areas via consistent observability, tune overall performance, and add substrate features in a single place.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As the recently published &lt;a href="https://dropbox.tech/infrastructure/how-we-migrated-dropbox-from-nginx-to-envoy" rel="noopener noreferrer"&gt;Dropbox’s migration from NGINX&lt;/a&gt; to Envoy highlights, Envoy is rapidly becoming the default proxy for cloud native applications that need higher performance, observability, extensibility, security, building and testing, and last but not least, deep features (such as HTTP/2, gRPC, and egress proxying). It was the third CNCF project to reach the &lt;a href="https://www.cncf.io/announcement/2018/11/28/cncf-announces-envoy-graduation/" rel="noopener noreferrer"&gt;graduated status&lt;/a&gt;, following Kubernetes and Prometheus, and has gained widespread adoption in a relatively short period of time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why use Envoy’s PostgreSQL filter?
&lt;/h1&gt;

&lt;p&gt;Envoy supports configuration of multiple traffic listeners where each listener is composed of one or more filter chains. An individual filter chain is selected to process the incoming data based on the filter’s &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#envoy-v3-api-msg-config-listener-v3-filterchainmatch" rel="noopener noreferrer"&gt;match criteria&lt;/a&gt; (which includes connection parameters such as destination port/IP, transport protocol name, source port/IP, and more). When a new connection is received on a listener, the matching filter chain is selected and instantiated. The filters then begin processing subsequent events. This generic listener architecture is used to perform the vast majority of different proxy tasks that Envoy is used for including rate limiting, TLS client authentication, HTTP connection management, raw TCP proxy, and more. One such task relevant to database deployments is the ability to instrument the wire protocol of popular databases such as MySQL, MongoDB, Kafka, and Amazon DynamoDB. PostgreSQL was missing from this list but the latest &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.15.0" rel="noopener noreferrer"&gt;v1.15&lt;/a&gt; release from July 2020 solved that problem by adding a &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_protocols/postgres" rel="noopener noreferrer"&gt;PostgreSQL proxy filter&lt;/a&gt;. This filter is based on &lt;a href="https://www.postgresql.org/docs/current/protocol.html" rel="noopener noreferrer"&gt;PostgreSQL frontend/backend protocol version 3.0&lt;/a&gt;, which was introduced in PostgreSQL 7.4.&lt;/p&gt;

&lt;p&gt;The main goal of the PostgreSQL filter is to capture runtime statistics while remaining completely transparent to the database server. &lt;strong&gt;There is no additional monitoring software to deploy or manage in order to collect these vital statistics!&lt;/strong&gt; As listed in the &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_protocols/postgres" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;, the filter currently offers the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decode non SSL traffic, ignore SSL traffic&lt;/li&gt;
&lt;li&gt;Decode session information&lt;/li&gt;
&lt;li&gt;Capture transaction information, including commits and rollbacks&lt;/li&gt;
&lt;li&gt;Expose counters for different types of statements (INSERTs, SELECTs, DELETEs, UPDATEs, etc.)&lt;/li&gt;
&lt;li&gt;Count frontend, backend, and unknown messages&lt;/li&gt;
&lt;li&gt;Identify errors and backend responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;YugabyteDB is fully compatible with the PostgreSQL wire protocol and SQL syntax given that its SQL query layer is based on a fork of PostgreSQL 11.2’s query layer. As a result, YugabyteDB is able to leverage the PostgreSQL filter from Envoy without any modifications whatsoever. The rest of this post outlines the instructions to run the most basic YugabyteDB with Envoy setup (including the PostgreSQL &amp;amp; TCP filters) using Docker Compose. Official &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/start/start#sandboxes" rel="noopener noreferrer"&gt;Envoy sandboxes&lt;/a&gt; use the same approach to test out different features and highlight sample configurations.&lt;/p&gt;

&lt;h1&gt;
  
  
  YugabyteDB with Envoy in action
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Install Docker
&lt;/h2&gt;

&lt;p&gt;Ensure that you have docker and docker-compose installed on your local machine. &lt;a href="https://www.docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; can be the simplest way to achieve this goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the “YugabyteDB with Envoy” stack using docker-compose
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a working directory
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir yugabyte-envoy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the envoy.yaml
&lt;/h3&gt;

&lt;p&gt;Copy the following contents into a file named &lt;code&gt;envoy.yaml&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;static_resources:
  listeners:
  - name: yb_listener
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 1999
    filter_chains:
    - filters:
      - name: envoy.filters.network.postgres_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.postgres_proxy.v3alpha.PostgresProxy
          stat_prefix: ysql
      - name: envoy.tcp_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          stat_prefix: tcp_ysql
          cluster: yb_cluster

  clusters:
  - name: yb_cluster
    connect_timeout: 1s
    type: strict_dns
    load_assignment:
      cluster_name: yb_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: ysql
                port_value: 5433

admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see above, we have configured an Envoy listener on port 1999 that has a filter chain with two filters, namely PostgreSQL and TCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the envoy dockerfile
&lt;/h3&gt;

&lt;p&gt;Copy the following contents into a file named &lt;code&gt;Dockerfile-proxy&lt;/code&gt;. When built and instantiated, we will have an envoyproxy container that will use the envoy.yaml configuration we created in the previous step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM envoyproxy/envoy-dev:latest

COPY ./envoy.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy.yaml -l debug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the yugabytedb dockerfile
&lt;/h3&gt;

&lt;p&gt;Copy the following contents into a file named &lt;code&gt;Dockerfile-yugabyte&lt;/code&gt;. When built and instantiated, we will have a single YugabyteDB container with the PostgreSQL-compatible YSQL API available on port 5433.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM yugabytedb/yugabyte:latest

CMD ["/home/yugabyte/bin/yugabyted","start","--daemon=false"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the docker-compose.yaml
&lt;/h3&gt;

&lt;p&gt;Copy the following contents into a file named &lt;code&gt;docker-compose.yaml&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;version: "3.7"
services:

  proxy:
    build:
      context: .
      dockerfile: Dockerfile-proxy
    networks:
      envoymesh:
        aliases:
          - envoy
    expose:
      - "1999"
      - "8001"
    ports:
      - "1999:1999"
      - "8001:8001"

  yugabyte:
    build:
      context: .
      dockerfile: Dockerfile-yugabyte
    networks:
      envoymesh:
        aliases:
          - ysql
    expose:
      - "5433"
    ports:
      - "5433:5433"

networks:
  envoymesh:
    name: envoymesh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start the docker-compose stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose pull
docker-compose up --build -d
docker-compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output from the &lt;code&gt;ps&lt;/code&gt; command is shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name                      Command                     State                Ports                                              
---------------------------------------------------------------------------------
yugabyte_proxy_1      /docker-entrypoint.sh /bin ...   Up      ... 0.0.0.0:1999-&amp;gt;1999/tcp, 0.0.0.0:8001-&amp;gt;8001/tcp                                                                    
yugabyte_yugabyte_1   /home/yugabyte/bin/yugabyt ...   Up      ... 0.0.0.0:5433-&amp;gt;5433/tcp, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, two containers have been spun up on a common &lt;em&gt;envoymesh&lt;/em&gt; network.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;yugabyte_yugabyte_1&lt;/em&gt; is the YugabyteDB container that is ready to interact with PostgreSQL clients on port 5433.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;yugabyte_proxy_1&lt;/em&gt; is the Envoy proxy container that is running the PostgreSQL proxy on the 1999 port. Requests to this port get automatically redirected to the port 5433 on the YugabyteDB container.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Connect using ysqlsh via the envoy listener
&lt;/h3&gt;

&lt;p&gt;We are now ready to connect to the YugabyteDB cluster using &lt;code&gt;ysqlsh&lt;/code&gt;. However, instead of directly connecting to the &lt;code&gt;5433&lt;/code&gt; port of the YugabyteDB container, we will connect to the Envoy proxy at the &lt;code&gt;1999&lt;/code&gt; port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -it --network envoymesh yugabytedb/yugabyte /home/yugabyte/bin/ysqlsh "sslmode=disable" -h envoy -p 1999
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As highlighted in the &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_protocols/postgres.html" rel="noopener noreferrer"&gt;Envoy docs&lt;/a&gt;, the current PostgreSQL filter decodes only non-SSL (aka unencrypted) traffic and ignores any SSL/encrypted traffic. The &lt;code&gt;sslmode=disable&lt;/code&gt; option shown above is mandatory for Envoy to treat the PostgreSQL traffic as unencrypted even though the cluster has been set up without any encryption. Since this behavior is reproducible with both PostgreSQL 12 and 11.2 (Yugabyte SQL is based on a fork of this version), this is most likely a bug in the filter implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run basic YSQL commands
&lt;/h2&gt;

&lt;p&gt;Let’s create a table.&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 links (
    id SERIAL PRIMARY KEY,
    url VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description VARCHAR (255),
      last_update DATE
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us insert four rows into the table we created.&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 links (url, name)
VALUES('https://www.postgresqltutorial.com','PostgreSQL Tutorial');

INSERT INTO links (url, name)
VALUES('https://www.oreilly.com','O''Reilly Media');

INSERT INTO links (url, name)
VALUES('https://docs.yugabyte.com','YugabyteDB Docs');

INSERT INTO links (url, name)
VALUES('https://blog.yugabyte.com','YugabyteDB Blog') 
RETURNING id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now run a &lt;code&gt;SELECT&lt;/code&gt; statement to get all the rows we inserted.&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 links;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also run a &lt;code&gt;SELECT&lt;/code&gt; statement to get the count of rows we inserted.&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(*) FROM links;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Review YSQL statistics collected by Envoy’s filters
&lt;/h2&gt;

&lt;p&gt;Each of the two filters configured provide us with statistics relevant to the data they observe. All these statistics are available on the Envoy stats page &lt;code&gt;http://localhost:8001/stats.&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Using the PostgreSQL filter
&lt;/h1&gt;

&lt;p&gt;Since we gave the stats prefix as &lt;em&gt;ysql&lt;/em&gt;, we see all the statistics with the overall prefix as &lt;em&gt;postgres.ysql&lt;/em&gt;. The ones that we can easily verify based on the queries we executed in the &lt;code&gt;ysqlsh&lt;/code&gt; session we created are highlighted with "**".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres.ysql.errors: 0
postgres.ysql.errors_error: 0
postgres.ysql.errors_fatal: 0
postgres.ysql.errors_panic: 0
postgres.ysql.errors_unknown: 0
postgres.ysql.messages: 45
postgres.ysql.messages_backend: 37
postgres.ysql.messages_frontend: 8
postgres.ysql.messages_unknown: 0
postgres.ysql.notices: 0
postgres.ysql.notices_debug: 0
postgres.ysql.notices_info: 0
postgres.ysql.notices_log: 0
postgres.ysql.notices_notice: 0
postgres.ysql.notices_unknown: 0
postgres.ysql.notices_warning: 0
**postgres.ysql.sessions: 1**
postgres.ysql.sessions_encrypted: 0
**postgres.ysql.sessions_unencrypted: 1**
**postgres.ysql.statements: 7**
postgres.ysql.statements_delete: 0
**postgres.ysql.statements_insert: 4**
**postgres.ysql.statements_other: 1**
postgres.ysql.statements_parse_error: 2
postgres.ysql.statements_parsed: 5
**postgres.ysql.statements_select: 2**
postgres.ysql.statements_update: 0
**postgres.ysql.transactions: 7**
**postgres.ysql.transactions_commit: 7**
postgres.ysql.transactions_rollback: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the TCP filter
&lt;/h3&gt;

&lt;p&gt;The TCP statistics relevant to YSQL are available with the &lt;em&gt;tcp.tcp_ysql&lt;/em&gt; prefix. As we can see, the statistics are at the network level including bytes transmitted and bytes received.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tcp.tcp_ysql.downstream_cx_no_route: 0
tcp.tcp_ysql.downstream_cx_rx_bytes_buffered: 33
tcp.tcp_ysql.downstream_cx_rx_bytes_total: 693
tcp.tcp_ysql.downstream_cx_total: 1
tcp.tcp_ysql.downstream_cx_tx_bytes_buffered: 0
tcp.tcp_ysql.downstream_cx_tx_bytes_total: 991
tcp.tcp_ysql.downstream_flow_control_paused_reading_total: 0
tcp.tcp_ysql.downstream_flow_control_resumed_reading_total: 0
tcp.tcp_ysql.idle_timeout: 0
tcp.tcp_ysql.upstream_flush_active: 0
tcp.tcp_ysql.upstream_flush_total: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remove all the containers in the stack
&lt;/h2&gt;

&lt;p&gt;We can remove the containers we have previously spun up using the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker rm -f $(docker ps -aq)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The recently released PostgreSQL filter from Envoy Proxy makes it extremely easy for developers and operations engineers to collect SQL statistics from YSQL, YugabyteDB’s PostgreSQL-compatible fully-relational distributed SQL API. The filter runs inside the Envoy Proxy sidecar container and works by simply sniffing the network traffic in a manner that is completely transparent to the database server. As a result, developers and operations engineers can leverage the integration without deploying and managing any additional software.&lt;/p&gt;

&lt;p&gt;We welcome all users to give the integration a try today and provide us feedback via &lt;a href="https://github.com/yugabyte/yugabyte-db/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://www.yugabyte.com/slack" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>envoy</category>
      <category>postgres</category>
      <category>yugabyte</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>SQL Tips &amp; Tricks: Counting Rows</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Thu, 27 Aug 2020 22:43:30 +0000</pubDate>
      <link>https://dev.to/yugabyte/sql-tips-tricks-counting-rows-4dgn</link>
      <guid>https://dev.to/yugabyte/sql-tips-tricks-counting-rows-4dgn</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This is a cross post of my colleague &lt;a href="https://www.linkedin.com/in/kranganathan/" rel="noopener noreferrer"&gt;Karthik Ranganathan's&lt;/a&gt; blog that was originally published &lt;a href="https://blog.yugabyte.com/row-counts-of-tables-in-a-sql-schema-database-postgresql-yugabytedb/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Getting total row counts of data in tables across various dimensions (per-table, per-schema, and in a given database) is a useful technique to have in one’s tool belt of SQL tricks. While there are a number of use cases for this, my scenario was to get the per-table row counts of all tables in PostgreSQL and YugabyteDB as a first sanity check after &lt;a href="https://docs.yugabyte.com/latest/migrate/migrate-from-postgresql/" rel="noopener noreferrer"&gt;migrating an application with the pre-existing data from PostgreSQL to YugabyteDB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This blog post outlines how to get the following row counts of tables in a database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Row counts broken down per table in the schema&lt;/li&gt;
&lt;li&gt;Aggregate row counts per schema of the database&lt;/li&gt;
&lt;li&gt;Aggregate row count across all tables in the database
We will create an example database, import two popular SQL datasets – &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; and &lt;a href="https://docs.yugabyte.com/latest/sample-data/sportsdb/" rel="noopener noreferrer"&gt;SportsDB&lt;/a&gt;, and run through the above scenarios on these example databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The examples in this blog post, which are essentially dynamic SQL queries on the system catalog tables, must be done with superuser privileges. Also, note that the programmatic generation of SQL queries using catalog tables needs to handle exotic names properly. An instance of a table and a column with an exotic name is shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="nv"&gt;"Some Exotically Named Table"&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="n"&gt;bigserial&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;"Some Exotically Named Column"&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this post does not explicitly discuss the challenges posed by the example above, the SQL functions below handle these cases correctly and do so by incorporating some of the important and well-known techniques necessary to &lt;a href="https://medium.com/swlh/sql-injection-for-developers-9e0d91ad8cbf" rel="noopener noreferrer"&gt;prevent SQL injection attacks&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Create an example database
&lt;/h1&gt;

&lt;p&gt;In order to create a test setup, I simply &lt;a href="https://download.yugabyte.com/" rel="noopener noreferrer"&gt;installed YugabyteDB&lt;/a&gt; on my laptop, created a database &lt;code&gt;example&lt;/code&gt;, and loaded the &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; dataset – all of which only took a few minutes to do. For the purpose of simplicity, we’re going to use the default &lt;code&gt;yugabyte&lt;/code&gt; user for the operations below. However, creating a dedicated user for each of these datasets with the appropriate privileges is the recommended best practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create an example database and connect to it.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE example;
yugabyte=# \c example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create the Northwind tables and import the dataset into the &lt;code&gt;northwind&lt;/code&gt; schema.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example=# CREATE SCHEMA northwind;
example=# SET SCHEMA 'northwind';
example=# \i northwind_ddl.sql
example=# \i northwind_data.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify that the tables have been created 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;example=# \d
                   List of relations
  Schema   |          Name          | Type  |  Owner
-----------+------------------------+-------+----------
 northwind | categories             | table | yugabyte
 northwind | customer_customer_demo | table | yugabyte
 northwind | customer_demographics  | table | yugabyte
 northwind | customers              | table | yugabyte
 northwind | employee_territories   | table | yugabyte
 northwind | employees              | table | yugabyte
 northwind | order_details          | table | yugabyte
 northwind | orders                 | table | yugabyte
 northwind | products               | table | yugabyte
 northwind | region                 | table | yugabyte
 northwind | shippers               | table | yugabyte
 northwind | suppliers              | table | yugabyte
 northwind | territories            | table | yugabyte
 northwind | us_states              | table | yugabyte
(14 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s &lt;a href="https://docs.yugabyte.com/latest/sample-data/sportsdb/" rel="noopener noreferrer"&gt;import the SportsDB dataset&lt;/a&gt; into a new schema named sportsdb as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example=# CREATE SCHEMA sportsdb;
example=# SET SCHEMA 'sportsdb';
example=# \i sportsdb_tables.sql
example=# \i sportsdb_indexes.sql
example=# \i sportsdb_inserts.sql
example=# \i sportsdb_constraints.sql
example=# \i sportsdb_fks.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Create a function for row count
&lt;/h1&gt;

&lt;p&gt;Recall that YugabyteDB re-uses the native PostgreSQL codebase for its query layer (or the SQL processing layer) of the database. This means that the high-level approach to solving this problem is identical in the case of both PostgreSQL and YugabyteDB.&lt;/p&gt;

&lt;p&gt;We’ll solve this problem by first creating a user defined function (UDF), &lt;code&gt;count_rows_of_table&lt;/code&gt; which counts the number of rows in a single table. Note that this function must be owned by a suitably privileged user, in our example we will use the &lt;code&gt;yugabyte&lt;/code&gt; user. This function can subsequently be used in various types of queries to print the desired row counts in the various scenarios. The function definition is shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;count_rows_of_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;schema&lt;/span&gt;    &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;tablename&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;returns&lt;/span&gt;   &lt;span class="nb"&gt;integer&lt;/span&gt;

  &lt;span class="k"&gt;security&lt;/span&gt;  &lt;span class="k"&gt;invoker&lt;/span&gt;
  &lt;span class="k"&gt;language&lt;/span&gt;  &lt;span class="n"&gt;plpgsql&lt;/span&gt;
&lt;span class="k"&gt;as&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;
&lt;span class="k"&gt;declare&lt;/span&gt;
  &lt;span class="n"&gt;query_template&lt;/span&gt; &lt;span class="n"&gt;constant&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="s1"&gt;'
      select count(*) from "?schema"."?tablename"
    '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="n"&gt;constant&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;query_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'?schema'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
     &lt;span class="s1"&gt;'?tablename'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tablename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;result&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;execute&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="k"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test the above function by passing in a table (for example, the &lt;code&gt;orders&lt;/code&gt; table loaded from the Northwind dataset) as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example=# SELECT count_rows_of_table('northwind', 'orders');
 count_rows_of_table
---------------------
                 830
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Per-table row counts in a given database
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;information_schema.tables&lt;/code&gt; table in the system catalog contains the list of all tables and the schemas they belong to. Because we are mainly interested in the user tables, we filter out all tables belonging to &lt;code&gt;pg_catalog&lt;/code&gt; and &lt;code&gt;information_schema&lt;/code&gt;, which are system schemas. We then call the function we defined in the previous section to get the row count for each table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;
  &lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;count_rows_of_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;
  &lt;span class="n"&gt;information_schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; 
  &lt;span class="n"&gt;table_schema&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'pg_catalog'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'information_schema'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;table_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'BASE TABLE'&lt;/span&gt;
&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query above outputs a table that contains the row counts of all tables across the various schemas, first sorted by the &lt;code&gt;table_schema&lt;/code&gt; column and for each table schema, sorted by the tables with the largest number of rows. If we run the above query on our test database, we should see 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; table_schema |       table_name       | count_rows_of_table
--------------+------------------------+---------------------
 northwind    | order_details          |                2155
 northwind    | orders                 |                 830
 northwind    | customers              |                  91
 northwind    | products               |                  77

...
 sportsdb     | affiliations_events    |               13052
 sportsdb     | stats                  |                9398
 sportsdb     | participants_events    |                8700
 sportsdb     | events_documents       |                7915
...
(121 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Aggregate row counts per schema
&lt;/h1&gt;

&lt;p&gt;Next, let us say we want to get the total row count across all tables broken down per schema. This can be achieved by using the following query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;row_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_rows&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
         &lt;span class="n"&gt;count_rows_of_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;row_count&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;information_schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;table_schema&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'pg_catalog'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'information_schema'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
      &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;table_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'BASE TABLE'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;per_table_count_subquery&lt;/span&gt;
  &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;table_schema&lt;/span&gt;
  &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above uses a subquery to first compute the totals row count per table and performs a &lt;code&gt;GROUP BY&lt;/code&gt; operation to get the total number of rows in each schema of the current database. The resulting output is sorted by the schema with the maximum number of rows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; table_schema | total_rows
--------------+------------
 sportsdb     |      79138
 northwind    |       3362
(2 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Aggregate row count across all tables
&lt;/h1&gt;

&lt;p&gt;The query below simply sums the row counts of the individual tables from the previous step to get a total row count across all the tables. This is done by running the per-table row count as a subquery called &lt;code&gt;per_table_count_subquery&lt;/code&gt; and performing a &lt;code&gt;SUM&lt;/code&gt; across all the row counts that are the output of that subquery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;per_table_counts&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;count_rows_of_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;row_count&lt;/span&gt;
    &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;information_schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;
    &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;table_schema&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'pg_catalog'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'information_schema'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;table_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'BASE TABLE'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;row_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_rows&lt;/span&gt;
    &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;per_table_counts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this on the Northwind example dataset produces 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;
 total_rows
------------
      82500
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This post shows some important SQL techniques for computing row counts for PostgreSQL-compatible databases like YugabyteDB. Please remember that writing programs that generate and execute dynamic SQL must be done with caution, rigorous testing, and thorough peer reviews. Errors bring the risk of wrong results. But far worse than this, they expose your code, and therefore your entire database, to the risks of SQL injection attacks.&lt;/p&gt;

&lt;p&gt;The code in the examples above works exactly the same way across PostgreSQL and YugabyteDB. This is by design, due to the &lt;a href="https://blog.yugabyte.com/why-we-built-yugabytedb-by-reusing-the-postgresql-query-layer/" rel="noopener noreferrer"&gt;reuse of the PostgreSQL query layer in YugabyteDB&lt;/a&gt;. Try out your favorite PostgreSQL feature on YugabyteDB, and let us know how it goes on our &lt;a href="https://www.yugabyte.com/slack" rel="noopener noreferrer"&gt;Community Slack&lt;/a&gt;. If you run into any issues, just file an issue on &lt;a href="https://github.com/yugabyte/yugabyte-db/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>yugabyte</category>
      <category>sql</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Hasura GraphQL Remote JOINs on Distributed SQL Running on AKS &amp; GKE</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Mon, 24 Aug 2020 23:41:39 +0000</pubDate>
      <link>https://dev.to/yugabyte/hasura-graphql-remote-joins-on-distributed-sql-running-on-aks-gke-1h3</link>
      <guid>https://dev.to/yugabyte/hasura-graphql-remote-joins-on-distributed-sql-running-on-aks-gke-1h3</guid>
      <description>&lt;p&gt;&lt;a href="https://hasura.io/blog/remote-joins-a-graphql-api-to-join-database-and-other-data-sources/" rel="noopener noreferrer"&gt;Remote Joins&lt;/a&gt; in Hasura GraphQL extend the concept of joining data across tables, to being able to join data across tables and remote data sources. In this blog post we are going to demonstrate this capability by configuring the following set up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 3 node YugabyteDB cluster running on GKE with a Hasura GraphQL Engine attached&lt;/li&gt;
&lt;li&gt;A 3 node YugabyteDB cluster running on AKS with a Hasura GraphQL Engine attached&lt;/li&gt;
&lt;li&gt;A Remote Schema and Remote Relationship configured&lt;/li&gt;
&lt;li&gt;The ability to issue GraphQL queries that join data from two different databases, hosted in two different clouds, into a single result set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2FGetting-Started-with-Hasura-GraphQL-Remote-JOINs-on-Multi-Cloud-Distributed-SQL-1024x699.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2FGetting-Started-with-Hasura-GraphQL-Remote-JOINs-on-Multi-Cloud-Distributed-SQL-1024x699.png" alt="remote-graphql1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or to cloud native environments. This is often motivated by the desire to reduce TCO or move away from the scaling limitations of monolithic RDBMS like Oracle, MySQL and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL API for querying and modeling data, with support for traditional RDBMS features like primary keys, foregin keys, indexes, stored procedures, and triggers.&lt;/li&gt;
&lt;li&gt;Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/li&gt;
&lt;li&gt;A distributed SQL database should support automatically distributed data storage. This includes indexes which should be automatically distributed (aka sharded) across multiple nodes of the cluster so that no single node becomes a bottleneck for ensuring high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.
For a deeper discussion about what Distributed SQL is, check out, “What is Distributed SQL?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible with support for advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Ok, on with the demo…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on GKE
&lt;/h1&gt;

&lt;p&gt;Here are the complete steps to &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/oss/helm-chart/" rel="noopener noreferrer"&gt;install a 3 node YugabyteDB cluster on Google Kubernetes Engine&lt;/a&gt;. Once you have a YugabyteDB cluster running on GKE, check the status of the cluster by executing the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo 

NAME                 EXTERNAL-IP      PORT(S) 
yb-tserver-service   35.224.XX.XX     5433:3067/TCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the external IP for &lt;code&gt;yb-tserver-service&lt;/code&gt; which we are going to use to establish a connection between YugabyteDB and Hasura GraphQL Engine. From the output above we can see that the IP is &lt;code&gt;35.224.XX.XX&lt;/code&gt; and the YSQL port is &lt;code&gt;5433&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the Northwind Sample Database
&lt;/h1&gt;

&lt;p&gt;In our documentation, you can find a variety of &lt;a href="https://docs.yugabyte.com/latest/sample-data/" rel="noopener noreferrer"&gt;sample databases&lt;/a&gt; that are compatible with YugabyteDB. For the purposes of this tutorial we are going to use the &lt;a href="https://docs.yugabyte.com/latest/sample-data/northwind/" rel="noopener noreferrer"&gt;Northwind&lt;/a&gt; sample database. The Northwind database contains the sales data for a fictitious company called “Northwind Traders,” which imports and exports specialty foods from around the world. The Northwind database is an excellent tutorial schema for a small-business ERP, with customers, orders, inventory, purchasing, suppliers, shipping, employees, and single-entry accounting.&lt;br&gt;
Connect to the &lt;code&gt;yb-tserver-pod&lt;/code&gt; 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;$ kubectl exec -n yb-demo -it yb-tserver-0 /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download the schema and data files, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_ddl.sql

$ wget https://raw.githubusercontent.com/yugabyte/yugabyte-db/master/sample/northwind_data.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect to the YSQL service, exit out of the pod shell and 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;$ exit 
$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE northwind; 
northwind=# \c northwind;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now create the database objects and load them with data using the files we downloaded to &lt;code&gt;yb-tserver-pod&lt;/code&gt; using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# \i 'northwind_ddl.sql'; 
northwind=# \i 'northwind_data.sql';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default &lt;code&gt;yugabyte user&lt;/code&gt;. Specifying one is done the same way you'd do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;northwind=# ALTER ROLE yugabyte WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Set Up Hasura on GKE to Use YugabyteDB
&lt;/h1&gt;

&lt;p&gt;We are now ready to install the Hasura GraphQL Engine on GKE. Exit the YSQL shell and get the Hasura Kubernetes deployment and service files by executing the commands below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/kubernetes/deployment.yaml

$ wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/kubernetes/svc.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the database URL in deployment.yaml file to include the IP of YugabyteDB. For the purposes of this tutorial, the modification should look 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;value: postgres://yugabyte:[email protected]:5433/northwind
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; If you’d like everything to run in the &lt;code&gt;yb-demo&lt;/code&gt; namespace, make sure to modify the namespace value in both the &lt;code&gt;deployment.yaml&lt;/code&gt; and &lt;code&gt;svc.yaml&lt;/code&gt; files. This is the setup I have chosen for this demo.&lt;/p&gt;

&lt;p&gt;After saving the file, use &lt;code&gt;kubectl&lt;/code&gt; to create a Hasura deployment using the commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create -f deployment.yaml 
deployment.apps/hasura created

$ kubectl create -f svc.yaml 
service/hasura created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To find the external IP and open the Hasura console execute the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo 

NAME      EXTERNAL-IP      PORT(S) 
hasura    35.192.XX.XX     80:30546/TCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now use &lt;code&gt;http://&amp;lt;EXTERNAL-IP&amp;gt;/console&lt;/code&gt; to access the Hasura console. In this case it is &lt;code&gt;35.192.XX.XX&lt;/code&gt;. You should now see the Hasura console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F2-access-the-hasura-console-distributed-sql-yugabytedb-tutorial-1024x502.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F2-access-the-hasura-console-distributed-sql-yugabytedb-tutorial-1024x502.png" alt="remote graphql 2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Track the Northwind Objects in Hasura
&lt;/h1&gt;

&lt;p&gt;Click on &lt;em&gt;Data&lt;/em&gt; in top nav, click on &lt;em&gt;Track All&lt;/em&gt; for tables, views, and foreign key relations. Refresh your browser and you should now see the &lt;code&gt;northwind&lt;/code&gt; tables in the Explorer tree on the left-hand side when you click on GraphQL in the top nav.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F3-see-northwind-tables.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F3-see-northwind-tables.png" alt="graphql 3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Install YugabyteDB on AKS
&lt;/h1&gt;

&lt;p&gt;Here are the complete steps to &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/single-zone/aks/helm-chart/" rel="noopener noreferrer"&gt;install a 3 node YugabyteDB cluster on Azure Kubernetes Service&lt;/a&gt;. Once you have a YugabyteDB cluster running on AKS, check the status of the cluster by executing the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo 
NAME                   EXTERNAL-IP     PORT(S) 
yb-tserver-service     20.190.XX.XX    5433:3067/TCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the external IP for &lt;code&gt;yb-tserver-service&lt;/code&gt; which we are going to use to establish a connection between YugabyteDB and Hasura GraphQL Engine. From the output above we can see that the IP is &lt;code&gt;20.190.XX.XX&lt;/code&gt; and the YSQL port is &lt;code&gt;5433&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Install the Promotions Database
&lt;/h1&gt;

&lt;p&gt;In this step we are going to create a database called promotions, as well as a table called promotions. We'll then load it with data about what types of promotions there are, what company is sponsoring them, and the duration of the promotion.&lt;/p&gt;

&lt;p&gt;Log into the YSQL shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl exec -n yb-demo -it yb-tserver-0 -- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yugabyte=# CREATE DATABASE promotions;
yugabyte=# \c promotions;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default &lt;code&gt;yugabyte&lt;/code&gt; user. Specifying one is done the same way you'd do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;promotions=# ALTER ROLE yugabyte WITH PASSWORD 'password';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the following table in the promotions database.&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 promotions ( 
      promotion_id serial PRIMARY KEY, 
      supplier_id int2 NOT NULL, 
      promotion_name VARCHAR ( 50 ) NOT NULL, 
      company_name VARCHAR ( 40 ) NOT NULL, 
      start_date DATE NOT NULL, 
      stop_date DATE NOT NULL, 
      created_on DATE NOT NULL DEFAULT CURRENT_DATE );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Populate the promotions table with the following 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 promotions 
     (supplier_id, promotion_name, company_name, start_date, stop_date, created_on) 
VALUES 
     ('28','Buy One Get One Free', 'Gai pâturage', '1996-08-15', '1996-08-30', CURRENT_DATE), 
     ('19', 'Free Shipping', 'New England Seafood Cannery', '1996-10-15', '1996-10-30', CURRENT_DATE), 
     ('16', 'Free T-Shirt With Every Purchase', 'Bigfoot Breweries', '1996-12-15', '1996-12-30', CURRENT_DATE), 
     ('20','10% Off', 'Gula Malacca', '1996-11-15', '1996-11-30', CURRENT_DATE), 
     ('8', '20% Off', 'Specialty Biscuits, Ltd.', '1996-09-15', '1996-09-30', CURRENT_DATE);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 7: Set Up Hasura on AKS to Use YugabyteDB
&lt;/h1&gt;

&lt;p&gt;We are now ready to install the Hasura GraphQL Engine on Azure Kubernetes Service. Fortunately, it is very easy to get Hasura up and running on AKS and pointed to our YugabyteDB cluster with a simple wizard. Use this &lt;a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3a%2f%2fraw.githubusercontent.com%2fhasura%2fgraphql-engine%2fmaster%2finstall-manifests%2fazure-container%2fazuredeploy.json" rel="noopener noreferrer"&gt;“one-click deployment”&lt;/a&gt; to set up the particulars. After selecting the option to connect to an existing database, you should see the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F4-ready-to-install-the-Hasura-GraphQL-Engine-on-Azure-Kubernetes-Service.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F4-ready-to-install-the-Hasura-GraphQL-Engine-on-Azure-Kubernetes-Service.png" alt="graphql 5" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that we are specifying the external IP and port of our YugabyteDB cluster. In this case &lt;code&gt;20.189.XX.XX&lt;/code&gt; and &lt;code&gt;5433&lt;/code&gt;. We are also specifying the &lt;code&gt;yugabyte&lt;/code&gt; user and the &lt;code&gt;promotions&lt;/code&gt; database in the settings.&lt;/p&gt;

&lt;p&gt;After Hasura is successfully deployed on AKS, locate the external IP for the console. In my case I looked in the Azure Portal under &lt;em&gt;All Services &amp;gt; Resource groups &amp;gt; /Resource Group/ &amp;gt; hasura-promotions-container-group&lt;/em&gt; and saw that &lt;code&gt;52.137.XX.XX&lt;/code&gt; was the public IP assigned to my Hasura GraphQL Engine. With this information you should now be able to open up the Hasura console and track the &lt;code&gt;promotions&lt;/code&gt; table. Once that's accomplished, you should now see the &lt;code&gt;promotions&lt;/code&gt; table in your Explorer as shown below.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Set Up a Remote Schema and Remote Relationship
&lt;/h1&gt;

&lt;p&gt;On the Hasura console running on GKE, navigate to the Remote Schemas tab, click on Add and provide the necessary information for the Hasura server running on AKS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F6-Set-Up-a-Remote-Schema.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F6-Set-Up-a-Remote-Schema.png" alt="graphql 6" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, let’s add a Remote Relationship on the &lt;code&gt;supplier_id&lt;/code&gt; table between the &lt;code&gt;suppliers&lt;/code&gt; and &lt;code&gt;promotions&lt;/code&gt; table that we can leverage in our remote &lt;code&gt;JOIN&lt;/code&gt;. You can accomplish this by navigating to &lt;code&gt;Data &amp;gt; suppliers &amp;gt; Relationships &amp;gt; Remote Schema Relationships&lt;/code&gt; and specify the relationship.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F7-add-a-Remote-Relationship.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F7-add-a-Remote-Relationship.png" alt="graphql 7" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 9: Issue a Remote Join Across Two Databases
&lt;/h1&gt;

&lt;p&gt;We are now finished with setting up a Remote Schema to the &lt;code&gt;promotions&lt;/code&gt; database and a Remote Relationship on &lt;code&gt;supplier_id&lt;/code&gt;. We can now issue a query that processes data located in two different YugabyteDB databases, hosted on two different clouds. For the purposes of this demo, we want to issue a Remote Join GraphQL query that will allow us to determine if a supplier in the "primary" Northwind database has a promotion scheduled in the "remote" Promotions database.&lt;/p&gt;

&lt;p&gt;For example, in the query below we want to know if supplier “16” is running any promotions, and if so, what is the name of the promotion and for what dates is the promotion active.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F8-query-supplier-16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F8-query-supplier-16.png" alt="graphql 8" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The GraphQL query should return the following results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F9-The-GraphQL-query-should-return-the-following-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F9-The-GraphQL-query-should-return-the-following-results.png" alt="grahpql 9" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we break down the GraphQL query, here’s what is happening.&lt;/p&gt;

&lt;p&gt;From the &lt;code&gt;suppliers&lt;/code&gt; table, which is hosted on a YugabyteDB cluster running on GKE, we are returning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;supplier_id = "16"&lt;/li&gt;
&lt;li&gt;company_name = "Bigfoot Breweries"&lt;/li&gt;
&lt;li&gt;contact _name = "Cheryl Saylor"&lt;/li&gt;
&lt;li&gt;phone = "(503) 555-9931"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We then make use of the Remote Schema &lt;code&gt;promotions_remote&lt;/code&gt; that has a relationship on &lt;code&gt;supplier_id&lt;/code&gt; to allow us to return the following data from the &lt;code&gt;promotions&lt;/code&gt; table, which is hosted on a YugabyteDB cluster running on AKS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;promotion_name = "Free T-Shirt With Every Purchase"&lt;/li&gt;
&lt;li&gt;start_date = "1996-12-15"&lt;/li&gt;
&lt;li&gt;stop_date = "1996-12-30"&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it, if you followed all the instructions in this blog post, you now have the following configured.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 node YugabyteDB cluster running on GKE with a Hasura GraphQL Engine attached&lt;/li&gt;
&lt;li&gt;3 node YugabyteDB cluster running on AKS with a Hasura GraphQL Engine attached&lt;/li&gt;
&lt;li&gt;A Remote Schema and Remote Relationship configured
The ability to issue GraphQL queries that join data from two different databases into a single result set&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>postgres</category>
      <category>yugabyte</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Deploying a Real-Time Location App with Hasura GraphQL Engine and Distributed SQL</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Fri, 21 Aug 2020 21:35:24 +0000</pubDate>
      <link>https://dev.to/yugabyte/deploying-a-real-time-location-app-with-hasura-graphql-engine-and-distributed-sql-1855</link>
      <guid>https://dev.to/yugabyte/deploying-a-real-time-location-app-with-hasura-graphql-engine-and-distributed-sql-1855</guid>
      <description>&lt;p&gt;&lt;a href="https://hasura.io/" rel="noopener noreferrer"&gt;Hasura&lt;/a&gt; is one of the leading vendors in the GraphQL ecosystem. They offer an open source engine that connects to your databases and microservices, and then auto-generates a production-ready GraphQL backend. GraphQL is a query language (more specifically a specification) for your API, and a server-side runtime for executing queries by using a type system you define for your data. GraphQL is often used for microservices, mobile apps, and as an alternative to REST. Although GraphQL isn’t tied to any specific database or storage engine and is instead backed by your existing code and data, YugabyteDB is a perfect complement to GraphQL giving you horizontal scalability, fault tolerance, and global data distribution in a single system.&lt;/p&gt;

&lt;p&gt;In this blog post we’ll show you how to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install a 3 node YugabyteDB cluster on Google Kubernetes Engine (GKE)&lt;/li&gt;
&lt;li&gt;Deploy the Hasura GraphQL Engine on GKE&lt;/li&gt;
&lt;li&gt;Stand up Hasura’s “realtime-location-tracking” app locally and connect to resources on GKE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/realtime-location-tracking" rel="noopener noreferrer"&gt;“realtime location application”&lt;/a&gt; is built using React and is powered by Hasura GraphQL Engine backed by a 3 node YugabyteDB cluster. It has an interface for users to track location of a vehicle using Hasura live queries, in real time. The application makes use of Hasura GraphQL Engine’s real-time capabilities using subscription.&lt;/p&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or cloud native environments. This is often motivated by the desire to reduce TCO or move away from the horizontal scaling limitations of monolithic RDBMS like Oracle, PostgreSQL, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They must have a SQL API for querying and modeling data, with support for traditional RDBMS features like foreign keys, partial indexes, stored procedures, and triggers.&lt;br&gt;
Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should support automatic and transparent distributed data storage. This includes indexes, which should be sharded across multiple nodes of the cluster so that no single node becomes a bottleneck. Data distribution ensures high performance and high availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible, cloud native, offers deep integration with GraphQL projects, plus supports advanced RDBMS features like stored procedures, triggers and UDFs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on a GKE Cluster Using Helm 3
&lt;/h1&gt;

&lt;p&gt;In this section we are going to install YugabyteDB on the cluster. The complete steps are documented &lt;a href="https://docs.yugabyte.com/latest/deploy/kubernetes/oss/helm-chart/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We’ll assume you already have a GKE cluster up and running as a starting point.&lt;/p&gt;

&lt;p&gt;The first thing to do is to add the charts repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo add yugabytedb https://charts.yugabyte.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, fetch the updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a namespace. In this case we’ll call it &lt;code&gt;yb-demo&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;$ kubectl create namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace/yb-demo created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to install YugabyteDB. In the command below we’ll be specifying values for a resource constrained environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm install yb-demo yugabytedb/yugabyte \
--set resource.master.requests.cpu=1,resource.master.requests.memory=1Gi,\
resource.tserver.requests.cpu=1,resource.tserver.requests.memory=1Gi,\
enableLoadBalancer=True --namespace yb-demo --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the status of the cluster, execute the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F2-check-the-status-of-the-cluster.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F2-check-the-status-of-the-cluster.png" alt="check yugabytedb cluster status hasura graphql distributed sql gke tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the external-IP for &lt;code&gt;yb-tserver-service&lt;/code&gt; which we are going to use to establish a connection between YugabyteDB and Hasura. In this demo, the IP is &lt;code&gt;35.224.XX.XX&lt;/code&gt; and the YSQL port is &lt;code&gt;5433&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Setting up Hasura to Use YugabyteDB
&lt;/h1&gt;

&lt;p&gt;Get the Hasura Kubernetes deployment and service files by executing the commands below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/kubernetes/deployment.yaml
&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;$ wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/kubernetes/svc.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the database URL in &lt;code&gt;deployment.yaml&lt;/code&gt; file to include the IP of YugabyteDB. This file can be edited using a text editor like vi. Note that by default the &lt;code&gt;yugabyte&lt;/code&gt; user in YugabyteDB doesn’t have a password and the default database is &lt;code&gt;yugabyte&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the purposes of this tutorial, the modification should look 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;value: postgres://yugabyte:@35.224.XX.XX:5433/yugabyte
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you’d like everything to run in the &lt;code&gt;yb-demo&lt;/code&gt; namespace, make sure to modify the namespace value in both the &lt;code&gt;deployment.yaml&lt;/code&gt; and &lt;code&gt;svc.yaml&lt;/code&gt; files. This is the setup I have chosen for this demo.&lt;/p&gt;

&lt;p&gt;After saving the file use &lt;code&gt;kubectl&lt;/code&gt; to create a Hasura deployment using the commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create -f deployment.yaml

deployment.apps/hasura created
&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;$ kubectl create -f svc.yaml

service/hasura created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To find the external IP and open the Hasura console execute the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get services --namespace yb-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F3-find-the-external-IP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F3-find-the-external-IP.png" alt="find the external IP hasura yugabytedb distributed sql gke tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now use &lt;code&gt;http://&amp;lt;EXTERNAL-IP&amp;gt;/console&lt;/code&gt; to access the Hasura console. In this case it is &lt;code&gt;34.68.XX.XX&lt;/code&gt;. You should now see the Hasura console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F4-hasura-console-1024x508.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F4-hasura-console-1024x508.png" alt="see the hasura console graphql distributed sql yugabytedb tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Install the Realtime Tracking Location App
&lt;/h1&gt;

&lt;p&gt;In step 3 we’ll be working locally. For the purposes of this demo, I am on a Mac.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download the sample applications
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/hasura/graphql-engine
&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;$ cd graphql-engine/community/sample-apps/realtime-location-tracking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Install the Hasura CLI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modify the config.yaml file
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;code&gt;hasura/&lt;/code&gt; directory and edit the &lt;code&gt;config.yaml&lt;/code&gt; file with the external IP of the Hasura service. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoint: http://34.68.XX.XX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modify the docker-compose.yaml file
&lt;/h2&gt;

&lt;p&gt;Within the same &lt;code&gt;hasura/&lt;/code&gt; directory modify the &lt;code&gt;docker-compose.yaml&lt;/code&gt; file with the following changes.&lt;/p&gt;

&lt;p&gt;Eliminate the need for a password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;environment:
- “POSTGRES_PASSWORD:“
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the port assignment so it can connect to YugabyteDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ports:
- “5433:5433“
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specify the connect string with YugabyteDB parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;environment:
- HASURA_GRAPHQL_DATABASE_URL: postgres://yugabyte:@35.224.xx.xx:5433/yugabyte
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Modify the constants.js file
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;code&gt;src/&lt;/code&gt; directory and edit the &lt;code&gt;constants.js&lt;/code&gt; file with the following changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Constants file
export const HASURA_GRAPHQL_URL = '34.68.XX.XX/v1/graphql';
const HASURA_GRAPHQL_ENGINE_HOSTNAME = '34.68.XX.XX';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Apply the migrations
&lt;/h2&gt;

&lt;p&gt;Navigate back to the &lt;code&gt;hasura/&lt;/code&gt; directory and run the migration scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ hasura migrate apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now be able to see the sample apps tables in the Hasura console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F5-see-sample-apps-hasura-console.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F5-see-sample-apps-hasura-console.png" alt="see the sample apps tables in the Hasura console yugabytedb gke distributed sql tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start the application
&lt;/h2&gt;

&lt;p&gt;We are now ready to run the app at the root of the application located at &lt;code&gt;~/graphql-engine/community/sample-apps/realtime-location-tracking/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You’ll need to Install Node.js if not already present on your system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a browser window open up with the landing page for the sample app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F6-sample-app-landing-page-1024x587.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F6-sample-app-landing-page-1024x587.png" alt="hasura graphql yugabytedb distributed sql tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the “track location” button to view a real time location tracking example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F7-Click-on-the-%25E2%2580%259Ctrack-location%25E2%2580%259D-button-to-view-a-real-time-location-tracking-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2F7-Click-on-the-%25E2%2580%259Ctrack-location%25E2%2580%259D-button-to-view-a-real-time-location-tracking-example.png" alt="realtime location tracking app hasura graphql and yugabytedb distributedsql tutorial screenshot" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it! You now have the Hasura GraphQL Engine running on top of a 3 node YugabyteDB cluster on GKE. The GraphQL realtime location tracking application is running locally but leveraging Hasura and YugabyteDB in the cloud.&lt;/p&gt;

</description>
      <category>yugabyte</category>
      <category>graphql</category>
      <category>kubernetes</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Run the REST Version of Spring PetClinic with Angular and Distributed SQL on GKE</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Thu, 20 Aug 2020 18:39:24 +0000</pubDate>
      <link>https://dev.to/yugabyte/run-the-rest-version-of-spring-petclinic-with-angular-and-distributed-sql-on-gke-23ia</link>
      <guid>https://dev.to/yugabyte/run-the-rest-version-of-spring-petclinic-with-angular-and-distributed-sql-on-gke-23ia</guid>
      <description>&lt;p&gt;Java developers know that &lt;a href="https://spring.io/projects" rel="noopener noreferrer"&gt;Spring Data&lt;/a&gt; makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. When YugabyteDB is combined with Spring, Java developers are able to leverage their familiarity with PostgreSQL while gaining the added benefits of Distributed SQL. These “out-of-the-box” benefits include geo-data distribution, high performance, and horizontal scalability, which are impossible or difficult to achieve with monolithic SQL databases. To demonstrate just how easy it is to get started with Spring and YugabyteDB, we’ve put together this simple tutorial using examples which should be very familiar to both the novice and expert Spring developer.&lt;/p&gt;

&lt;p&gt;In this blog post we’ll walk you though the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install a 3 node YugabyteDB cluster on Google Kubernetes Platform&lt;/li&gt;
&lt;li&gt;Deploy a REST version of the &lt;a href="https://github.com/spring-projects/spring-petclinic" rel="noopener noreferrer"&gt;Spring PetClinic&lt;/a&gt; sample application&lt;/li&gt;
&lt;li&gt;Configure an &lt;a href="https://github.com/spring-projects/spring-petclinic" rel="noopener noreferrer"&gt;Angular frontend&lt;/a&gt; for the Spring PetClinic&lt;/li&gt;
&lt;li&gt;Basic testing using Swagger and the Angular UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or to cloud native environments. This is often motivated by the desire to reduce TCO or move away from the scaling limitations of monolithic RDBMS like Oracle, MySQL and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A SQL API for querying and modeling data, with support for traditional RDBMS features like primary keys, foregin keys, indexes, stored procedures, and triggers.&lt;/li&gt;
&lt;li&gt;Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/li&gt;
&lt;li&gt;A distributed SQL database should support automatically distributed data storage. This includes indexes which should be automatically distributed (aka sharded) across multiple nodes of the cluster so that no single node becomes a bottleneck for ensuring high performance and high availability.&lt;/li&gt;
&lt;li&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.
For a deeper discussion about what Distributed SQL is, check out, “What is Distributed SQL?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible with support for advanced RDBMS features like stored procedures, triggers, and UDFs.&lt;/p&gt;

&lt;p&gt;Ok, on with the demo…&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install YugabyteDB on a GKE Cluster using Helm 3
&lt;/h1&gt;

&lt;p&gt;In this section we are going to install YugabyteDB on the cluster. The complete steps are documented here. We’ll assume you already have a GKE cluster up and running as a starting point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;yugabytedb&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;charts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yugabyte&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, fetch the updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a namespace. In this case we’ll call it yb-demo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;yb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;yb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to install YugabyteDB. In the command below we’ll be specifying values for a resource constrained environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;helm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;yb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt; &lt;span class="n"&gt;yugabytedb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;yugabyte&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;span class="c1"&gt;--set resource.master.requests.cpu=1,resource.master.requests.memory=1Gi,\&lt;/span&gt;
&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Gi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;
&lt;span class="n"&gt;enableLoadBalancer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;True&lt;/span&gt; &lt;span class="c1"&gt;--namespace yb-demo --wait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the status of the cluster, execute the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="c1"&gt;--namespace yb-demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage3.png" alt="image3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the external-IP for &lt;code&gt;yb-tserver-service&lt;/code&gt; which we are going to use to establish a connection to YugabyteDB. From the screenshot above we can see that the IP is &lt;code&gt;35.224.XX.XX&lt;/code&gt; and the YSQL port is &lt;code&gt;5433&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the petclinic database and set a password
&lt;/h1&gt;

&lt;p&gt;Let’s create a dedicated database called &lt;code&gt;petclinic&lt;/code&gt; for our application. To connect to the YSQL service run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;yb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;demo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;yb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tserver&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;-- ysqlsh -h yb-tserver-0.yb-tservers.yb-demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the &lt;code&gt;petclinic&lt;/code&gt; database and connect to it using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;yugabyte&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;yugabyte&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, a YugabyteDB installation doesn’t have a password setup for the default &lt;code&gt;yugabyte&lt;/code&gt; user. Specifying one is done the same way you’d do it in PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;yugabyte&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Install and configure the REST version of Spring PetClinic
&lt;/h1&gt;

&lt;p&gt;In step 3 we’ll be working locally. For the purposes of this demo, I am on a Mac. First up we’ll need to clone the PetClinic application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to &lt;em&gt;~/spring-petclinic-rest/src/main/resources/&lt;/em&gt;.&lt;br&gt;
—&lt;br&gt;
&lt;em&gt;Recall that YugabyteDB is PostgreSQL wire compatible, so it will leverage all of the application’s existing PostgreSQL connectivity and databases scripts.&lt;/em&gt;&lt;br&gt;
—&lt;br&gt;
In the &lt;code&gt;application.properties&lt;/code&gt; file you’ll want to specify &lt;code&gt;postgresql&lt;/code&gt; as the database and set the database initialization to &lt;code&gt;always&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;jpa&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9966&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servlet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initialization&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;always&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;level&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;
&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;application-postgresql.properties&lt;/code&gt; file you’ll want to uncomment the init database block and modify the database connectivity string, plus user credentials. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;initDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;populateDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt;

&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;jdbc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;224&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5433&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;yugabyte&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jpa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;POSTGRESQL&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jpa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hibernate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dialect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostgreSQLDialect&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jpa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hibernate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ddl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Run the PetClinic application
&lt;/h1&gt;

&lt;p&gt;You can now run the application with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mvnw&lt;/span&gt; &lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to &lt;code&gt;http://localhost:9966/petclinic/swagger-ui.html&lt;/code&gt; to view the Swagger REST API documentation for the app. You should see something similar to this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage6.png" alt="image2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also jump back over to the YugabyteDB command line and execute PostgreSQL’s familiar \dt command or view the PetClinic tables in a UI like &lt;a href="https://blog.yugabyte.com/getting-started-with-dbeaver-on-a-distributed-sql-database/" rel="noopener noreferrer"&gt;DBeaver&lt;/a&gt;. You should see 9 new tables created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage11.png" alt="image3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also issue a simple SELECT statement or use a UI to view the data that ends up populating the tables by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage7.png" alt="image4" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Configure an Angular frontend
&lt;/h1&gt;

&lt;p&gt;To get an Angular frontend for our PetClinic application we’ll make use of the project that can be found &lt;a href="https://github.com/spring-petclinic/spring-petclinic-angular" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Again we’ll be working locally on a Mac.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You should be running a current version of the angular-cli.&lt;/p&gt;

&lt;p&gt;Clone the project from GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;clone&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;petclinic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;angular&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the local project package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bring up a development server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;ng&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, navigate to &lt;em&gt;&lt;a href="http://localhost:4200/" rel="noopener noreferrer"&gt;http://localhost:4200/&lt;/a&gt;&lt;/em&gt;. &lt;strong&gt;Note:&lt;/strong&gt; The application will automatically reload any changes to source files. You should now see something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage8.png" alt="image5" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Simple data manipulation in Angular
&lt;/h1&gt;

&lt;p&gt;Next, navigate to &lt;em&gt;&lt;a href="http://localhost:4200/petclinic/owners" rel="noopener noreferrer"&gt;http://localhost:4200/petclinic/owners&lt;/a&gt;&lt;/em&gt; and click on “Add Owner” to add a new owner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage9.png" alt="image7" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We should now see this new owner in the UI. This means we’ve successfully written to the YugabyteDB cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage4.png" alt="image8" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, the results you’d see in YugabyteDB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage1.png" alt="image8" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Simple data manipulation in Swagger
&lt;/h1&gt;

&lt;p&gt;Navigate to &lt;em&gt;&lt;a href="http://localhost:9966/petclinic/swagger-ui.html" rel="noopener noreferrer"&gt;http://localhost:9966/petclinic/swagger-ui.html&lt;/a&gt;&lt;/em&gt; and locate the &lt;code&gt;pet-rest-controller&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage5.png" alt="image9" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s add a pet named “Maxine” and assign her to the owner we just created named “Richard.” We can make a POST with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "birthDate": "2020/07/20",
  "id": 0,
  "name": "Maxine",
  "owner": {
    "address": "string",
    "city": "string",
    "firstName": "string",
    "id": 101,
    "lastName": "string",
    "pets": [
      null
    ],
    "telephone": "string"
  },
  "type": {
    "id": 2,
    "name": "string"
  },
  "visits": [
    {
      "date": "yyyy/MM/dd",
      "description": "string",
      "id": 0
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After execution, in the Angular UI we should see that the owner “Richard” now has a pet named “Maxine”. This tells us that the POST successfully inputted the data into YugabyteDB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3lr6t13cowm230cj0q42yphj-wpengine.netdna-ssl.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fimage2.png" alt="image10" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s it! You now have the REST version of the Spring PetClinic running on top of a 3 node YugabyteDB cluster on GKE, with an Angular frontend. For more information about how to build Spring applications with YugabyteDB backends, check the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.yugabyte.com/latest/reference/drivers/spring-data-yugabytedb/" rel="noopener noreferrer"&gt;Spring Data YugabyteDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.yugabyte.com/latest/quick-start/build-apps/java/ysql-spring-data/" rel="noopener noreferrer"&gt;Spring Data JPA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yugabyte/jdbc-yugabytedb" rel="noopener noreferrer"&gt;YugabyteDB JDBC Driver&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>spring</category>
      <category>yugabyte</category>
      <category>angular</category>
    </item>
    <item>
      <title>Geo-Distributed SQL Databases: 9 Techniques to Reduce Cross-Region Latency</title>
      <dc:creator>Jimmy Guerrero</dc:creator>
      <pubDate>Wed, 19 Aug 2020 20:43:03 +0000</pubDate>
      <link>https://dev.to/yugabyte/geo-distributed-sql-databases-9-techniques-to-reduce-cross-region-latency-5b17</link>
      <guid>https://dev.to/yugabyte/geo-distributed-sql-databases-9-techniques-to-reduce-cross-region-latency-5b17</guid>
      <description>&lt;p&gt;Here's a webinar playback on how to stretch database clusters across 3 or more regions while at the same time reducing cross-region latency.&lt;/p&gt;

&lt;p&gt;Delivered by my colleague Sid Choudhury, SVP of Product at Yugabyte, you can also check out the companion blog here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.yugabyte.com/9-techniques-to-build-cloud-native-geo-distributed-sql-apps-with-low-latency/" rel="noopener noreferrer"&gt;blog.yugabyte.com/9-techniques-to-build-cloud-native-geo-distributed-sql-apps-with-low-latency/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New to distributed SQL or YugabyteDB? Read on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Distributed SQL?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Distributed SQL databases are becoming popular with organizations interested in moving data infrastructure to the cloud or cloud native environments. This is often motivated by the desire to reduce TCO or move away from the horizontal scaling limitations of monolithic RDBMS like Oracle, PostgreSQL, MySQL, and SQL Server. The basic characteristics of Distributed SQL are:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They must have a SQL API for querying and modeling data, with support for traditional RDBMS features like foreign keys, partial indexes, stored procedures, and triggers.&lt;br&gt;
Automatic distributed query execution so that no single node becomes a bottleneck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should support automatic and transparent distributed data storage. This includes indexes, which should be sharded across multiple nodes of the cluster so that no single node becomes a bottleneck. Data distribution ensures high performance and high availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed SQL systems should also provide for strongly consistent replication and distributed ACID transactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper discussion about what Distributed SQL is, check out, &lt;a href="https://blog.yugabyte.com/what-is-distributed-sql/" rel="noopener noreferrer"&gt;“What is Distributed SQL?”&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is YugabyteDB?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/yugabyte/yugabyte-db" rel="noopener noreferrer"&gt;YugabyteDB&lt;/a&gt; is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. YugabyteDB is PostgreSQL wire compatible, cloud native, offers deep integration with GraphQL projects, plus supports advanced RDBMS features like stored procedures, triggers and UDFs.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>distributedsystems</category>
      <category>yugabytedb</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
