<?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: Aurel</title>
    <description>The latest articles on DEV Community by Aurel (@aurelmegn).</description>
    <link>https://dev.to/aurelmegn</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%2F67257%2F9da50825-881c-4914-bc17-01237b237c00.jpg</url>
      <title>DEV Community: Aurel</title>
      <link>https://dev.to/aurelmegn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aurelmegn"/>
    <language>en</language>
    <item>
      <title>multipart/formdata: why is it recommended</title>
      <dc:creator>Aurel</dc:creator>
      <pubDate>Sat, 17 Feb 2024 11:02:28 +0000</pubDate>
      <link>https://dev.to/aurelmegn/multipartformdata-why-is-it-recommended-461n</link>
      <guid>https://dev.to/aurelmegn/multipartformdata-why-is-it-recommended-461n</guid>
      <description>&lt;p&gt;Multipart/formdata is a way of transferring form data from a client to a server.&lt;/p&gt;

&lt;p&gt;It was first described in 1995 with the &lt;a href="https://www.rfc-editor.org/rfc/rfc1867"&gt;RFC 1867&lt;/a&gt; witch makes it one of the oldest specification about transferring huge data between computer. Let's see why is it the recommended approach to transfer some data in a client/server architecture.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TLDR&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are some reasons why it is the recommended approach to implement file upload:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Possibility to transfer different kind of data inside the same request&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Efficiency compared to bare text sending&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Supported on all internet browsers&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive into each reason:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Possibility to transfer different kind of data inside the same request&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The mulltipart/formdata specification allow sending of multiple types of content along the same request. It means that you can transfer simple text, JSON data, binary data in the payload of the request. Each part need to be separated by a &lt;strong&gt;boundary,&lt;/strong&gt; identified by a name and a content-type.&lt;/p&gt;

&lt;p&gt;In the following example, you can see that we are sending :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;form-data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and image/gif&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Type: multipart/form-data; boundary=AaB03x

   --AaB03x
   Content-Disposition: form-data; name="submit-name"

   Larry
   --AaB03x
   Content-Disposition: form-data; name="files"
   Content-Type: multipart/mixed; boundary=BbC04y

   --BbC04y
   Content-Disposition: file; filename="file1.txt"
   Content-Type: text/plain

   ... contents of file1.txt ...
   --BbC04y
   Content-Disposition: file; filename="file2.gif"
   Content-Type: image/gif
   Content-Transfer-Encoding: binary

   ...contents of file2.gif...
   --BbC04y--
   --AaB03x--
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Efficiency compared to bare text sending&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4"&gt;https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;application/x-www-form-urlencoded&lt;/strong&gt; and &lt;strong&gt;application/json&lt;/strong&gt; are designed to handle text data and not binary data. If you want to send binary data, you need to encode it in base64, which is inefficient regarding the output result size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Browser handle content negotiation:&lt;/strong&gt; The approach of sending file using JSON is not standard, and you may need to implement it yourself both on your client and the server before benefiting from it. Knowing that your browser and the server negotiate to handle the content transfer, your implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Transferring a content to the browser by default use&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported on all internet browsers
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc1867"&gt;https://www.rfc-editor.org/rfc/rfc1867&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;multipart/formdata&lt;/strong&gt; has been around for decades. It has been the norm for transferring file to a backend, and all the internet relies on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;multipart/formdata&lt;/strong&gt; is the way of transferring file, and form-data from a client to a server in an efficient way. They are some alternative, but they would be an overhead for implementation and may not be as benefiting for your development.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;next post&lt;/strong&gt;, we will dig deeper into how &lt;strong&gt;multipart/formdata&lt;/strong&gt; is structured to send different kind of data to your server.&lt;/p&gt;

</description>
      <category>http</category>
      <category>fileupload</category>
      <category>json</category>
    </item>
    <item>
      <title>How to deploy poetry based Fast-Api apps on Heroku</title>
      <dc:creator>Aurel</dc:creator>
      <pubDate>Wed, 21 Apr 2021 17:16:14 +0000</pubDate>
      <link>https://dev.to/aurelmegn/how-to-deploy-poetry-based-fast-api-on-heroku-2hd6</link>
      <guid>https://dev.to/aurelmegn/how-to-deploy-poetry-based-fast-api-on-heroku-2hd6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Fast-Api is a python framework which intended to help developers to build a modern API easily and quickly. It heavily relies on python standard typing module and Mypy for static type checking. Fast-Api is based on Starlette framework  which is ASGI framework and allow to made use of python asyncio module.&lt;/p&gt;

&lt;p&gt;Heroku is a Paas which help developers to easily deploy their app. Their offer a free plan which is enough to host an MVP or your hobby project. It can also be integrated to GitHub for automatic deployment on commit.&lt;/p&gt;

&lt;p&gt;Poetry is a dependency and virtual env management program for python like Pipenv or many others. &lt;/p&gt;

&lt;p&gt;The aims of this article is to show how you can deploy a Fast-Api project which use poetry as dependency management on Heroku. Many tutorials cover the deployment of Fast-Api on Heroku but fewer mention the particularity of poetry deployment on the Heroku platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initializing the app
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create the app on Heroku
&lt;/h3&gt;

&lt;p&gt;Creating the app with is a quite easy process. You just need to log in on &lt;a href="https://www.heroku.com/"&gt;https://www.heroku.com/&lt;/a&gt; and create a new app. Make sure to select the language you are mainly using in your application.&lt;/p&gt;

&lt;p&gt;Here we are focusing on Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the Procfile to your local project
&lt;/h3&gt;

&lt;p&gt;Heroku read the instructions to start your app from a file named Procfile, located at the root of your project.&lt;/p&gt;

&lt;p&gt;You need to set a &lt;code&gt;web&lt;/code&gt; command in your Procfile which define how to start your app. For a Fast-Api project, it is basically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uvicorn&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Poetry build pack for Heroku
&lt;/h2&gt;

&lt;p&gt;To be able to install your Poetry dependencies, you need to add  a poetry build pack to your Heroku app. The poetry build pack helps Heroku to figure out how to install those dependencies defined in the &lt;code&gt;pyproject.toml&lt;/code&gt;  as Heroku do not support Poetry by default as dependency manager. &lt;/p&gt;

&lt;p&gt;If you already install the &lt;a href="https://devcenter.heroku.com/articles/using-the-cli"&gt;heroku-cli&lt;/a&gt; app, you could easily add the build pack by issuing the following instructions in your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;heroku buildpacks:clear
heroku buildpacks:add https://github.com/moneymeets/python-poetry-buildpack.git
heroku buildpacks:add heroku/python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/moneymeets/python-poetry-buildpack"&gt;moneymeets/python-poetry-buildpack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The build pack help to create a &lt;code&gt;requirement.txt&lt;/code&gt; file from your &lt;code&gt;pyproject.lock&lt;/code&gt; during the build on Heroku. &lt;/p&gt;

&lt;p&gt;Your Heroku app is now configured to run properly. Let me share with you &lt;a href="https://github.com/sdkcodes/heroku-config"&gt;this&lt;/a&gt; script that is useful for setting env var on Heroku. If you have a bunch of env vars to set up during your app creation on Heroku, then you will definitely need this script. It simply helps to set env var from a local .env.&lt;/p&gt;

&lt;p&gt;I hope this post will helps you in a way. &lt;br&gt;
You can follow me on &lt;a href="//twitter.com/aurelmegn"&gt;Twitter&lt;/a&gt; if you like the content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related posts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/how-to-deploy-your-fastapi-app-on-heroku-for-free-8d4271a4ab9"&gt;How to Deploy Your FastAPI App on Heroku for Free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/autodeploy-fastapi-app-to-heroku-via-git-in-these-5-easy-steps-8c7958ef5d41"&gt;Autodeploy FastAPI App to Heroku via Git in these 5 Easy Steps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>heroku</category>
      <category>fastapi</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Clean architecture use in real world</title>
      <dc:creator>Aurel</dc:creator>
      <pubDate>Sun, 26 Jan 2020 06:42:58 +0000</pubDate>
      <link>https://dev.to/aurelmegn/clean-architecture-use-in-real-world-3dd1</link>
      <guid>https://dev.to/aurelmegn/clean-architecture-use-in-real-world-3dd1</guid>
      <description>&lt;p&gt;Software architecture lectures brought me to clean architecture and onions architecture notions,&lt;br&gt;
I would like to know if those architectural styles are really used in enterprises or if people really adopt them. I'm asking this because there is no concrete resources to use as example on GitHub.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Setting up distributed database architecture with postgresql</title>
      <dc:creator>Aurel</dc:creator>
      <pubDate>Sun, 20 Oct 2019 11:41:04 +0000</pubDate>
      <link>https://dev.to/aurelmegn/setting-up-distributed-database-architecture-with-postgresql-261</link>
      <guid>https://dev.to/aurelmegn/setting-up-distributed-database-architecture-with-postgresql-261</guid>
      <description>&lt;h2&gt;
  
  
  What is a distributed database
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Distributed_database" rel="noopener noreferrer"&gt;Distributed databases&lt;/a&gt;  are a set of databases split across different locations which communicate and provide services through a network.&lt;/p&gt;

&lt;p&gt;A well designed distributed database should provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a network transparency: the end users should not know that the database is split across different locations, they should run queries as they do in a normal database architecture &lt;/li&gt;
&lt;li&gt;a architecture transparency: the users don't know the architecture behind the database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pros and cons of distributed databases
&lt;/h2&gt;

&lt;p&gt;/!\ you do not make a distributed database architecture because you want it, but because your project need it. Distributed databases provide (when they are well designed)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easily scale-out of you entire production &lt;/li&gt;
&lt;li&gt;easy to set up replication to maintain your data's integrity&lt;/li&gt;
&lt;li&gt;high availability&lt;/li&gt;
&lt;li&gt;fail over&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;some cons are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;not easy to maintain &lt;/li&gt;
&lt;li&gt;not easy to set up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, we will use postgresql as DBMS to set up our architecture:.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case study
&lt;/h2&gt;

&lt;p&gt;Let consider this relational model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkwh7ro5g6s12ojl4ls93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkwh7ro5g6s12ojl4ls93.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It describes a scenario where students can lend book sample from a library. Let assume that the library is split into two cities: (Paris, and Lagos). In the generated queries of our application, we notice that many queries are of this kind:&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;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lendable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'lagos'&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;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lendable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'paris'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To speed up queries execution, we decide to set up a distributed databases in out two sites, Paris and Lagos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partitionning
&lt;/h2&gt;

&lt;p&gt;Many methods of tables partitioning exists and are use in distributed databases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Horizontal partitioning&lt;/strong&gt;: its about splitting the rows according to the values of the attributes of the table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vertical partitioning&lt;/strong&gt;: its about splitting the columns of the table into different servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, we will do a &lt;strong&gt;horizontal partitioning&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From the above queries , we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;partition booksample table into two tables:

&lt;ul&gt;
&lt;li&gt;booksample_paris&lt;/li&gt;
&lt;li&gt;booksample_lagos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;partition lend table into two tables:

&lt;ul&gt;
&lt;li&gt;lend_paris&lt;/li&gt;
&lt;li&gt;lend_lagos&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0hj7zav2qypralfi9dt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0hj7zav2qypralfi9dt1.png" alt="partitions of the architectures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;/!\ &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the intersection of the partitions of a table should be null &lt;/li&gt;
&lt;li&gt;the union of the partitions of a table should contain all the rows of the initial table&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  On the master server
&lt;/h2&gt;

&lt;p&gt;Let create the different table on the master database.&lt;/p&gt;

&lt;p&gt;The master database is the one at the front of the user, we will create the tables as normal table to start. Here we would use the Paris's server as the master.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;create the database:&lt;/strong&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="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="n"&gt;dd_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;create the tables student and book:&lt;/strong&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="c1"&gt;--table student&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&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="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;--table book&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&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="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;table booksample:&lt;/strong&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="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&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="k"&gt;state&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lendable&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;references&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;table lend:&lt;/strong&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="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;lend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;references&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;booksample_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;references&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;at&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;returned_at&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  On Paris's server
&lt;/h2&gt;

&lt;p&gt;In this example, as we are using the Paris's site as master, this query should be run on the same postgres server as the previous one. Let create the tables &lt;strong&gt;booksample_paris&lt;/strong&gt; and &lt;strong&gt;lend_paris&lt;/strong&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="c1"&gt;-- paris site&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;booksample_paris&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;booksample_paris&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paris'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend_paris&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend_paris&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lend&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;check(location='paris')&lt;/code&gt; will help postgres to fetch the row in a &lt;strong&gt;"smart"&lt;/strong&gt; way.&lt;/p&gt;

&lt;p&gt;I use the &lt;strong&gt;inherits&lt;/strong&gt; keyword to tell postgres that the table &lt;strong&gt;booksample_paris&lt;/strong&gt; is actually a part of the table &lt;strong&gt;booksample&lt;/strong&gt;. Thus, when we issue a:&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;explain&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we get&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;dd_test&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; explain &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; from booksample&lt;span class="p"&gt;;&lt;/span&gt;
                                  QUERY PLAN                                  
&lt;span class="nt"&gt;------------------------------------------------------------------------------&lt;/span&gt;
 Append  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.00..151.56 &lt;span class="nv"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1251 &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;104&lt;span class="o"&gt;)&lt;/span&gt;
   -&amp;gt;  Seq Scan on booksample  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.00..0.00 &lt;span class="nv"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;104&lt;span class="o"&gt;)&lt;/span&gt;
   -&amp;gt;  Seq Scan on booksample_paris  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.00..16.10 &lt;span class="nv"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;610 &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;104&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;3 rows&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It means that postgres will try to grab the rows of the table &lt;strong&gt;booksample_paris&lt;/strong&gt; on a &lt;strong&gt;select&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  On Lagos's server
&lt;/h2&gt;

&lt;p&gt;Let's create the database&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;database&lt;/span&gt; &lt;span class="n"&gt;dd_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are going to set up the postgres server to listen to the other network interfaces. This is done by modifying the configuration file located at (on most Linux os) &lt;code&gt;/etc/postgresql/9.5/main/postgresql.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# CONNECTIONS AND AUTHENTICATION&lt;/span&gt;
&lt;span class="c"&gt;#------------------------------------------------------------------------------&lt;/span&gt;

&lt;span class="c"&gt;# - Connection Settings -&lt;/span&gt;

listen_addresses &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt;      &lt;span class="c"&gt;# what IP address(es) to listen on;&lt;/span&gt;
                    &lt;span class="c"&gt;# comma-separated list of addresses;&lt;/span&gt;
                    &lt;span class="c"&gt;# defaults to 'localhost'; use '*' for all&lt;/span&gt;
                    &lt;span class="c"&gt;# (change requires restart)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The next step is to allow a user to connect through the network interfaces by modifying &lt;code&gt;/etc/postgresql/9.5/main/pg_hba.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# TYPE  DATABASE        USER            ADDRESS                 METHOD&lt;/span&gt;

&lt;span class="c"&gt;# IPv4 local connections:&lt;/span&gt;
host    all             test_user       all                     md5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create now the partitions tables:&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="c1"&gt;-- booksample_lagos&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lendable&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- lend_lagos&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend_lagos&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;lend_lagos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;at&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;returned_at&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  On the master server
&lt;/h2&gt;

&lt;p&gt;We will use the &lt;strong&gt;foreign table ** feature of postgres to be able to access the **Lagos's database&lt;/strong&gt; tables remotely from the &lt;strong&gt;master server&lt;/strong&gt; . To be able to do this, we should create the &lt;strong&gt;postgres_fdw&lt;/strong&gt; extension in our database. This action should be done only by an administrator, so let's connect to the database as the administrator &lt;strong&gt;postgres&lt;/strong&gt; user and do:&lt;/p&gt;

&lt;p&gt;/!\ There are many alternatives to foreign table use, such as the use of &lt;a href="https://www.postgresql.org/docs/9.3/sql-creatematerializedview.html" rel="noopener noreferrer"&gt;&lt;strong&gt;materialized views + triggers&lt;/strong&gt;&lt;/a&gt; or &lt;strong&gt;&lt;a href="https://www.postgresql.org/docs/10/ddl-partitioning.html" rel="noopener noreferrer"&gt;postgres partitioning&lt;/a&gt;&lt;/strong&gt; feature.&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="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;postgres_fdw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;master_server&lt;/span&gt; &lt;span class="k"&gt;foreign&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt; &lt;span class="n"&gt;postgres_fdw&lt;/span&gt; &lt;span class="k"&gt;options&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;host&lt;/span&gt; &lt;span class="s1"&gt;'{ip address of the lagos postgres server}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="s1"&gt;'5432'&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dbname&lt;/span&gt; &lt;span class="s1"&gt;'dd_test'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;master_user&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;master_server&lt;/span&gt; &lt;span class="k"&gt;options&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="s1"&gt;'{our username on lagos server}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="s1"&gt;'{our password on lagos server}'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;alter&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;master_server&lt;/span&gt; &lt;span class="k"&gt;owner&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;master_user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we create the extension &lt;strong&gt;&lt;a href="https://wiki.postgresql.org/wiki/Foreign_data_wrappers" rel="noopener noreferrer"&gt;postgres_fdw&lt;/a&gt;&lt;/strong&gt; and after a &lt;strong&gt;"foreign data server"&lt;/strong&gt; on the master postgres server. We now create a user mapping to be able to query the &lt;strong&gt;Lagos server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's create the foreign tables located on the &lt;strong&gt;master server&lt;/strong&gt; which map to the shard on the &lt;strong&gt;Lagos servers&lt;/strong&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="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;foreign&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;foreign&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'lagos'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;master_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;foreign&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend_lagos&lt;/span&gt; &lt;span class="k"&gt;cascade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;foreign&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;lend_lagos&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;master_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In its actual state, the &lt;strong&gt;master server&lt;/strong&gt;  will fill the the table &lt;strong&gt;booksample&lt;/strong&gt; and &lt;strong&gt;lend&lt;/strong&gt; when a query like this is executed.&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;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'new'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'paris'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a good behavior as the new partitions we created will not hold any data. To fix this situation, we will use &lt;strong&gt;"triggers"&lt;/strong&gt; to redirect the row into their normal destination.&lt;/p&gt;

&lt;p&gt;The trigger bellows is to redirect the &lt;strong&gt;booksample&lt;/strong&gt; insertion into the correct partition: either &lt;strong&gt;booksample_lagos&lt;/strong&gt; or &lt;strong&gt;booksample_paris&lt;/strong&gt; based on the value of attribute location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plsql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- trigger on insert booksample&lt;/span&gt;
&lt;span class="kr"&gt;create&lt;/span&gt; &lt;span class="kr"&gt;or&lt;/span&gt; &lt;span class="kr"&gt;replace&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt; &lt;span class="n"&gt;booksample_trigger_fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paris&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
        &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;into&lt;/span&gt; &lt;span class="n"&gt;booksample_paris&lt;/span&gt; &lt;span class="kr"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lagos&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
        &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;into&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt; &lt;span class="kr"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kr"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;language&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;drop&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kr"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;booksample_trigger&lt;/span&gt; &lt;span class="kr"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="kr"&gt;create&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="n"&gt;booksample_trigger&lt;/span&gt; &lt;span class="k"&gt;before&lt;/span&gt; &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt; &lt;span class="k"&gt;execute&lt;/span&gt; &lt;span class="k"&gt;procedure&lt;/span&gt; &lt;span class="n"&gt;booksample_trigger_fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

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

&lt;/div&gt;



&lt;p&gt;Now, we would like to redirect the queries on the table &lt;strong&gt;lend&lt;/strong&gt; to the correct partition. Here we store the row into the site where the booksample belongs to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plsql"&gt;&lt;code&gt;
&lt;span class="kr"&gt;create&lt;/span&gt; &lt;span class="kr"&gt;or&lt;/span&gt; &lt;span class="kr"&gt;replace&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt; &lt;span class="n"&gt;lend_trigger_fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="kr"&gt;as&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;vbooksample&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="na"&gt;%rowtype&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="c1"&gt;-- select the booksample referenced by the booksample_id&lt;/span&gt;
    &lt;span class="kr"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;into&lt;/span&gt; &lt;span class="n"&gt;vbooksample&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt; &lt;span class="k"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;booksample_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;-- get the location to use and save the row&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vbooksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paris&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
        &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;into&lt;/span&gt; &lt;span class="n"&gt;lend_paris&lt;/span&gt; &lt;span class="kr"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;vbooksample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lagos&lt;/span&gt;&lt;span class="o"&gt;'&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
        &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;into&lt;/span&gt; &lt;span class="n"&gt;lend_lagos&lt;/span&gt; &lt;span class="kr"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kr"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;endtut&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;language&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;drop&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kr"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;lend_trigger&lt;/span&gt; &lt;span class="kr"&gt;on&lt;/span&gt; &lt;span class="n"&gt;lend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="kr"&gt;create&lt;/span&gt; &lt;span class="kr"&gt;trigger&lt;/span&gt; &lt;span class="n"&gt;lend_trigger&lt;/span&gt; &lt;span class="k"&gt;before&lt;/span&gt; &lt;span class="kr"&gt;insert&lt;/span&gt; &lt;span class="kr"&gt;on&lt;/span&gt; &lt;span class="n"&gt;lend&lt;/span&gt; &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="k"&gt;each&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt; &lt;span class="k"&gt;execute&lt;/span&gt; &lt;span class="k"&gt;procedure&lt;/span&gt; &lt;span class="n"&gt;lend_trigger_fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our database is now functional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test
&lt;/h2&gt;

&lt;p&gt;Let's run some query to get an overview of our database capabilities:&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;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'book#1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'std#1'&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="s1"&gt;'std#2'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'std#3'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- thanks to the trigger we wrote, the insertion will be executed in the right server &lt;/span&gt;
&lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lendable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'old'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'lagos'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'old'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'paris'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'new'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="s1"&gt;'lagos'&lt;/span&gt;&lt;span class="p"&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;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;lend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booksample_id&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&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;now&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let see what happen when we try to select all the row.&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;explain&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- thanks to the check(location='{}') constraint, the select query is executed in a "smart" way &lt;/span&gt;
&lt;span class="k"&gt;explain&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'lagos'&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;PLAN&lt;/span&gt;                                

&lt;span class="c1"&gt;----------------------------------------------------------------------------&lt;/span&gt;
 &lt;span class="n"&gt;Append&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;Seq&lt;/span&gt; &lt;span class="n"&gt;Scan&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="k"&gt;rows&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;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'lagos'&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="k"&gt;Foreign&lt;/span&gt; &lt;span class="n"&gt;Scan&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample_lagos&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;explain&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'paris'&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;PLAN&lt;/span&gt;                                

&lt;span class="c1"&gt;----------------------------------------------------------------------------&lt;/span&gt;
 &lt;span class="n"&gt;Append&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;Seq&lt;/span&gt; &lt;span class="n"&gt;Scan&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="k"&gt;rows&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;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'paris'&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="k"&gt;Foreign&lt;/span&gt; &lt;span class="n"&gt;Scan&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;booksample_paris&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cost&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to the &lt;code&gt;check(location='{}')&lt;/code&gt; constraint, the select query is executed in a "smart" way. The DBMS scan only the table on Paris's server or Lagos's server.&lt;/p&gt;

&lt;p&gt;Thank you for your attention.&lt;/p&gt;

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