diff --git a/lib/internal/Magento/Framework/App/Resource.php b/lib/internal/Magento/Framework/App/Resource.php
index d76a3a68bdcafbc35eda2c73dc8b1868fb39ee61..fae3cdb761c5fc502aef804db2f7b59f492ef335 100644
--- a/lib/internal/Magento/Framework/App/Resource.php
+++ b/lib/internal/Magento/Framework/App/Resource.php
@@ -85,6 +85,7 @@ class Resource
      *
      * @param string $resourceName
      * @return \Magento\Framework\DB\Adapter\AdapterInterface|false
+     * @codeCoverageIgnore
      */
     public function getConnection($resourceName)
     {
@@ -152,12 +153,26 @@ class Resource
         return $this->getConnection($connectionName)->getTableName($tableName);
     }
 
+    /**
+     * Build a trigger name
+     *
+     * @param string $tableName  The table that is the subject of the trigger
+     * @param string $time  Either "before" or "after"
+     * @param string $event  The DB level event which activates the trigger, i.e. "update" or "insert"
+     * @return string
+     */
+    public function getTriggerName($tableName, $time, $event)
+    {
+        return $this->getConnection(self::DEFAULT_READ_RESOURCE)->getTriggerName($tableName, $time, $event);
+    }
+
     /**
      * Set mapped table name
      *
      * @param string $tableName
      * @param string $mappedName
      * @return $this
+     * @codeCoverageIgnore
      */
     public function setMappedTableName($tableName, $mappedName)
     {
@@ -193,13 +208,12 @@ class Resource
         $fields,
         $indexType = \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX
     ) {
-        return $this->getConnection(
-            self::DEFAULT_READ_RESOURCE
-        )->getIndexName(
-            $this->getTableName($tableName),
-            $fields,
-            $indexType
-        );
+        return $this->getConnection(self::DEFAULT_READ_RESOURCE)
+            ->getIndexName(
+                $this->getTableName($tableName),
+                $fields,
+                $indexType
+            );
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ResourceTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ResourceTest.php
index a92a9eb73432db63d22a8b28c104da5ec28360f4..86fc5bf7ac92bcbd89d423311a0fd3fc9be8cfbe 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/ResourceTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/ResourceTest.php
@@ -14,7 +14,7 @@ use Magento\Framework\Config\ConfigOptionsListConstants;
 class ResourceTest extends \PHPUnit_Framework_TestCase
 {
     const RESOURCE_NAME = \Magento\Framework\App\Resource::DEFAULT_READ_RESOURCE;
-    const CONNECTION_NAME = 'Connection Name';
+    const CONNECTION_NAME = 'connection-name';
     const TABLE_PREFIX = 'prefix_';
 
     /**
@@ -197,4 +197,21 @@ class ResourceTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals('fkName', $this->resource->getFkName($table, $columnName, $refTable, $refColumnName));
     }
+
+    public function testGetTriggerName()
+    {
+        $tableName = 'subject_table';
+        $time = 'before';
+        $event = 'insert';
+        $triggerName = 'trg_subject_table_before_insert';
+
+        $this->_connectionFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->connection));
+        $this->connection->expects($this->once())
+            ->method('getTriggerName')
+            ->with($tableName, $time, $event)
+            ->willReturn($triggerName);
+        $this->assertSame($triggerName, $this->resource->getTriggerName($tableName, $time, $event));
+    }
 }
diff --git a/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php b/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
index 96eb992ade3f58cd9e3d6860c36fc1310baacd4b..ed43451bfa848d1bc40599fa074d113ea7e03670 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
@@ -918,6 +918,17 @@ interface AdapterInterface
      */
     public function getTableName($tableName);
 
+
+    /**
+     * Build a trigger name based on table name and trigger details
+     *
+     * @param string $tableName  The table that is the subject of the trigger
+     * @param string $time  Either "before" or "after"
+     * @param string $event  The DB level event which activates the trigger, i.e. "update" or "insert"
+     * @return string
+     */
+    public function getTriggerName($tableName, $time, $event);
+
     /**
      * Retrieve valid index name
      * Check index name length and allowed symbols
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index 013e4148ba4ba36bcc194a825f3cbf79dec4238b..0ea7863c01942408729bcd06527301cb7f1eac48 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -19,6 +19,7 @@ use Magento\Framework\DB\Profiler;
 use Magento\Framework\DB\Select;
 use Magento\Framework\DB\Statement\Parameter;
 use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Mview\View\Subscription;
 use Magento\Framework\Phrase;
 use Magento\Framework\Stdlib\DateTime;
 use Magento\Framework\Stdlib\String;
@@ -3115,47 +3116,31 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
     }
 
     /**
-     * Minus superfluous characters from hash.
+     * Returns a compressed version of the table name if it is too long
      *
-     * @param  string $hash
-     * @param  string $prefix
-     * @param  int $maxCharacters
+     * @param string $tableName
      * @return string
+     * @codeCoverageIgnore
      */
-    protected function _minusSuperfluous($hash, $prefix, $maxCharacters)
+    public function getTableName($tableName)
     {
-        $diff        = strlen($hash) + strlen($prefix) -  $maxCharacters;
-        $superfluous = $diff / 2;
-        $odd         = $diff % 2;
-        $hash        = substr($hash, $superfluous, - ($superfluous + $odd));
-        return $hash;
+        return ExpressionConverter::shortenEntityName($tableName, 't_');
     }
 
     /**
-     * Retrieve valid table name
-     * Check table name length and allowed symbols
+     * Build a trigger name based on table name and trigger details
      *
-     * @param string $tableName
+     * @param string $tableName  The table which is the subject of the trigger
+     * @param string $time  Either "before" or "after"
+     * @param string $event  The DB level event which activates the trigger, i.e. "update" or "insert"
      * @return string
+     * @codeCoverageIgnore
      */
-    public function getTableName($tableName)
-    {
-        $prefix = 't_';
-        if (strlen($tableName) > self::LENGTH_TABLE_NAME) {
-            $shortName = ExpressionConverter::shortName($tableName);
-            if (strlen($shortName) > self::LENGTH_TABLE_NAME) {
-                $hash = md5($tableName);
-                if (strlen($prefix . $hash) > self::LENGTH_TABLE_NAME) {
-                    $tableName = $this->_minusSuperfluous($hash, $prefix, self::LENGTH_TABLE_NAME);
-                } else {
-                    $tableName = $prefix . $hash;
-                }
-            } else {
-                $tableName = $shortName;
-            }
-        }
 
-        return $tableName;
+    public function getTriggerName($tableName, $time, $event)
+    {
+        $triggerName = 'trg_' . $tableName . '_' . $time . '_' . $event;
+        return ExpressionConverter::shortenEntityName($triggerName, 'trg_');
     }
 
     /**
@@ -3176,35 +3161,15 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
         switch (strtolower($indexType)) {
             case AdapterInterface::INDEX_TYPE_UNIQUE:
                 $prefix = 'unq_';
-                $shortPrefix = 'u_';
                 break;
             case AdapterInterface::INDEX_TYPE_FULLTEXT:
                 $prefix = 'fti_';
-                $shortPrefix = 'f_';
                 break;
             case AdapterInterface::INDEX_TYPE_INDEX:
             default:
                 $prefix = 'idx_';
-                $shortPrefix = 'i_';
-        }
-
-        $hash = $tableName . '_' . $fields;
-
-        if (strlen($hash) + strlen($prefix) > self::LENGTH_INDEX_NAME) {
-            $short = ExpressionConverter::shortName($prefix . $hash);
-            if (strlen($short) > self::LENGTH_INDEX_NAME) {
-                $hash = md5($hash);
-                if (strlen($hash) + strlen($shortPrefix) > self::LENGTH_INDEX_NAME) {
-                    $hash = $this->_minusSuperfluous($hash, $shortPrefix, self::LENGTH_INDEX_NAME);
-                }
-            } else {
-                $hash = $short;
-            }
-        } else {
-            $hash = $prefix . $hash;
         }
-
-        return strtoupper($hash);
+        return strtoupper(ExpressionConverter::shortenEntityName($tableName . '_' . $fields, $prefix));
     }
 
     /**
@@ -3216,28 +3181,12 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * @param string $refTableName
      * @param string $refColumnName
      * @return string
+     * @codeCoverageIgnore
      */
     public function getForeignKeyName($priTableName, $priColumnName, $refTableName, $refColumnName)
     {
-        $prefix = 'fk_';
-        $hash = sprintf('%s_%s_%s_%s', $priTableName, $priColumnName, $refTableName, $refColumnName);
-        if (strlen($prefix . $hash) > self::LENGTH_FOREIGN_NAME) {
-            $short = ExpressionConverter::shortName($prefix . $hash);
-            if (strlen($short) > self::LENGTH_FOREIGN_NAME) {
-                $hash = md5($hash);
-                if (strlen($prefix . $hash) > self::LENGTH_FOREIGN_NAME) {
-                    $hash = $this->_minusSuperfluous($hash, $prefix, self::LENGTH_FOREIGN_NAME);
-                } else {
-                    $hash = $prefix . $hash;
-                }
-            } else {
-                $hash = $short;
-            }
-        } else {
-            $hash = $prefix . $hash;
-        }
-
-        return strtoupper($hash);
+        $fkName = sprintf('%s_%s_%s_%s', $priTableName, $priColumnName, $refTableName, $refColumnName);
+        return strtoupper(ExpressionConverter::shortenEntityName($fkName, 'fk_'));
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/DB/ExpressionConverter.php b/lib/internal/Magento/Framework/DB/ExpressionConverter.php
index 2df91ab77991222d8f1814134020df7e3d45dc1e..9a9b2d7eacf4797821fded20bf885edb7367ea00 100644
--- a/lib/internal/Magento/Framework/DB/ExpressionConverter.php
+++ b/lib/internal/Magento/Framework/DB/ExpressionConverter.php
@@ -10,7 +10,12 @@ namespace Magento\Framework\DB;
 class ExpressionConverter
 {
     /**
-     * Dictionary for generate short name
+     * Maximum length for many MySql identifiers, including database, table, trigger, and column names
+     */
+    const MYSQL_IDENTIFIER_LEN = 64;
+
+    /**
+     * Dictionary maps common words in identifiers to abbreviations
      *
      * @var array
      */
@@ -62,7 +67,7 @@ class ExpressionConverter
     ];
 
     /**
-     * Convert name using dictionary
+     * Shorten name by abbreviating words
      *
      * @param string $name
      * @return string
@@ -73,7 +78,7 @@ class ExpressionConverter
     }
 
     /**
-     * Add or replace translate to dictionary
+     * Add an abbreviation to the dictionary, or replace if it already exists
      *
      * @param string $from
      * @param string $to
@@ -83,4 +88,47 @@ class ExpressionConverter
     {
         self::$_translateMap[$from] = $to;
     }
+
+    /**
+     * Shorten the name of a MySql identifier, by abbreviating common words and hashing if necessary. Prepends the
+     * given prefix to clarify what kind of entity the identifier represents, in case hashing is used.
+     *
+     * @param string $entityName
+     * @param string $prefix
+     * @return string
+     */
+    public static function shortenEntityName($entityName, $prefix)
+    {
+        if (strlen($entityName) > self::MYSQL_IDENTIFIER_LEN) {
+            $shortName = ExpressionConverter::shortName($entityName);
+            if (strlen($shortName) > self::MYSQL_IDENTIFIER_LEN) {
+                $hash = md5($entityName);
+                if (strlen($prefix . $hash) > self::MYSQL_IDENTIFIER_LEN) {
+                    $entityName = self::trimHash($hash, $prefix, self::MYSQL_IDENTIFIER_LEN);
+                } else {
+                    $entityName = $prefix . $hash;
+                }
+            } else {
+                $entityName = $shortName;
+            }
+        }
+        return $entityName;
+    }
+
+    /**
+     * Remove superfluous characters from hash
+     *
+     * @param  string $hash
+     * @param  string $prefix
+     * @param  int $maxCharacters
+     * @return string
+     */
+    private static function trimHash($hash, $prefix, $maxCharacters)
+    {
+        $diff        = strlen($hash) + strlen($prefix) -  $maxCharacters;
+        $superfluous = $diff / 2;
+        $odd         = $diff % 2;
+        $hash        = substr($hash, $superfluous, - ($superfluous + $odd));
+        return $hash;
+    }
 }
diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php
index b7c080064bc969890c42c8ca983025f89548738c..4d7bfa42ed2eab83d5f1d5e67b31ca022cf1e8b1 100644
--- a/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php
+++ b/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php
@@ -11,6 +11,8 @@
  */
 namespace Magento\Framework\DB\Test\Unit\Adapter\Pdo;
 
+use Magento\Framework\DB\Adapter\AdapterInterface;
+
 class MysqlTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -149,7 +151,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
         } catch (\Exception $e) {
             $this->assertNotContains(
                 $e->getMessage(),
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_DDL_MESSAGE
+                AdapterInterface::ERROR_DDL_MESSAGE
             );
         }
 
@@ -160,7 +162,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
         } catch (\Exception $e) {
             $this->assertNotContains(
                 $e->getMessage(),
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_DDL_MESSAGE
+                AdapterInterface::ERROR_DDL_MESSAGE
             );
         }
     }
@@ -226,7 +228,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             throw new \Exception('Test Failed!');
         } catch (\Exception $e) {
             $this->assertEquals(
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_ASYMMETRIC_ROLLBACK_MESSAGE,
+                AdapterInterface::ERROR_ASYMMETRIC_ROLLBACK_MESSAGE,
                 $e->getMessage()
             );
         }
@@ -242,7 +244,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             throw new \Exception('Test Failed!');
         } catch (\Exception $e) {
             $this->assertEquals(
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_ASYMMETRIC_COMMIT_MESSAGE,
+                AdapterInterface::ERROR_ASYMMETRIC_COMMIT_MESSAGE,
                 $e->getMessage()
             );
         }
@@ -354,7 +356,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             throw new \Exception('Test Failed!');
         } catch (\Exception $e) {
             $this->assertEquals(
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_ROLLBACK_INCOMPLETE_MESSAGE,
+                AdapterInterface::ERROR_ROLLBACK_INCOMPLETE_MESSAGE,
                 $e->getMessage()
             );
             $this->_adapter->rollBack();
@@ -377,7 +379,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             throw new \Exception('Test Failed!');
         } catch (\Exception $e) {
             $this->assertEquals(
-                \Magento\Framework\DB\Adapter\AdapterInterface::ERROR_ROLLBACK_INCOMPLETE_MESSAGE,
+                AdapterInterface::ERROR_ROLLBACK_INCOMPLETE_MESSAGE,
                 $e->getMessage()
             );
             $this->_adapter->rollBack();
@@ -549,4 +551,28 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             ]
         ];
     }
+
+    /**
+     * @dataProvider getIndexNameDataProvider
+     */
+    public function testGetIndexName($name, $fields, $indexType, $expectedName)
+    {
+        $resultIndexName = $this->_mockAdapter->getIndexName($name, $fields, $indexType);
+        $this->assertTrue(
+            strpos($resultIndexName, $expectedName) === 0,
+            "Index name '$resultIndexName' did not begin with expected value '$expectedName'"
+        );
+    }
+
+    public function getIndexNameDataProvider()
+    {
+        // 65 characters long - will be compressed
+        $longTableName = '__________________________________________________long_table_name';
+        return [
+            [$longTableName, [], AdapterInterface::INDEX_TYPE_UNIQUE, 'UNQ_'],
+            [$longTableName, [], AdapterInterface::INDEX_TYPE_FULLTEXT, 'FTI_'],
+            [$longTableName, [], AdapterInterface::INDEX_TYPE_INDEX, 'IDX_'],
+            ['short_table_name', ['field1', 'field2'], '', 'SHORT_TABLE_NAME_FIELD1_FIELD2'],
+        ];
+    }
 }
diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/ExpressionConverterTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/ExpressionConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a184d7395918a4533cbb1462e5ab3592a9f84ed5
--- /dev/null
+++ b/lib/internal/Magento/Framework/DB/Test/Unit/ExpressionConverterTest.php
@@ -0,0 +1,57 @@
+<?php
+/***
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\DB\Test\Unit;
+
+
+use Magento\Framework\DB\ExpressionConverter;
+
+class ExpressionConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider shortenEntityNameDataProvider
+     */
+    public function testShortenEntityName($in, $prefix, $expectedOut)
+    {
+        $resultEntityName = ExpressionConverter::shortenEntityName($in, $prefix);
+        $this->assertTrue(
+            strpos($resultEntityName, $expectedOut) === 0,
+            "Entity name '$resultEntityName' did not begin with expected value '$expectedOut'"
+        );
+    }
+
+    public function shortenEntityNameDataProvider()
+    {
+        $length64 = '________________________________________________________________';
+        $length40 = '________________________________________';
+        return [
+            'Short identifier' => [
+                'already_short',
+                'pre_',
+                'already_short'
+            ],
+            'Hashed identifer' => [
+                $length64 . '_cannotBeAbbreviated',
+                'pre_',
+                'pre_'
+            ],
+            'Abbreviated identifier' => [
+                $length40 . 'enterprise_notification_index',
+                'pre_',
+                $length40 . 'ent_ntfc_idx'
+            ],
+        ];
+    }
+
+    public function testShortenEntityNameReducedHash()
+    {
+        /** Length of 64 characters, to go over max MySql identifier length */
+        $length64 = '________________________________________________________________';
+        $longPrefix = 'pre_____________________________________';
+        $shortenedName = ExpressionConverter::shortenEntityName($length64 . '_cannotBeAbbreviated', $longPrefix);
+        $this->assertNotSame(0, strpos($shortenedName, 'pre'), 'Entity name not supposed to with long prefix');
+    }
+}
diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
index 8b36902a699e2f0f56c397a9e787651c07faeb06..f9b642136422dd229deebd9762f183742646c698 100644
--- a/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
+++ b/lib/internal/Magento/Framework/Mview/Test/Unit/View/SubscriptionTest.php
@@ -12,11 +12,6 @@ use \Magento\Framework\Mview\View\Subscription;
 
 class SubscriptionTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Framework\Mview\View\Subscription
-     */
-    protected $model;
-
     /**
      * Mysql PDO DB adapter mock
      *
@@ -24,34 +19,37 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
      */
     protected $connectionMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Resource
-     */
+    /** @var \Magento\Framework\Mview\View\Subscription */
+    protected $model;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Resource */
     protected $resourceMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Ddl\TriggerFactory
-     */
+    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Ddl\TriggerFactory */
     protected $triggerFactoryMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Mview\View\CollectionInterface
-     */
+    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Mview\View\CollectionInterface */
     protected $viewCollectionMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Mview\ViewInterface
-     */
+    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Mview\ViewInterface */
     protected $viewMock;
 
+    /** @var  string */
+    private $tableName;
+
     protected function setUp()
     {
         $this->connectionMock = $this->getMock('Magento\Framework\DB\Adapter\Pdo\Mysql', [], [], '', false);
+        $this->resourceMock = $this->getMock('Magento\Framework\App\Resource', [], [], '', false, false);
+
+        $this->connectionMock->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+
+        $this->resourceMock->expects($this->atLeastOnce())
+            ->method('getConnection')
+            ->willReturn($this->connectionMock);
 
-        $this->resourceMock = $this->getMock(
-            'Magento\Framework\App\Resource', ['getConnection', 'getTableName'], [], '', false, false
-        );
-        $this->mockGetConnection($this->connectionMock);
         $this->triggerFactoryMock = $this->getMock(
             'Magento\Framework\DB\Ddl\TriggerFactory', [], [], '', false, false
         );
@@ -62,16 +60,16 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\Mview\ViewInterface', [], '', false, false, true, []
         );
 
-        $this->connectionMock->expects($this->any())
-            ->method('quoteIdentifier')
-            ->will($this->returnArgument(0));
+        $this->resourceMock->expects($this->any())
+            ->method('getTableName')
+            ->willReturn($this->tableName);
 
         $this->model = new Subscription(
             $this->resourceMock,
             $this->triggerFactoryMock,
             $this->viewCollectionMock,
             $this->viewMock,
-            'tableName',
+            $this->tableName,
             'columnName'
         );
     }
@@ -83,7 +81,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
 
     public function testGetTableName()
     {
-        $this->assertEquals('tableName', $this->model->getTableName());
+        $this->assertEquals($this->tableName, $this->model->getTableName());
     }
 
     public function testGetColumnName()
@@ -93,11 +91,14 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
 
     public function testCreate()
     {
-        $this->mockGetTableName();
-
-        $triggerMock = $this->getMock('Magento\Framework\DB\Ddl\Trigger', [], [], '', false, false);
+        $triggerName = 'trigger_name';
+        $this->resourceMock->expects($this->atLeastOnce())->method('getTriggerName')->willReturn($triggerName);
+        $triggerMock = $this->getMockBuilder('Magento\Framework\DB\Ddl\Trigger')
+            ->disableOriginalConstructor()
+            ->getMock();
         $triggerMock->expects($this->exactly(3))
             ->method('setName')
+            ->with($triggerName)
             ->will($this->returnSelf());
         $triggerMock->expects($this->exactly(3))
             ->method('getName')
@@ -111,7 +112,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnSelf());
         $triggerMock->expects($this->exactly(3))
             ->method('setTable')
-            ->with('tableName')
+            ->with($this->tableName)
             ->will($this->returnSelf());
         $triggerMock->expects($this->exactly(6))
             ->method('addStatement')
@@ -153,7 +154,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue('other_id'));
         $otherViewMock->expects($this->exactly(1))
             ->method('getSubscriptions')
-            ->will($this->returnValue([['name' => 'tableName'], ['name' => 'otherTableName']]));
+            ->will($this->returnValue([['name' => $this->tableName], ['name' => 'otherTableName']]));
         $otherViewMock->expects($this->exactly(3))
             ->method('getChangelog')
             ->will($this->returnValue($otherChangelogMock));
@@ -182,8 +183,6 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
 
     public function testRemove()
     {
-        $this->mockGetTableName();
-
         $triggerMock = $this->getMock('Magento\Framework\DB\Ddl\Trigger', [], [], '', false, false);
         $triggerMock->expects($this->exactly(3))
             ->method('setName')
@@ -200,7 +199,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnSelf());
         $triggerMock->expects($this->exactly(3))
             ->method('setTable')
-            ->with('tableName')
+            ->with($this->tableName)
             ->will($this->returnSelf());
         $triggerMock->expects($this->exactly(3))
             ->method('addStatement')
@@ -228,7 +227,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue('other_id'));
         $otherViewMock->expects($this->exactly(1))
             ->method('getSubscriptions')
-            ->will($this->returnValue([['name' => 'tableName'], ['name' => 'otherTableName']]));
+            ->will($this->returnValue([['name' => $this->tableName], ['name' => 'otherTableName']]));
         $otherViewMock->expects($this->exactly(3))
             ->method('getChangelog')
             ->will($this->returnValue($otherChangelogMock));
@@ -259,21 +258,4 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
 
         $this->model->remove();
     }
-
-    /**
-     * @param $connection
-     */
-    protected function mockGetConnection($connection)
-    {
-        $this->resourceMock->expects($this->once())
-            ->method('getConnection')
-            ->will($this->returnValue($connection));
-    }
-
-    protected function mockGetTableName()
-    {
-        $this->resourceMock->expects($this->any())
-            ->method('getTableName')
-            ->will($this->returnArgument(0));
-    }
 }
diff --git a/lib/internal/Magento/Framework/Mview/View/Subscription.php b/lib/internal/Magento/Framework/Mview/View/Subscription.php
index 498cb0e147801ef8709a89a13def616677662be3..e72c255d750ac85df31a1d4a9a1e8eb6e30d3c53 100644
--- a/lib/internal/Magento/Framework/Mview/View/Subscription.php
+++ b/lib/internal/Magento/Framework/Mview/View/Subscription.php
@@ -8,13 +8,11 @@
 
 namespace Magento\Framework\Mview\View;
 
+use Magento\Framework\App\Resource;
+use Magento\Framework\DB\Ddl\Trigger;
+
 class Subscription implements SubscriptionInterface
 {
-    /**
-     * Trigger name qualifier
-     */
-    const TRIGGER_NAME_QUALIFIER = 'trg';
-
     /**
      * Database write connection
      *
@@ -23,7 +21,7 @@ class Subscription implements SubscriptionInterface
     protected $write;
 
     /**
-     * @var \Magento\Framework\DB\Ddl\Trigger
+     * @var \Magento\Framework\DB\Ddl\TriggerFactory
      */
     protected $triggerFactory;
 
@@ -55,12 +53,12 @@ class Subscription implements SubscriptionInterface
     protected $linkedViews = [];
 
     /**
-     * @var \Magento\Framework\App\Resource
+     * @var Resource
      */
     protected $resource;
 
     /**
-     * @param \Magento\Framework\App\Resource $resource
+     * @param Resource $resource
      * @param \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory
      * @param \Magento\Framework\Mview\View\CollectionInterface $viewCollection
      * @param \Magento\Framework\Mview\ViewInterface $view
@@ -68,7 +66,7 @@ class Subscription implements SubscriptionInterface
      * @param string $columnName
      */
     public function __construct(
-        \Magento\Framework\App\Resource $resource,
+        Resource $resource,
         \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory,
         \Magento\Framework\Mview\View\CollectionInterface $viewCollection,
         \Magento\Framework\Mview\ViewInterface $view,
@@ -91,23 +89,14 @@ class Subscription implements SubscriptionInterface
      */
     public function create()
     {
-        foreach (\Magento\Framework\DB\Ddl\Trigger::getListOfEvents() as $event) {
-            $triggerName = $this->getTriggerName(
-                $this->resource->getTableName($this->getTableName()),
-                \Magento\Framework\DB\Ddl\Trigger::TIME_AFTER,
-                $event
-            );
-
-            /** @var \Magento\Framework\DB\Ddl\Trigger $trigger */
-            $trigger = $this->triggerFactory->create()->setName(
-                $triggerName
-            )->setTime(
-                \Magento\Framework\DB\Ddl\Trigger::TIME_AFTER
-            )->setEvent(
-                $event
-            )->setTable(
-                $this->resource->getTableName($this->getTableName())
-            );
+        foreach (Trigger::getListOfEvents() as $event) {
+            $triggerName = $this->getAfterEventTriggerName($event);
+            /** @var Trigger $trigger */
+            $trigger = $this->triggerFactory->create()
+                ->setName($triggerName)
+                ->setTime(Trigger::TIME_AFTER)
+                ->setEvent($event)
+                ->setTable($this->resource->getTableName($this->tableName));
 
             $trigger->addStatement($this->buildStatement($event, $this->getView()->getChangelog()));
 
@@ -131,23 +120,14 @@ class Subscription implements SubscriptionInterface
      */
     public function remove()
     {
-        foreach (\Magento\Framework\DB\Ddl\Trigger::getListOfEvents() as $event) {
-            $triggerName = $this->getTriggerName(
-                $this->resource->getTableName($this->getTableName()),
-                \Magento\Framework\DB\Ddl\Trigger::TIME_AFTER,
-                $event
-            );
-
-            /** @var \Magento\Framework\DB\Ddl\Trigger $trigger */
-            $trigger = $this->triggerFactory->create()->setName(
-                $triggerName
-            )->setTime(
-                \Magento\Framework\DB\Ddl\Trigger::TIME_AFTER
-            )->setEvent(
-                $event
-            )->setTable(
-                $this->resource->getTableName($this->getTableName())
-            );
+        foreach (Trigger::getListOfEvents() as $event) {
+            $triggerName = $this->getAfterEventTriggerName($event);
+            /** @var Trigger $trigger */
+            $trigger = $this->triggerFactory->create()
+                ->setName($triggerName)
+                ->setTime(Trigger::TIME_AFTER)
+                ->setEvent($event)
+                ->setTable($this->resource->getTableName($this->getTableName()));
 
             // Add statements for linked views
             foreach ($this->getLinkedViews() as $view) {
@@ -204,8 +184,8 @@ class Subscription implements SubscriptionInterface
     protected function buildStatement($event, $changelog)
     {
         switch ($event) {
-            case \Magento\Framework\DB\Ddl\Trigger::EVENT_INSERT:
-            case \Magento\Framework\DB\Ddl\Trigger::EVENT_UPDATE:
+            case Trigger::EVENT_INSERT:
+            case Trigger::EVENT_UPDATE:
                 return sprintf(
                     "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);",
                     $this->write->quoteIdentifier($this->resource->getTableName($changelog->getName())),
@@ -213,7 +193,7 @@ class Subscription implements SubscriptionInterface
                     $this->write->quoteIdentifier($this->getColumnName())
                 );
 
-            case \Magento\Framework\DB\Ddl\Trigger::EVENT_DELETE:
+            case Trigger::EVENT_DELETE:
                 return sprintf(
                     "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);",
                     $this->write->quoteIdentifier($this->resource->getTableName($changelog->getName())),
@@ -227,25 +207,26 @@ class Subscription implements SubscriptionInterface
     }
 
     /**
-     * Retrieve trigger name
+     * Build an "after" event for the given table and event
      *
-     * Build a trigger name by concatenating trigger name prefix, table name,
-     * trigger time and trigger event.
+     * @param string $event The DB level event, like "update" or "insert"
      *
-     * @param string $tableName
-     * @param string $time
-     * @param string $event
      * @return string
      */
-    protected function getTriggerName($tableName, $time, $event)
+    private function getAfterEventTriggerName($event)
     {
-        return self::TRIGGER_NAME_QUALIFIER . '_' . $tableName . '_' . $time . '_' . $event;
+        return $this->resource->getTriggerName(
+            $this->resource->getTableName($this->getTableName()),
+            Trigger::TIME_AFTER,
+            $event
+        );
     }
 
     /**
      * Retrieve View related to subscription
      *
      * @return \Magento\Framework\Mview\ViewInterface
+     * @codeCoverageIgnore
      */
     public function getView()
     {
@@ -256,6 +237,7 @@ class Subscription implements SubscriptionInterface
      * Retrieve table name
      *
      * @return string
+     * @codeCoverageIgnore
      */
     public function getTableName()
     {
@@ -266,6 +248,7 @@ class Subscription implements SubscriptionInterface
      * Retrieve table column name
      *
      * @return string
+     * @codeCoverageIgnore
      */
     public function getColumnName()
     {