我们再聊一聊gorm自动迁移数据库:AutoMigrate()
当数据库迁移时,若方法中有从表,gorm是会自动将依赖的主表创建出来的,(多对多关系不会)
所以迁移表时,只需要将最从表放入,其他主表都会自动创建。同时也可以认证表与表之间的关系
贴上我的数据库设计
https://download.csdn.net/download/qq_48826531/85960868
我期待中的表关系如下:
但实际是
我辛辛苦苦写了那么多的tag,都没起作用???
尝试一:去网上搜答案:
可都是去介绍手动创建外键:AddForeignKey()
(5条消息) gorm标签外键失效_鹿灏楷silves的博客-CSDN博客
可能跟我出错的原因并不一致。
尝试二:将模型拉到其他项目中去自动迁移尝试
居然可以创建出来表的关系。得出结论。问题在gorm的配置中
因为我是用的gin-vue-admin框架的配置,所以找到配置gorm方法:
config := &gorm.Config{
DisableForeignKeyConstraintWhenMigrating: true, //自动迁移时,禁用外键约束,不禁用
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
}
答案就在 DisableForeignKeyConstraintWhenMigrating 这个配置上,true时,自动禁止外键约束。原来改了半天,原因在这里。
但我还是疑惑gva中也有很多设置外键的gorm-tag,为什么还要有这个配置呢?
大佬很贴心的给出了解释
物理外键:某张表的字段使用foreignkey作为外键关联另外一张表、字段。并且限定引擎为inno DB;
逻辑外键:又叫事物外键,不使用foreignkey,使用语法(代码)上产生逻辑关联而产生的外键;
从维护上来看,逻辑外键由于需要使用代码来进行维护,好像更麻烦;物理外键无需代码维护直接使用mysql自身维护,好像更简单。
实际上物理外键是有性能问题的:
- 数据库需要维护外键的内部管理;
- 外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
- 有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
- 外键还会因为需要请求对其他表内部加锁而容易出现死锁情况
- 所有tables必须是InnoDB型,它们不能是临时表
- 不支持对外键列的索引前缀。这样的后果之一是BLOB和TEXT列不被包括在一个外键中,这是因为对这些列的索引必须总是包含一个前缀长度
- InnoDB不对那些外键或包含NULL列的被引用键值检查外键约束
- 如果数据量上去后,使用物理外键会大大的降低性能,特别是出现死锁情况。
其中优化数据库中的一个方向是避免大事务,尽量将大事务拆成多个小事务来处理,小事务发生锁冲突的几率也更小。
当采用物理外键时,此时一个事物同时最少是需要更新2张表。此时是需要同时最少锁住两张的表的。如果拆分后,则两张锁住的时间是不同步的。造成死锁的概率更小。