mysql表的relationship_数据表关联关系映射 Relationship Map

本文介绍了MySQL数据表之间的三种关联关系:一对一、一对多和多对多映射。详细阐述了每种关系的使用场景、实现方式以及数据查询操作,包括外键和反向查询。通过示例代码展示了如何在Django ORM中创建和操作这些关联关系。

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

数据表关联关系映射 Relationship Map

在关系型数据库中,通常不会把所有数据都放在同一张表中,这样做会额外占用内存空间,

在关系列数据库中通常用表关联来解决数据库。

用的表关联方式有三种:

一对一映射

如: 一个身份证对应一个人

一对多映射

如: 一个班级可以有多个学生

多对多映射

如: 一个学生可以报多个课程,一个课程可以有多个学生学习

一一对一映射

一对一是表示现实事物间存在的一对一的对应关系。

如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等

1.语法:

在关联的两个类中的任何一个类中:classA(model.Model):

...classB(model.Model):

属性= models.OneToOneField(A)

2.用法

(1)创建作家和作家妻子类

#file : xxxxxxxx/models.py

from django.db importmodelsclassAuthor(models.Model):'''作家模型类'''name= models.CharField('作家', max_length=50)classWife(models.Model):'''作家妻子模型类'''name= models.CharField("妻子", max_length=50)

author= models.OneToOneField(Author) #增加一对一属性

(2)查询

在 Wife 对象中,通过 author 属性找到对应的author对象

在 Author 对象中,通过 wife 属性找到对应的wife对象

(3)创始一对一的数据记录

from . importmodels

author1= models.Author.objects.create(name='王老师')

wife1= models.Wife.objects.create(name='王夫人', author=author1) #关联王老师

author2 = models.Author.objects.create(name='张老师') #一对一可以没有对应的数据

(4)一对一数据的相互获取

1.正向查询

直接通过关联属性查询即可

#通过 wife 找 author

from . importmodels

wife= models.Wife.objects.get(name='王夫人')print(wife.name, '的老公是', wife.author.name)

2.反向查询

通过反向引用属性查询

反向引用属性为实例对象,引用类名(小写),如作家的反向引用为作家对象.wife

当反向引用不存在时,则会触发异常

#通过 author.wife 引用属性 找 wife,如果没有对应的wife刚触发异常

author1 = models.Author.objects.get(name='王老师')print(author1.name, '的妻子是', author1.wife.name)

author2= models.Author.objects.get(name='张老师')try:print(author2.name, '的妻子是', author2.wife.name)except:print(author2.name, '还没有妻子')

3.作用

主要是解决常用数据不常用数据的存储问题,把经常加载的一个数据放在主表中,不常用数据放在另一个副表中,这样在访问主表数据时不需要加载副表中的数据以提高访问速度提高效率和节省内存空间,如经常把书的内容和书名建成两张表,因为在网站上经常访问书名等信息,但不需要得到书的内容。

二一对多映射

一对多是表示现实事物间存在的一对多的对应关系。

如:一个学校有多个班级,一个班级有多个学生, 一本图书只能属于一个出版社,一个出版社允许出版多本图书

1.用法:当一个A类对象可以关联多个B类对象时

classA(model.Model):

...classB(model.Model):

属性= models.ForeignKey(多对一中"一"的模型类, ...)

2.外键类ForeignKey

构造函数:ForeignKey(to, on_delete, **options)

常用参数:

on_delete

models.CASCADE 级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。

models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;

SET_NULL 设置ForeignKey null;只有null是True才有可能。

SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。

**options 可以是常用的字段选项如:null

unique等

3.示例

有二个出版社对应五本书的情况.

1.清华大学出版社 有书

C++  Java  Python

2.北京大学出版社 有书

西游记  水浒

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1.定义一对多的类#file: myorm/models.py

from django.db importmodelsclassPublisher(models.Model):'''出版社'''name= models.CharField('名称', max_length=50, unique=True)classBook(models.Model):

title= models.CharField('书名', max_length=50)

publisher= models.ForeignKey(Publisher, null=True)----------------------

2.创建一对多的对象#file: xxxxx/views.py

from . importmodels

pub1= models.Publisher.objects.create(name='清华大学出版社')

models.Book.objects.create(title='C++', publisher=pub1)

models.Book.objects.create(title='Java', publisher=pub1)

models.Book.objects.create(title='Python', publisher=pub1)

pub2= models.Publisher.objects.create(name='北京大学出版社')

models.Book.objects.create(title='西游记', publisher=pub2)

models.Book.objects.create(title='水浒', publisher=pub2)

示例

4.数据查询

通过多查一

#通过一本书找到对应的出版社

abook = models.Book.objects.get(id=1)print(abook.title, '的出版社是:', abook.publisher.name)

通过多查一

#通过出版社查询对应的书

pub1 = models.Publisher.objects.get(name='清华大学出版社')

books= pub1.book_set.all() #通过book_set 获取pub1对应的多个Book数据对象#books = models.Book.objects.filter(publisher=pub1) # 也可以采用此方式获取

print("清华大学出版社的书有:")for book inbooks:print(book.title)

三多对多映射

多对多表达对象之间多对多复杂关系,如: 每个人都有不同的学校(小学,初中,高中,...),每个学校都有不同的学生...

1.语法

在关联的两个类中的任意一个类中,增加:

属性= models.ManyToManyField(MyModel)

2.示例

一个作者可以出版多本图书

一本图书可以被多名作者同时编写classAuthor(models.Model):

xxxx xxxxclassBook(models.Model):

xxxx xxxx

authors= models.ManyToManyField(Author)

3.数据查询

通过Book查询对应的所有的Authors

可以通过authors表示对应所有Author的查询对象

book.authors.all()->获取 book 对应的所有的author的信息

book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息

通过Author查询对应的所有的Books

Django会生成一个属性 book_set 用于表示对对应的book的查询对象相关操作

author.book_set.all()

author.book_set.filter()

author.book_set.create(...)#创建新书并联作用author

author.book_set.add(book) #添加已有的书为当前作者author

author.book_set.clear() #删除author所有并联的书

author.book_set.remove() #删除所author所有并联的书

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#多对多模型

classAuthor(models.Model):'''作家模型类'''name= models.CharField('作家', max_length=50)def __str__(self):returnself.nameclassBook(models.Model):

title= models.CharField('书名', max_length=50)

author= models.ManyToManyField(Author, null=True)def __str__(self):returnself.title-----------------------

#多对多视图操作

from django.http importHttpResponsefrom . importmodelsdefmany2many_init(request):#创建两人个作者

author1 = models.Author.objects.create(name='王老师')

author2= models.Author.objects.create(name='张老师')#王老师和张老师同时写了一本Python

book11 = author1.book_set.create(title="Python")

author2.book_set.add(book11)#

#张老师还写了两本书

book21 = author2.book_set.create(title="C") #创建一本新书"C"

book22 = author2.book_set.create(title="C++") #创建一本新书"C++"

return HttpResponse("初始化成功")defshow_many2many(request):

authors=models.Author.objects.all()for auth inauthors:print("作者:", auth.name, '发出版了', auth.book_set.count(), '本书:')for book inbooks:print(' ', book.title)print("----显示书和作者的关系----")

books=models.Book.objects.all()for book inbooks:

auths=book.author.all()print(book.title, '的作者是:', '、'.join([str(x.name) for x inauths]))return HttpResponse("显示成功,请查看服务器端控制台终端")------------------------

#多对多最终的SQL结果

mysql> select * frommyorm2_author;+----+-----------+

| id | name |

+----+-----------+

| 1 | 王老师 |

| 1 | 张老师 |

+----+-----------+

2 rows in set (0.00sec)

mysql> select * frommyorm2_book;+----+--------+

| id | title |

+----+--------+

| 13 | Python |

| 14 | C |

| 15 | C++ |

+----+--------+

3 rows in set (0.00sec)

mysql> select * frommyorm2_book_author;+----+---------+-----------+

| id | book_id | author_id |

+----+---------+-----------+

| 17 | 13 | 11 |

| 20 | 13 | 12 |

| 18 | 14 | 12 |

| 19 | 15 | 12 |

+----+---------+-----------+

4 rows in set (0.00 sec)

多对多模型示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值