diff --git a/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php b/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
index 98bb4bc45234669e3f3885a15cde2fd5b7b2d6cb..b5ba4f07a419a8855c25046ade9ba1016040f215 100644
--- a/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
+++ b/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
@@ -686,11 +686,14 @@ class DefaultTcaSchema
                     }
                 }
 
-                // @todo: If there is no "uid" primary key field, the combination of "uid_local & uid_foreign", or
-                //        "uid_local & uid_foreign & tablenames & fieldname" *should* be specified as combined primary key.
-                //        However, workspaces has a bug and currently inserts broken duplicate rows. A primary
-                //        key, or at least an unique constraint should be added when this is resolved.
-                //        Note especially galera clusters rely on this.
+                // Primary key handling: If there is a uid field, PK has been added above already.
+                // Otherwise, the PK combination is either "uid_local, uid_foreign", or
+                // "uid_local, uid_foreign, tablenames, fieldname" if this is a multi-foreign setup.
+                if (!$hasUid && $tables[$tablePosition]->getPrimaryKey() === null && !empty($tcaColumn['config']['MM_oppositeUsage'])) {
+                    $tables[$tablePosition]->setPrimaryKey(['uid_local', 'uid_foreign', 'tablenames', 'fieldname']);
+                } elseif (!$hasUid && $tables[$tablePosition]->getPrimaryKey() === null) {
+                    $tables[$tablePosition]->setPrimaryKey(['uid_local', 'uid_foreign']);
+                }
             }
         }
         return $tables;
diff --git a/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php b/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
index dca809a1421ea244c5e85c0621b703c11603d18a..964b43356908438bf7646fa807b66eebcafd09a6 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
@@ -761,6 +761,12 @@ final class DefaultTcaSchemaTest extends UnitTestCase
                     'uid_foreign',
                     ['uid_foreign']
                 ),
+                new Index(
+                    'primary',
+                    ['uid_local', 'uid_foreign'],
+                    true,
+                    true
+                ),
             ]
         );
         self::assertEquals($expectedMmTable, $result[1]);
@@ -918,6 +924,12 @@ final class DefaultTcaSchemaTest extends UnitTestCase
                     'uid_foreign',
                     ['uid_foreign']
                 ),
+                new Index(
+                    'primary',
+                    ['uid_local', 'uid_foreign', 'tablenames', 'fieldname'],
+                    true,
+                    true
+                ),
             ]
         );
         self::assertEquals($expectedMmTable, $result[1]);