禁用django的物理外键(CONSTRAINT,REFERENCES)

本文介绍了在公司DBA禁止使用REFERENCES命令的情况下,如何将Django模型的外键从数据库层移至应用层。作者尝试了通过设置`db_constraint=False`以及更改数据库引擎为MyISAM来实现,最终通过在本地初始化数据库并导入到生产环境解决外键问题,避免了权限系统的冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

用django自带的admin和auth搭建了内部网站,使用了django的用户和权限分组系统,但是在移到生产环境时发现公司把REFERENCES这种命令禁止了,DBA说影响性能不给开权限,所以不得不尝试把外键从db层移到应用层。

第一次尝试

刚开始只找到https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.db_constraint,中db_constraint这个参数,尝试了下的确可以移除物理外键,但是由于我使用的User,Group等对象都是django内部的模型,我如果要修改的话,要么改源码,要么只能重写了。

于是模仿https://www.zhihu.com/question/61129892/answer/189472143中,对AbstractBaseUser和PermissionsMixin这两个类里只要用到ForeignKey或者manttomany的字段都加上db_constraint=False这个参数。具体代码就不展示了。反正最后不是很顺利,跟内部很多东西有冲突,看起来即使弄好了也没法用权限系统,因此尝试其他方法。

第二次尝试

思路:之后就把目光投向了django本身对于db的全局设置,因为我在看文档时无意中看到关于InnoDB相关的东西,后来通过

<think>好的,用户想了解的概念、用途以及如何在数据库设计中使用。首先,我需要先明确的基本定义。是数据库中的一个约束,用于确保两个表之间数据的一致性和完整性。接下来,用户可能想知道的具体作用,比如维护数据关系、级联操作等。 然后,用户询问如何使用。这部分需要给出实际的SQL示例,比如在创建表时添加约束,或者修改现有表结构添加。同时,要提到约束的几种操作,如CASCADE、SET NULL等,说明它们的不同用途。 用户还提到了数据库设计,可能需要了解在数据库设计中的角色。这里可以结合引用中的内容,讨论物理和逻辑的区别。根据引用[1]和[2],实际生产中常避免使用物理,转而用逻辑,即在应用层处理关联关系。需要解释这样做的原因,比如性能问题、灵活性、软删除的实现等。 此,用户提供的引用中提到避免使用的几个理由,如级联删除的问题、性能影响、分库分表的困难等。需要将这些点整合到回答中,说明的优缺点,帮助用户全面理解为什么有些情况下不推荐使用。 可能还需要比较约束的优点和缺点,引用[3]提到确保数据完整性和一致性,但实际开发中可能带来维护成本和性能损耗。要平衡理论和实际应用,让用户明白在不同场景下的取舍。 最后,生成相关问题时要涵盖的概念、使用场景、优缺点、替代方案以及实际应用中的考虑因素,这样用户可以有进一步的学习方向。</think>### 概念与数据库设计解析 #### 一、的定义与作用 (Foreign Key)是关系型数据库中用于建立表间关联关系的约束条件。其核心作用是**维护数据完整性和一致性**,通过强制要求子表中的某个字段值必须存在于父表的对应字段中,例如: ```sql -- 父表 CREATE TABLE departments ( id INT PRIMARY KEY, name VARCHAR(50) ); -- 子表(包含) CREATE TABLE employees ( id INT PRIMARY KEY, dept_id INT, FOREIGN KEY (dept_id) REFERENCES departments(id) ON DELETE CASCADE ); ``` 此结构保证`employees.dept_id`的值必须存在于`departments.id`中,否则插入/更新操作将被拒绝[^3]。 #### 二、的典型用法 1. **创建表时定义** ```sql CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, FOREIGN KEY (user_id) REFERENCES users(id) ON UPDATE CASCADE ); ``` 2. **修改表结构添加** ```sql ALTER TABLE comments ADD CONSTRAINT fk_post_id FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE SET NULL; ``` 3. **级联操作类型** - `CASCADE`:父表记录变更时自动同步子表 - `SET NULL`:父表记录删除时将子表关联字段置空 - `RESTRICT`(默认):阻止破坏关联关系的操作 #### 三、生产环境中的取舍 | 特性 | 物理(数据库级) | 逻辑(应用层实现) | |-------------|----------------------------|---------------------------| | 数据一致性 | 自动保证(强约束) | 需手动维护(可能出错) | | 性能影响 | 高频写入场景可能产生锁竞争 | 无额数据库负载 | | 灵活性 | 修改表结构需停机维护 | 可动态调整关联逻辑 | | 分库分表 | 难以实现跨库关联 | 天然支持分布式架构 | 实际开发中普遍采用逻辑的主要原因: 1. **软删除兼容性**:通过`is_deleted`字段标记删除状态时,物理会阻止标记操作[^2] 2. **性能优化**:电商系统每秒万级订单写入时,检查可能成为瓶颈[^1] 3. **架构扩展**:微服务架构下不同服务使用独立数据库,无法使用跨库 #### 四、设计建议 1. **强一致性系统**(如银行核心系统)可适当使用 2. **高并发系统**建议在应用层通过事务+校验实现逻辑 3. 使用ORM框架时,建议配置: ```python # Django示例(逻辑实现) class Order(models.Model): user = models.ForeignKey( User, on_delete=models.SET_NULL, # 应用层处理删除逻辑 db_constraint=False # 不创建物理 ) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值