diff --git a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
index c74d39afa292e3a7d2c1688da711d70c9542bfa8..78e3897e74c1ec3ebe52b83750c12173e5da6548 100644
--- a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
+++ b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
@@ -44,7 +44,44 @@ class ConnectionMigrator
     /**
      * @var int
      */
-    protected $maxTableNameLength = 64;
+    protected $tableAndFieldMaxNameLengthsPerDbPlatform = [
+        'default' => [
+            'tables' => 30,
+            'columns' => 30
+        ],
+        'mysql' => [
+            'tables' => 64,
+            'columns' => 64
+        ],
+        'drizzle_pdo_mysql' => 'mysql',
+        'mysqli' => 'mysql',
+        'pdo_mysql' => 'mysql',
+        'pdo_sqlite' => 'mysql',
+        'postgresql' => [
+            'tables' => 63,
+            'columns' => 63
+        ],
+        'sqlserver' => [
+            'tables' => 128,
+            'columns' => 128
+        ],
+        'pdo_sqlsrv' => 'sqlserver',
+        'sqlsrv' => 'sqlserver',
+        'ibm' => [
+            'tables' => 30,
+            'columns' => 30
+        ],
+        'ibm_db2' => 'ibm',
+        'pdo_ibm' => 'ibm',
+        'oci8' => [
+            'tables' => 30,
+            'columns' => 30
+        ],
+        'sqlanywhere' => [
+            'tables' => 128,
+            'columns' => 128
+        ]
+    ];
 
     /**
      * @var Connection
@@ -880,14 +917,7 @@ class ConnectionMigrator
                 $fromTable = $removedTable
             );
 
-            $tableDiff->newName = $this->deletedPrefix . $removedTable->getName();
-            if (strlen($tableDiff->newName) > $this->maxTableNameLength) {
-                $shortTableName = substr(
-                    $removedTable->getName(),
-                    strlen($removedTable->getName()) + strlen($this->deletedPrefix) - $this->maxTableNameLength
-                );
-                $tableDiff->newName = $this->deletedPrefix . $shortTableName;
-            }
+            $tableDiff->newName = substr($this->deletedPrefix . $removedTable->getName(), 0, $this->getMaxTableNameLength());
             $schemaDiff->changedTables[$index] = $tableDiff;
             unset($schemaDiff->removedTables[$index]);
         }
@@ -917,8 +947,9 @@ class ConnectionMigrator
                 }
 
                 // Build a new column object with the same properties as the removed column
+                $renamedColumnName = substr($this->deletedPrefix . $removedColumn->getName(), 0, $this->getMaxColumnNameLength());
                 $renamedColumn = new Column(
-                    $this->connection->quoteIdentifier($this->deletedPrefix . $removedColumn->getName()),
+                    $this->connection->quoteIdentifier($renamedColumnName),
                     $removedColumn->getType(),
                     array_diff_key($removedColumn->toArray(), ['name', 'type'])
                 );
@@ -943,6 +974,57 @@ class ConnectionMigrator
         return $schemaDiff;
     }
 
+    /**
+     * Retrieve the database platform-specific limitations on column and schema name sizes as
+     * defined in the tableAndFieldMaxNameLengthsPerDbPlatform property.
+     *
+     * @param string $databasePlatform
+     * @return array
+     */
+    protected function getTableAndFieldNameMaxLengths(string $databasePlatform = '')
+    {
+        if ($databasePlatform === '') {
+            $databasePlatform = $this->connection->getDatabasePlatform()->getName();
+        }
+        $databasePlatform = strtolower($databasePlatform);
+
+        if (isset($this->tableAndFieldMaxNameLengthsPerDbPlatform[$databasePlatform])) {
+            $nameLengthRestrictions = $this->tableAndFieldMaxNameLengthsPerDbPlatform[$databasePlatform];
+        } else {
+            $nameLengthRestrictions = $this->tableAndFieldMaxNameLengthsPerDbPlatform['default'];
+        }
+
+        if (is_string($nameLengthRestrictions)) {
+            return $this->getTableAndFieldNameMaxLengths($nameLengthRestrictions);
+        } else {
+            return $nameLengthRestrictions;
+        }
+    }
+
+    /**
+     * Get the maximum table name length possible for the given DB platform.
+     *
+     * @param string $databasePlatform
+     * @return string
+     */
+    protected function getMaxTableNameLength(string $databasePlatform = '')
+    {
+        $nameLengthRestrictions = $this->getTableAndFieldNameMaxLengths($databasePlatform);
+        return $nameLengthRestrictions['tables'];
+    }
+
+    /**
+     * Get the maximum column name length possible for the given DB platform.
+     *
+     * @param string $databasePlatform
+     * @return string
+     */
+    protected function getMaxColumnNameLength(string $databasePlatform = '')
+    {
+        $nameLengthRestrictions = $this->getTableAndFieldNameMaxLengths($databasePlatform);
+        return $nameLengthRestrictions['columns'];
+    }
+
     /**
      * Return the amount of records in the given table.
      *
diff --git a/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php b/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php
index 6fcce2b80b0602beda4659fdd179d7079e7648a7..cedd532f0e534931514a16bf52d5137e49965793 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Database;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Schema\Column;
 use Doctrine\DBAL\Schema\SchemaDiff;
 use Doctrine\DBAL\Schema\Table;
 use TYPO3\CMS\Core\Database\Connection;
@@ -27,33 +28,136 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class ConnectionMigratorTest extends \TYPO3\CMS\Components\TestingFramework\Core\UnitTestCase
 {
+    /**
+     * @var array
+     */
+    protected $tableAndFieldMaxNameLengthsPerDbPlatform = [
+        'default' => [
+            'tables' => 10,
+            'columns' => 10,
+        ],
+        'dbplatform_type1' => [
+            'tables' => 15,
+            'columns' => 15,
+        ],
+        'dbplatform_type2' => 'dbplatform_type1'
+    ];
 
     /**
-     * @test
+     * Utility method to quickly create a 'ConnectionMigratorMock' instance for
+     * a specific database platform.
+     *
+     * @param string $databasePlatformName
+     * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
      */
-    public function tableNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
+    private function getConnectionMigratorMock($databasePlatformName='default')
+    {
+        $platformMock = $this->getMockBuilder(\Doctrine\DBAL\Platforms\AbstractPlatform::class)->disableOriginalConstructor()->getMock();
+        $platformMock->method('getName')->willReturn($databasePlatformName);
+
+        $connectionMock = $this->getMockBuilder(Connection::class)->setMethods(['getDatabasePlatform', 'quoteIdentifier'])->disableOriginalConstructor()->getMock();
+        $connectionMock->method('getDatabasePlatform')->willReturn($platformMock);
+        $connectionMock->method('quoteIdentifier')->willReturnArgument(0);
+
+        $connectionMigrator = $this->getAccessibleMock(ConnectionMigrator::class, null, [], '', false);
+        $connectionMigrator->_set('connection', $connectionMock);
+        $connectionMigrator->_set('tableAndFieldMaxNameLengthsPerDbPlatform', $this->tableAndFieldMaxNameLengthsPerDbPlatform);
+
+        return $connectionMigrator;
+    }
+
+    /**
+     * Utility method to create a table mock instance with a much too long
+     * table name in any case.
+     *
+     * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
+     */
+    private function getTableMock()
     {
-        $maxTableNameLength = 64;
         $ridiculouslyLongTableName = 'table_name_that_is_ridiculously_long_' . random_bytes(200);
         $tableMock = $this->getAccessibleMock(Table::class, ['getQuotedName'], [$ridiculouslyLongTableName]);
         $tableMock->expects($this->any())->method('getQuotedName')->withAnyParameters()->will($this->returnValue($ridiculouslyLongTableName));
 
-        $platform = $this->getMockBuilder(\Doctrine\DBAL\Platforms\AbstractPlatform::class)->disableOriginalConstructor()->getMock();
+        return $tableMock;
+    }
+
+    /**
+     * @test
+     */
+    public function tableNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
+    {
+        $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type1');
+        $tableMock = $this->getTableMock();
 
-        $connectionMock = $this->getMockBuilder(Connection::class)->setMethods(['getDatabasePlatform'])->disableOriginalConstructor()->getMock();
-        $connectionMock->method('getDatabasePlatform')->willReturn($platform);
+        $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
+        $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
 
-        $connectionMigrator = $this->getAccessibleMock(ConnectionMigrator::class, null, [], '', false);
-        $connectionMigrator->_set('connection', $connectionMock);
+        $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->newName);
+        $this->assertLessThanOrEqual(
+            $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['tables'],
+            strlen($renamedSchemaDiff->changedTables[0]->newName)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function databasePlatformNamingRestrictionGetsResolved()
+    {
+        $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type2');
+        $tableMock = $this->getTableMock();
 
         $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
+        $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
+
+        $this->assertLessThanOrEqual(
+            $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['tables'],
+            strlen($renamedSchemaDiff->changedTables[0]->newName)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function whenPassingAnUnknownDatabasePlatformTheDefaultTableAndFieldNameRestrictionsApply()
+    {
+        $connectionMigrator = $this->getConnectionMigratorMock('dummydbplatformthatdoesntexist');
+        $tableMock = $this->getTableMock();
 
+        $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
         $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
 
-        $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->newName);
         $this->assertLessThanOrEqual(
-            $maxTableNameLength,
+            $this->tableAndFieldMaxNameLengthsPerDbPlatform['default']['tables'],
             strlen($renamedSchemaDiff->changedTables[0]->newName)
         );
     }
+
+    /**
+     * @test
+     */
+    public function columnNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
+    {
+        $connectionMigrator = $this->getConnectionMigratorMock('dbplatform_type1');
+        $tableMock = $this->getAccessibleMock(Table::class, ['getQuotedName'], ['test_table']);
+        $columnMock = $this->getAccessibleMock(
+            Column::class,
+            ['getQuotedName'],
+            [
+                'a_column_name_waaaaay_over_20_characters',
+                $this->getAccessibleMock(\Doctrine\DBAL\Types\StringType::class, [], [], '', false)
+            ]
+        );
+        $columnMock->expects($this->any())->method('getQuotedName')->withAnyParameters()->will($this->returnValue('a_column_name_waaaaay_over_20_characters'));
+
+        $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
+        $originalSchemaDiff->changedTables[0]->removedColumns[] = $columnMock;
+        $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedFieldsToRenames', $originalSchemaDiff);
+
+        $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->changedColumns[0]->column->getName());
+        $this->assertLessThanOrEqual(
+            $this->tableAndFieldMaxNameLengthsPerDbPlatform['dbplatform_type1']['columns'],
+            strlen($renamedSchemaDiff->changedTables[0]->changedColumns[0]->column->getName())
+        );
+    }
 }