Mysql 理解/欺骗Django的外国关键关系

Mysql 理解/欺骗Django的外国关键关系,mysql,django,database-design,django-models,foreign-key-relationship,Mysql,Django,Database Design,Django Models,Foreign Key Relationship,所以我继承了一些django mySQL表非常简单,其中parent不是FK关系,只是“parent”id: 但后来发起者做了这件事 class Child(models.Model): """Project Child information""" id = models.AutoField(primary_key=True) parent = models.ForeignKey(Parent) name = models.CharField(max_lengt

所以我继承了一些django

mySQL表非常简单,其中parent不是FK关系,只是“parent”id:

但后来发起者做了这件事

class Child(models.Model):
    """Project Child information"""
    id = models.AutoField(primary_key=True)
    parent = models.ForeignKey(Parent)
    name = models.CharField(max_length=255)

    class Meta:
        managed = False
诚然,我不是一个SQL骑师,但我知道“真正的”外键关系看起来类似于此通知
约束

CREATE TABLE `Child` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `child_63f17a16` (`parent_id`),
  CONSTRAINT `parent_id_refs_id_34923e1e` FOREIGN KEY (`parent_id`) REFERENCES `Parent` (`id`)
) ENGINE=InnoDB;
我想知道的是:

  • 我希望通过这种“诡计”看到什么问题
  • 虽然这似乎有效,但是否推荐或建议
  • 是否建议我们将SQL修改为

  • 非常感谢

    应该更快。。。因为在子表中添加行之前,mysql不会检查约束。 但是有了外键,你的生活会更轻松,因为你可以在更新和删除时使用。 我同意这个限制

  • 没有实际约束可能会导致引用中断、父项无效和其他类型的数据不一致。我不是Django专家,但我敢猜测,在大多数情况下,Django仍能很好地处理关系,除非您有意添加一些无效记录

  • 通常,如果您的RDBMS支持外键约束,那么绝对没有理由不使用它们,忽略它们可能会被视为设计缺陷

  • 应考虑添加密钥约束。它们不仅为DBMS提供了优化查询的好方法,还确保了数据的一致性。我非常确定Django在某个地方有一个设置,当您运行

    manage.py syncdb

    有关为什么选择外键的更多信息,请阅读

    最有趣的是:

    InnoDB需要外键和引用键的索引,以便外键检查可以快速进行,而不需要表扫描。在引用表中,必须有一个索引,其中外键列按相同顺序列为第一列。如果引用表不存在,则会自动在引用表上创建这样的索引。(这与一些旧版本形成对比,在这些旧版本中,必须显式创建索引,否则外键约束的创建将失败。)如果给定索引名称,则按照前面所述使用


    除非手动将索引添加到外键字段,否则速度不会更快。如果你要这么做,你最好用外键来完成。无论采用哪种方法,索引都会有一个页面I/O,并且检查约束也是一个页面I/O。这意味着insert可能有一个小缺点(通常不重要),但是你要百分之百地确定你的表格中没有不完整的参考资料。这真是一个很好的信息——非常感谢你的详细回复——我当然同意你关于没有参考资料的问题。也就是说,您是否看到简单地将其指定为FK而不施加这些约束的问题?这当然让我的查询更简单了……我不知道你不施加约束是什么意思。在InnoDB中,当您有
    外键引用时,它会自动创建并强制执行存在约束。你不需要一个
    约束
    子句。措词不当。您认为在Django中将其定义为ForeignKey而不是在db级别强制使用它有什么问题吗;注意managed=FalseDjango不会强制执行这些约束,它只需要知道这些约束,就可以创建适当的SQL和联接表。除非手动将索引添加到模式中的所有外键字段,否则连接上可能还会出现性能问题。如果您确实这样做,则需要确保(在视图级别)使用现有/有效的外键插入数据,否则将产生孤立项,并且仍然会遇到一致性问题。也就是说,Django将起作用。可以运行MyISAM模式(无FKs);它只是不能确保所有引用都是有效的。@alxbl:不理解您的注释中的一部分-“它只需要知道它们,就可以创建适当的SQL和联接表”。这将在何时发生?这个用例是什么?
    CREATE TABLE `Child` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) NOT NULL,
      `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      PRIMARY KEY (`id`),
      KEY `child_63f17a16` (`parent_id`),
      CONSTRAINT `parent_id_refs_id_34923e1e` FOREIGN KEY (`parent_id`) REFERENCES `Parent` (`id`)
    ) ENGINE=InnoDB;