This tutorial is the 5th of a long series of magento2 tutorial. It will be updated as the platform evolves. You will now learn how to create sql setup to automatically process the installation of your Magento2 module. If you do not know magento (v1) it does not matter, I'll talk about it a little but it is not necessary to know the magento platform (v1) to master this tutorial on magento2.
In the previous tutorial we saw how to create a block under magento2 for our extension! We will now see how to start a process that adds a table to our database automatically at the installation of our module. For that, we will take the files of the previous tutorial.
 What is the version of our module?
Go to  /app/code/Pfay/Contacts/etc/module.xml and verify that the version of our module magento2 is 0.1.0.
<module name="Pfay_Contacts" setup_version="0.1.0">
Creating our installation process for magento2 
Now we will create the file that will be launched during the installation of our module, under magento it is always called in the same way: 
InstallSchema and when called it executes the 
install function.
Create the file /app/code/Pfay/Contacts/Setup/InstallSchema.php like this:
<?php
namespace Pfay\Contacts\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
 * @codeCoverageIgnore
 */
class InstallSchema implements InstallSchemaInterface
{
    /**
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @throws \Zend_Db_Exception
     */
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        /**
         * Create table 'pfay_contacts'
         */
        if (!$setup->getConnection()->isTableExists($setup->getTable('pfay_contacts'))) {
            $table = $setup->getConnection()
                ->newTable($setup->getTable('pfay_contacts'))
                ->addColumn(
                    'pfay_contacts_id',
                    \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
                    null,
                    ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
                    'Contacts ID'
                )
                ->addColumn(
                    'name',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    100,
                    ['nullable' => false, 'default' => 'simple'],
                    'Name'
                )
                ->addColumn(
                    'email',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    100,
                    ['nullable' => false, 'default' => 'simple'],
                    'Email'
                )
                ->setComment('Pfay Contacts Table')
                ->setOption('type', 'InnoDB')
                ->setOption('charset', 'utf8');
            $setup->getConnection()->createTable($table);
        }
        $setup->endSetup();
    }
}
In this setup, we create the table in database that will be used for the continuation of the tutorials.
You notice the 
 getTable  function that just makes sure to format the table name, no need to declare 'pfay_contacts' elsewhere (as on magento1).
This creates the table with the 
 newTable  function and adds columns with 
 addColumn , a comment with 
 setComment 
And we specify options linked to the database with 
 setOption 
The table is then stored in the database from the connection and the 
 createTable  function.
As for magento1, an installer starts with 
 startSetup  and ends with 
 endSetup  Enable the module, update the tables and assign the rights to the cache 
Via the following commands:
php bin/magento module:enable Pfay_Contacts
php bin/magento setup:upgrade 
chmod 777 -R var/
We then verify that the table has been created:
mysql> show tables where Tables_in_magento2 like '%pfay%';         
+--------------------+
| Tables_in_magento2 |
+--------------------+
| pfay_contacts      |
+--------------------+
1 row in set (0.01 sec)
mysql> select * from pfay_contacts;
Empty set (0.00 sec)
mysql> describe pfay_contacts;     
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| pfay_contacts_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name             | varchar(100)     | NO   |     | simple  |                |
| email            | varchar(100)     | NO   |     | simple  |                |
+------------------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
Apparently it looks pretty good;)
Upgrade of a magento2 module
To do an upgrade (the updates our module if we need to change it after the installation) we will add a comment field (of type TEXT). 
The ugrade of a magento module always uses its 
 UpgradeSchema  file and executes the 
 upgrade  method
We create the file /app/code/Pfay/Contacts/Setup/UpgradeSchema.php like this: 
On
<?php
namespace Pfay\Contacts\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Catalog\Model\ResourceModel\Product\Gallery;
use Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter;
/**
 * Upgrade the Catalog module DB scheme
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * {@inheritdoc}
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        if (version_compare($context->getVersion(), '0.2.0', '<')) {
            $tableName = $setup->getTable('pfay_contacts');
            $setup->getConnection()->addColumn($tableName, 'comment', [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                'length'    => 255,
                'unsigned' => true,
                'nullable' => false,
                'default' => '0',
                'comment' => 'Comment'
            ]);
        }
        $setup->endSetup();
    }
}
Here we still format the table name with 
 getTable  then we add it with the 
 addColumn  method of the connection. 
We also start with 
 startSetup  and we finish with 
 endSetup 
<?php
namespace Pfay\Contacts\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Catalog\Model\ResourceModel\Product\Gallery;
use Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter;
/**
 * Upgrade the Catalog module DB scheme
 */
class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * {@inheritdoc}
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();
        if (version_compare($context->getVersion(), '0.2.0', '<')) {
            $tableName = $setup->getTable('pfay_contacts');
            $setup->getConnection()->addColumn($tableName, 'comment', [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                'length'    => 255,
                'unsigned' => true,
                'nullable' => false,
                'default' => '0',
                'comment' => 'Comment'
            ]);
        }
        $setup->endSetup();
    }
}
The current numbers of the magento module versions are defined in the setup_module table, if you have already installed your module and you finally want to restart the update here is how:
mysql> update setup_module set schema_version='0.1.0', data_version='0.1.0' where module like 'Pfay_Contacts';
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0
Effectively ... we just delete the line in the table (if we want to restart the installer) or update to the desired version if we want to restart the update. 
Finally, we have:
mysql> update setup_module set schema_version='0.1.0', data_version='0.1.0' where module like 'Pfay_Contacts';
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0
We update our module number:
<module name="Pfay_Contacts" setup_version="0.2.0">
We launch the update :
php bin/magento setup:db-schema:upgrade
and we finaly have :
mysql> describe pfay_contacts;                                                 
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| pfay_contacts_id | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name             | varchar(100)     | NO   |     | simple  |                |
| email            | varchar(100)     | NO   |     | simple  |                |
| comment          | varchar(255)     | NO   |     | 0       |                |
+------------------+------------------+------+-----+---------+----------------+
Some possible errors:
My table is not created during the magento2 installer:
The solution :
mysql> delete from setup_module where module like '%Pfay_Contacts';
Query OK, 1 row affected (0.04 sec)
"Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory."
The solution :
php bin/magento setup:upgrade
"Fatal error: Uncaught RuntimeException: Can't create directory /var/www/html/magento2/var/generation/Magento/Framework/App/ResourceConnection"
The solution :
chmod 777 -R var/
"Fatal error: Uncaught Zend_Cache_Exception: cache_dir "/var/www/html/magento2/var/cache/" is not writable"
The solution :
chmod 777 -R var/
There you go ! This is the end of this tutorial. Does not it work for you? Download the code below.
You now know how to add an installer to your magento2 module and how to upgrade it... Congratulations!
Do not hesitate also to ask your questions in the comments (for those who share the article), I will try to answer quickly.
Good luck at all for the continuation of these tutorials on magento2!