多表操作
一、數據庫表關系
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 。
三、添加表記錄
多表操作