数据库中外键关联,
1. 关系分类
一对一关系
一对多关系
多对多关系
2外键的优缺点
优点:
由数据库自身保证数据一致性和完整性,数据更可靠
可以增加 ER 图的可读性
外键可节省开发量
缺点:
性能缺陷,有额外开销
主键表被锁定时,会引发外键表也被锁
删除主键表的数据时,需先删除外键表的数据
修改外键表字段时,需重建外键约束
不能⽤于分布式环境
不容易做到数据解耦
3. 应用场景
适⽤场景: 内部系统、传统企业级应⽤可以使⽤ (需要数据量可控, 数据库服务器数量可控)
不适⽤场景: 互联⽹⾏业不建议使⽤
4. ⼿动构建关联
- ⼀对多: 主表 id 与 ⼦表 id 完全⼀⼀对应
- ⼀对多: 在"多"的表内添加"唯⼀"表 id 字段
- 多对多: 创建关系表, 关系表中⼀般只存放两个相关联的条⽬的 id
扩展:数据分片,外键没法做分布式数据库,大型互联网禁止使用外键。
如果不使用外键,怎么建立关联呢?
第一步分析两个表的关系。
用户和配置是一对一的关系。
django里的数据库操作不要用循环,运算直接使用count(),exists(),因为数据库和django实际开发中是两个电脑,通过tcp链接的,尽量减少运算。
User.objects.filter(id_range=(1,100)).only('name','age')
操作不当,写出来的语句就是比别人慢。
QuerySet
⽅法
创建: create() / get_or_create() / update_or_create() /
bulk_create()(创建大量数据,批量创建。)
条件过滤和排除: filter() / exclude()
只加载需要的字段: only() / defer()
order_by() / count() / exists()
latest() / earliest()
first() / last()
复习下orm,然后开始继续编写model.py中代码:
class User(models.Model):
...
@property
def profile(self):
"""用户的配置项"""
my_profile, created = Profile.objects.get_or_create(id=self.id)
return my_profile
如果出现下面查询,就会出现查询好几次,性能就会很差。如何解决这个问题?
profile = user.profile
profile.location
profile.min_dating_age
profile.max_distance
python 是动态语言,取完profile,然后把它加给self._profile,作为私有属性,相当于给self加了一个字典的值,修改如下:
@property
def profile(self):
"""用户的配置项"""
# if '_profile' not in self.__dict__:
if not hasattr(self, '_profile'):
_profile, created = Profile.objects.get_or_create(id=self.id)
self._profile = _profile
return self._profile