1. 程式人生 > >多表操作

多表操作

pes class pytho 信息 會有 bsp day con ren

一、數據庫表關系

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 。

三、添加表記錄

多表操作