使用數據圖視圖的起因
最近在做一個銷售數據統計的功能,把數據表中的實時產生的銷售數據按天做統計計算。於是在MySQL數據庫中做了一個視圖,很容易得到每天的統計數據,並且有新的數據產生時,能實時查看到當天的數據更新。
視圖的數據是建立在數據表基礎上的,把統計的SQL調試好之后,生成數據庫視圖,后續的查詢可以直接數據庫視圖來完成,這樣在Django中編寫查詢的代碼就簡單多了,不需要做統計計算。
Django訪問數據庫視圖
參照網上找的資料,Django訪問數據庫視圖的參考代碼如下,重點是class Meta信息中要設置 managed = False。表格的字段申明要與視圖的字段一一對應,另外主鍵字段和排序字段的申明,似乎不能起到作用。
# 備份表格,用於數據同步 class BranchDailyAchievementBackup(models.Model): branchid = models.IntegerField(primary_key=True) fullname = models.CharField(max_length=_LEN_FULLNAME, verbose_name='名稱') cdate = models.DateField() sumtotal = models.FloatField() class Meta: managed = False ordering = ["cdate", "branchid"] db_table = "branchdailyachv_backup"
到這里已經可以用這個Model 來查詢數據庫視圖的數據了。
問題來了:
實際測試時,發現這里的查詢操作實際上非常慢,可能是每次查詢,都在數據庫中重新執行一次視圖的SQL語句。但是如果把數據庫視圖轉變成數據表之后,這些數據已經存在表格中了,查詢起來就快多了。
對於數據庫中已有的表格數據訪問方式,和數據庫視圖的訪問方式一樣,可以按上面的方法定義Model。
把數據從視圖轉存到表格的SQL語句如下:
CREATE TABLE branchdailyachv_backup AS SELECT * FROM branchdailyachv_view;
這樣又帶來一個問題:視圖中的數據轉存到表格后,數據已經固化了,不會因為新的數據產生而動態更新了。
結合現在統計數據的特點,只需要更新當天的數據就可以了,之前的數據不會發生變化。
於是有了新的思路:
先用根據視圖生成一個數據表格1,然后定時的生成數據表2,然后把表2中最新的數據更新到表1。這樣表1是一直存在並且定時更新的,表2會不斷的重新生成,每次生成之前需要刪除數據表,但是用戶的查詢操作是針對表1的,所以表2的刪除操作對用戶查詢不影響。
然后按照這個思路寫代碼,做好之后又出現了新的問題:
在更新這個表1的數據時,執行save()操作之后,數據庫中會出現很多條重復的記錄。具體的原因不清楚,但應該是因為設置了 managed = False的原因。
重新整理思路:
- 創建數據庫視圖
- 根據數據庫視圖生成數據表格2.
- 在Django中生編寫表格模型1, managed = True 。
- 編寫訪問數據庫視圖的模型2,設置 managed = False,並且讓表格1和表格2的內容一致。
- 定時將表格2的數據更新到表格1。 首次更新操作時,表格1的內容為空,需要將表格2的全部數據更新到表格1。這樣Django就能正常地查詢表格1的數據了,並且因為用戶不會查詢表格2,所以表格2刪除后重建也不會有影響。