diff --git a/django/db/models/options.py b/django/db/models/options.py
index d471bba..284a67d 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -23,6 +23,9 @@ DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
                  'order_with_respect_to', 'app_label', 'db_tablespace',
                  'abstract', 'managed', 'proxy', 'swappable', 'auto_created')
 
+# Lookup table for table names introduced in order to prevent that users from declaring the same table twice
+db_table_lookup = {}
+
 
 @python_2_unicode_compatible
 class Options(object):
@@ -121,6 +124,16 @@ class Options(object):
             self.db_table = "%s_%s" % (self.app_label, self.module_name)
             self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
 
+        # Prevent users from declaring the same table twice, ISSUE #20098
+        if self.managed:
+            qname = '%s.%s' % (cls.__module__, cls.__name__)
+            if self.db_table in db_table_lookup:
+
+                raise Exception('db_table "%s" was already declared by "%s" and was redeclared by "%s".'
+                                % (self.db_table, db_table_lookup[self.db_table], qname))
+
+            db_table_lookup[self.db_table] = qname
+
     def _prepare(self, model):
         if self.order_with_respect_to:
             self.order_with_respect_to = self.get_field(self.order_with_respect_to)
diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
index 3bb8bb0..82a512a 100644
--- a/tests/regressiontests/admin_scripts/tests.py
+++ b/tests/regressiontests/admin_scripts/tests.py
@@ -1069,6 +1069,49 @@ class ManageValidate(AdminScriptTestCase):
         self.assertNoOutput(err)
         self.assertOutput(out, '0 errors found')
 
+    def test_unmanaged_duplicate_db_table_declaration(self):
+        """ISSUE #20098
+        manage.py validate must not not raise errors when a project or an app
+        declares the same db_table twice using unmanaged model classes.
+        """
+        self.write_settings('settings.py',
+            apps=['admin_scripts.unmanaged_duplicate_db_table_declaration'],
+            sdict={'DEBUG': True}
+        )
+        args = ['validate']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, '0 errors found')
+
+    def test_duplicate_db_table_declaration_single_app(self):
+        """ISSUE #20098
+        manage.py validate does not raise errors when a project or an app
+        declares the same db_table twice or multiple times for different models
+        declared by a single app.
+        """
+        self.write_settings('settings.py',
+            apps=['admin_scripts.duplicate_db_table_declaration_single_app'],
+            sdict={'DEBUG': True}
+        )
+        args = ['validate']
+        out, err = self.run_manage(args)
+        self.assertOutput(err, 'was redeclared')
+
+    def test_duplicate_db_table_declaration_multiple_app(self):
+        """ISSUE #20098
+        manage.py validate does not raise errors when a project or an app
+        declares the same db_table twice or multiple times for different models
+        declared by different apps.
+        """
+        self.write_settings('settings.py',
+            apps=['admin_scripts.duplicate_db_table_declaration_multiple_app.app1',
+                  'admin_scripts.duplicate_db_table_declaration_multiple_app.app2'],
+            sdict={'DEBUG': True}
+        )
+        args = ['validate']
+        out, err = self.run_manage(args)
+        self.assertOutput(err, 'was redeclared')
+
 
 class CustomTestRunner(DjangoTestSuiteRunner):
 
