多表操作
Posted xiugeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多表操作相关的知识,希望对你有一定的参考价值。
一、数据库表关系
1、单表操作:
Book id title price publish email addr 1 php 100 人民出版社 111 北京 2 python 200 沙河出版社 222 沙河 3 go 100 人民出版社 111 北京 4 java 300 人民出版社 111 北京
总结:重复内容过多,浪费大量存储空间,资源浪费。
2、表关系之一对多:
Book id title price publish_id 1 php 100 1 2 python 200 1 3 go 100 2 4 java 300 1 Pulish id name email addr 1 人民出版社 111 北京 2 沙河出版社 222 沙河 一个出版社可以对应多本书,但是一本书对应不了多个出版社。
总结:一旦确定表关系是一对多时,在多对应的表中创建关联字段。
3、表关系之多对多:
Book id title price publish_id 1 php 100 1 2 python 200 1 3 go 100 2 4 java 300 1 Author id name age addr 1 alex 34 beijing 2 egon 55 nanjing Book2Author id book_id author_id 1 2 1 2 2 2 3 3 2
总结:一旦确定表关系是多对多,创建第三张关系表:id 和 另外两个表的关联字段。
# alex出版过的书籍名称(子查询) select id from Author where name=‘alex‘; select book_id from Book2Author where author_id=1; select title from Book where id = book_id;
4、表关系之一对一
Author id name age ad_id(UNIQUE) 1 alex 34 1 2 egon 55 2 AuthorDetail id addr gender tel gf_name author_id(UNIQUE) 1 beijing male 110 小花 1 2 nanjing male 911 杠娘 2
总结:一旦确定是一对一关系,在两张表中的任意一张表中建立关联字段+ UNIQUE。
5、表关系之关联字段和外键约束
创建关联字段和约束不是必然关系,但是不建立约束的话,从引擎的角度来说两个表之间没有任何关联,因此删除的时候,再查找时会找不到数据。
创建关联字段是为了进行查询,建立约束是为了防止出现脏数据。
6、表关系之sql创建关联表
GREATE TABLE publish( id INT PRIMARY KEY auto_increment, name VARCHAR (20) ); GREATE TABLE book( id INT PRIMARY KEY auto_increment, title VARCHAR (20), price DECIMAL (8,2), pub_date DATE, publish_id INT, # 关联字段 FOREIGN KEY (publish_id) REFERENCES publish(id) # 关联字段约束 ); GREATE TABLE authordetail ( id INT PRIMARY KEY auto_increment, tel VARCHAR (20) ); GREATE TABLE author ( id INT PRIMARY KEY auto_increment, name VARCHAR (20), age INT, authordetail_id INT UNIQUE, # 一对一约束 FOREIGN KEY (authordetail_id) REFERENCES authordetail(id) ); GREATE TABLE book2author ( # 多对多 id INT PRIMARY KEY auto_increment, book_id INT, author_id INT, FOREIGN KEY (book_id) REFERENCES book(id), FOREIGN KEY (author_id) REFERENCES author(id) );
二、创建模型
实例:我们来假定下面这些概念,字段和关系
作者模型:一个作者有姓名和年龄。
作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
出版商模型:出版商有名称,所在城市以及email。
书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。
模型建立如下:
from django.db import models # 出版社表 class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() # 作者详情表 class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 与AuthorDetail建立一对一的关系,一对一的关系建立在任意一边都可以 # to="AuthorDetail",加了引号之后是在全局中寻找不会因为位置关系找不到AuthorDetail authorDetail=models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE) """ 上面语句代表含义为下面sql语句 authordetail_id INT UNIQUE, # 一对一约束 FOREIGN KEY (authordetail_id) REFERENCES authordetail(id) """ class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) #与publish建立 一对多关系 ,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish", to_field="nid",on_delete=models.CASCADE) """ 上面语句代表含义为下面的sql语句 publish_id INT, # 关联字段 FOREIGN KEY (publish_id) REFERENCES publish(id) # 关联字段约束 """ # 多对多 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors = models.ManyToManyField(to="Author") """ 上面这个语句含义为下面的sql语句 GREATE TABLE book2author ( id INT PRIMARY KEY auto_increment, book_id INT, author_id INT, FOREIGN KEY (book_id) REFERENCES book(id), FOREIGN KEY (author_id) REFERENCES author(id) ); """ # 这种多对多写法可以由 authors = models.ManyToManyField(to="Author") 替代 # class Book2Author(models.Model): # nid = models.AutoField(primary_key=True) # book = models.ForeignKey(to="Book") # author = models.ForeignKey(to="Author")
参数解析:
ForeignKey.to_field:指定当前关系与被关联对象中的哪个字段关联。默认情况下,to_field 指向被关联对象的主键。
ForeignKey.on_delete:当一个model对象的ForeignKey关联的对象被删除时,默认情况下此对象也会一起被级联删除的。
CASCADE:默认值,model对象会和ForeignKey关联对象一起被删除。
配置settings.py文件:
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘, ] DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘orm2‘, # 要连接的数据库,连接前需要创建好 ‘USER‘:‘root‘, # 连接数据库的用户名 ‘PASSWORD‘:‘1234‘, # 连接数据库的密码 ‘HOST‘:‘127.0.0.1‘, # 连接主机,默认本级 ‘PORT‘: 3306, # 端口 默认3306 } }
配置ORM2/__init__.py文件:
import pymysql pymysql.install_as_MySQLdb()
通过两条数据库迁移命令即可在指定的数据库中创建表:
$ python3 manage.py makemigrations $ python3 manage.py migrate
生成如下表:
注意事项:
- 表的名称
myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称 id
字段是自动添加的(没有设置id时会自动添加id字段)- 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
- 这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。 - 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称。(见前面settings设置) - 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
三、添加表记录
以上是关于多表操作的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段15——git命令操作一个完整流程