国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

Django實(shí)現(xiàn)ORM模型數(shù)據(jù)查詢優(yōu)化

2019-07-11 12:05郭顯娥
關(guān)鍵詞:視圖語句代碼

郭顯娥

(山西大同大學(xué)計(jì)算機(jī)與網(wǎng)絡(luò)工程學(xué)院,山西大同037009)

通常情況下,數(shù)據(jù)庫查詢使用原生的SQL語句實(shí)現(xiàn)。隨著項(xiàng)目越來越大,采用寫原生SQL的方式在代碼中會(huì)出現(xiàn)大量的SQL 語句,如下問題就出現(xiàn)了:

(1)SQL 語句重復(fù)利用率不高,越復(fù)雜的SQL語句條件越多,代碼越長。會(huì)出現(xiàn)很多相近的SQL語句;

(2)很多SQL 語句是在業(yè)務(wù)邏輯中拼出來的,如果有數(shù)據(jù)庫需要更改,就要去修改這些邏輯,這會(huì)很容易漏掉對(duì)某些SQL語句的修改;

(3)寫SQL 時(shí)容易忽略web 安全問題,給未來造成隱患。

Dango開發(fā)使用ORM 模型的查找操作,大多是基于QuerySet 上的一些 API 的使用,通過Filter、Exclude以及Get 三個(gè)方法來實(shí)現(xiàn),在調(diào)用這些方法的時(shí)候傳遞不同的參數(shù)來實(shí)現(xiàn)查詢需求[1-3]。

1 Django與ORM概述

1.1 Django簡(jiǎn)介

Django 已經(jīng)成為web 開發(fā)者的首選框架,是一個(gè)遵循 MVC 設(shè)計(jì)模式的框架。MVC 是 Model、View、Controller 三個(gè)單詞的簡(jiǎn)寫,分別代表模型、視圖、控制器。

Django 其實(shí)也是一個(gè)MTV 的設(shè)計(jì)模式。MTV是Model、Template、View三個(gè)單詞的簡(jiǎn)寫,分別代表模型、模版、視圖。

1.2 ORM簡(jiǎn)介

ORM,全稱Object Relational Mapping,叫做對(duì)象關(guān)系映射。通過ORM 類的方式去操作數(shù)據(jù)庫,而不用再寫原生的SQL 語句。其原理是把表映射成類,把行映射作實(shí)例,把字段映射為屬性。ORM在執(zhí)行對(duì)象操作的時(shí)候最終還是會(huì)把對(duì)應(yīng)的操作轉(zhuǎn)換為數(shù)據(jù)庫原生語句。使用ORM 有如下優(yōu)點(diǎn):

(1)易用性:使用ORM 做數(shù)據(jù)庫的開發(fā)可以有效的減少重復(fù)SQL語句的概率,寫出來的模型也更加直觀、清晰;

(2)性能損耗?。篛RM 轉(zhuǎn)換成底層數(shù)據(jù)庫操作指令確實(shí)會(huì)有一些開銷。但從實(shí)際的情況來看,這種性能損耗很少(不足5%),只要不是對(duì)性能有嚴(yán)苛的要求,綜合考慮開發(fā)效率、代碼的閱讀性,帶來的好處要遠(yuǎn)遠(yuǎn)大于性能損耗,而且項(xiàng)目越大作用越明顯;

(3)設(shè)計(jì)靈活:可以輕松的寫出復(fù)雜的查詢;

(4)可移植性:Django 封裝了底層的數(shù)據(jù)庫實(shí)現(xiàn),支持多個(gè)關(guān)系數(shù)據(jù)庫引擎,包括流行的MySQL、PostgreSQL 和SQLite??梢苑浅]p松的切換數(shù)據(jù)庫。

2 利用Django搭建ORM模型

2.1 ORM模型創(chuàng)建

ORM 模型一般都是放在app 的models.py 文件中。每個(gè)app 都可以擁有自己的模型。并且如果這個(gè)模型想要映射到數(shù)據(jù)庫中,那么這個(gè)app 必須要放在settings.py 的INSTALLED_APP 中進(jìn)行安裝。本項(xiàng)目中app 命名為front,實(shí)驗(yàn)需用的四個(gè)ORM模型分別為:Author 模型(見圖1)、Publisher 模型(見圖2)、Book 模型(見圖3)與Book_order 模型(見圖4)。

圖1 Author模型

圖2 Publisher模型

圖3 Book模型

圖4 Book_order模型

2.2 映射模型到數(shù)據(jù)庫中

將ORM 的四個(gè)模型映射到數(shù)據(jù)庫中。步驟如下:

Step2.在項(xiàng)目同名目錄下的__inti__.py 中初始化 mysql 驅(qū)動(dòng),告訴 django 用 pymysql 驅(qū)動(dòng),代碼如下。

import pymysql

pymysql.install_as_MySQLdb()

Step3.在命令行終端,進(jìn)入到項(xiàng)目所在的路徑,然后執(zhí)行命令python manage.py makemigrations生成遷移腳本文件。

Step4.同樣在命令行中,執(zhí)行命令python manage.py migrate 將遷移腳本文件映射到數(shù)據(jù)庫中,生成相應(yīng)的數(shù)據(jù)庫表:author表、publisher表、book表和book_order表。

2.3 錄入表中原始數(shù)據(jù)

分 別 在 author 表 、publisher 表 、book 表 和book_order 表中錄入3 至6 條記錄,數(shù)據(jù)清單見下圖:author 表(圖5)、publisher 表(圖6)、book 表(圖7)和book_order表(圖8)。

圖5 author表數(shù)據(jù)

圖6 publisher表數(shù)據(jù)

圖7 book表數(shù)據(jù)

圖8 book_order表數(shù)據(jù)

2.4 視圖函數(shù)的實(shí)現(xiàn)

視圖寫在app 的views.py 中。視圖的第一個(gè)參數(shù)是request 對(duì)象。這個(gè)對(duì)象存儲(chǔ)了請(qǐng)求過來的所有信息,包括攜帶的參數(shù)以及一些頭部信息等。在視圖中,一般是完成邏輯相關(guān)的操作。比如這個(gè)請(qǐng)求是添加一篇博客,那么可以通過request來接收到這些數(shù)據(jù),然后存儲(chǔ)到數(shù)據(jù)庫中,最后再把執(zhí)行的結(jié)果返回給瀏覽器。視圖函數(shù)的返回結(jié)果是HttpResponseBase 對(duì)象。示例代碼如下:

2.5 URL映射

視圖創(chuàng)建后,要與URL進(jìn)行映射,也即用戶在瀏覽器中輸入什么url 的時(shí)候可以請(qǐng)求到這個(gè)視圖函數(shù)。在用戶輸入了某個(gè)url,請(qǐng)求到網(wǎng)站的時(shí)候,django 會(huì)從項(xiàng)目的urls.py 文件中尋找對(duì)應(yīng)的視圖。django 會(huì)從urls.py 文件中urlpatterns 變量中讀取所有的匹配規(guī)則。示例代碼如下:

3 數(shù)據(jù)查詢及優(yōu)化

3.1 問題提出

在book 模型(圖3 與圖7)中,首先查詢與book對(duì)應(yīng)的author 數(shù)據(jù),即每本書對(duì)應(yīng)的作者;再次查詢與book 對(duì)應(yīng)的bookorder 數(shù)據(jù),即每本書的訂單情況。

3.2 數(shù)據(jù)查詢使用的方法

數(shù)據(jù)庫相關(guān)聯(lián)表的存在如下四種關(guān)系:一對(duì)多、一對(duì)一關(guān)系,多對(duì)一、多對(duì)多關(guān)系,下面分別分兩種情況實(shí)現(xiàn)查詢的優(yōu)化。

3.2.1 一對(duì)多或一對(duì)一查詢的傳統(tǒng)方法

針對(duì)3.1 問題之一,先用傳統(tǒng)方法實(shí)現(xiàn):第一步查詢所有的book,第二步遍歷books,查詢作者的信息,在每本圖書上發(fā)生一次查詢。Views.py 源代碼為:

測(cè)試結(jié)果分析(圖9):本例共有三本圖書,共發(fā)生四次查詢,如果增加圖書的數(shù)量,查詢次數(shù)隨之增加。設(shè)有n本圖書,那么發(fā)生的查詢次數(shù)就是n+1次。

圖9 優(yōu)化前測(cè)試結(jié)果

3.2.2 select_related方法實(shí)現(xiàn)查詢優(yōu)化

使用select_related 方法,可以實(shí)現(xiàn)一對(duì)多或一對(duì)一查詢的優(yōu)化,將傳統(tǒng)方法中的:

books=Book.objects.all()

改為:

books= Book.objects.select_related("author","publisher")測(cè)試結(jié)果數(shù)據(jù)見圖10。

分析其原理,對(duì)于相關(guān)聯(lián)的模型,查找book時(shí)一次性地查找相關(guān)聯(lián)的其它數(shù)據(jù),并放入緩沖區(qū)備用,而不用每次從數(shù)據(jù)庫中查找。

用select_related 方法優(yōu)化后,本實(shí)例只發(fā)生一次查詢,如果圖書數(shù)量增加,也同樣只發(fā)生一次查詢。這樣節(jié)省了開銷,提高了查詢效率。

但是,select_related 只能用在一對(duì)多或者一對(duì)一中,不能用在多對(duì)多或者多對(duì)一中。下面引入prefetch_related 方法,實(shí)現(xiàn)多對(duì)一或一對(duì)多查詢優(yōu)化。

3.2.3 prefetch_related方法實(shí)現(xiàn)查詢優(yōu)化

針對(duì)3.1 問題之二,使用prefetch_related 方法,實(shí)現(xiàn)多對(duì)一或多對(duì)多查詢優(yōu)化。Views.py 源代碼為:

測(cè)試結(jié)果見圖11。

prefetch_related:這個(gè)方法和 select_related 非常的類似,就是在訪問多個(gè)表中的數(shù)據(jù)的時(shí)候,減少查詢的次數(shù)。這個(gè)方法是為了解決多對(duì)一和多對(duì)多的關(guān)系的查詢問題。優(yōu)化后,本實(shí)例只發(fā)生兩次查詢,如果圖書數(shù)量增加,也同樣只發(fā)生兩次查詢,大大節(jié)省了開銷。

圖10 select_related優(yōu)化后測(cè)試結(jié)果

圖11 select_related優(yōu)化后測(cè)試結(jié)果

4 結(jié)語

介紹的兩種方法select_related與prefetch_related 有各自不同的應(yīng)用場(chǎng)景。前面已經(jīng)實(shí)現(xiàn)了查詢圖書信息時(shí)一次性地把圖書訂單也查詢出來,若在此基礎(chǔ)上另增需求,查詢圖書訂單是給定限制條件的,也就是在上述兩種方法基礎(chǔ)上能否使用fileter做進(jìn)上步的過濾呢?會(huì)不會(huì)把已有的優(yōu)化算法破壞掉?那如果確實(shí)是想要在查詢的時(shí)候指定過濾條件該如何做呢,這時(shí)候就得使用django.db.models.Prefetch 來實(shí)現(xiàn),用Prefetch包裹后,即使在查詢文章的時(shí)候使用了filter,也只會(huì)發(fā)生兩次查詢操作。

猜你喜歡
視圖語句代碼
重點(diǎn):語句銜接
創(chuàng)世代碼
創(chuàng)世代碼
創(chuàng)世代碼
創(chuàng)世代碼
視圖
Y—20重型運(yùn)輸機(jī)多視圖
SA2型76毫米車載高炮多視圖
Django 框架中通用類視圖的用法
我喜歡