# 管理資料:Data Models
## 資料庫概論
在作業系統出現之後,隨著電腦應用範圍的擴大、需要處理的資料迅速膨脹。最初,資料與程式一樣,以簡單的檔案作為主要儲存形式。
以這種方式組織的資料在邏輯上更簡單,但可延伸性差,存取這種資料的程式需要了解資料的具體組織格式。
當系統資料量大或者使用者瀏覽量大時,應用程式還需要解決資料的完整性、一致性以及安全性等一系列的問題。
因此,必須開發出一種系統軟體,它應該能夠像作業系統封鎖了硬體存取複雜性那樣,封鎖資料存取的複雜性。由此產生了資料管理系統,即資料庫。
重要名詞:
- 紀錄(record):資料的最小單位
- 資料表(Table):儲存多個紀錄
- 資料庫(Database):儲存多個資料表
- 資料庫管理系統(Database Management System,簡稱DBMS):儲存多個資料庫的軟體系統
- 資料庫概要(Database Schema):描述資料庫的定義
## 資料庫管理系統的種類
### 關聯式資料庫管理系統
Relational Database Management System,簡稱RDMS。
關聯式資料庫是一組資料項目,項目之間具有預先定義的關係。
這些項目會整理成由直欄和橫列構成的一組表格
- 表格會儲存資料庫中所要表示的物件的相關資訊
- 表格的每一直欄儲存特定類型(`Data Type`)的資料
- 每個欄位儲存某個屬性的實際數值
- 表格中的橫列代表一個物件或實體的一組相關數值
- 表格的每一橫列可以用稱為主索引鍵的唯一識別符(`Primary Key`)加以標記,
Data schema
| 學號 | 姓名 | 電話 |
| -------- | -------- | -------- |
| INTEGER | CHAR(50) | CHAR(50) |
Data Table
| 學號 | 姓名 | 電話 |
| -------- | -------- | -------- |
| S1300001 | AAA | 0911-123-123 |
| S1300001 | AAA | 0911-123-123 |
| S1300001 | AAA | 0911-123-123 |
常見的RDMS:MySQL, PostgreSQL
### 非關聯式資料庫管理系統
又稱NOSQL,使用key-value方式儲存資料
## 存取資料庫管理系統的方法
### 使用SQL語言
Structured Query Language:結構化查詢語言,是一種領域特定語言(domain-specific language、DSL),專注於某個應用程式領域的計算機語言
SQL語言基本指令:
- `INSERT`: 在資料表插入一筆新記錄
- `UPDATE`: 更新資料表的記錄,這些記錄是已經存在的記錄
- `DELETE`: 刪除資料表的記錄
- `SELECT`: 查詢資料表的記錄,使用條件子句查詢資料表符合條件的記錄
### 使用ORM
ORM, Object-relational mapping,利用物件導向的語法來對應SQL指令,有以下優點
- 安全性提升:避免SQL injection攻擊
- 語法較直覺
- 不需改寫程式就可更換不同資料庫系統
Django的資料庫模組,就是使用ORM的方式存取資料庫。
## 開始設計部落格的功能
### 確認開發環境
1. 啟動虛擬環境blogVenV: $`activate.bat`
2. 安裝ProgreSQL:
- 至[官網](https://www.postgresql.org/download/)下載安裝檔
- 安裝程式中,勾選設定如下
- 取消勾選 `Stack Builder`
- 設定super user password: `postgres`
- port 保留預設值(`5432`)
- Locale 保留預設值(`Default Locale`)
3. 安裝ProgreSQL driver: $`pip install psycopg2`
4. 啟動ProgreSQL(通常開機會自動啟動)
:::info
MacOS開發者,請使用以下指令啟動
$ brew servicesc start postgresql
:::
### 新建資料庫
1. 切換路徑至C:\Program Files\PostgreSQL\\`版本號碼`\bin
2. 輸入指令
- $ `set PGUSER=postgres`
- $ `set PGPASSWORD=postgres`
- $ `createdb blogdb`
- $ `createuser -P dbuser`
enter password for new role: `dbuser`
- $ `psql`
- \# `grant all privileges on database blogdb to dbuser;`
- \# `\q`
### 編輯專案設定檔
編輯 `blog/settings.py`
```python=
DATABASES = {
'default':{
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'blogdb',
'USER': 'dbuser',
'PASSWORD': 'dbuser',
'HOST': 'localhost',
'POST': '',
}
...
LANGUAGE_CODE = 'zh-hant'
TIME_ZONE = 'Asia/Taipei'
}
```
### 資料庫變更儲存
1. 啟用虛擬環境(blogVenv)
2. (blogVenv)$ `python manage.py makemigrations`
3. (blogVenv)$ `python manage.py migrate`
以上,就完成資料庫的基礎安裝跟設定。
### 功能實作:建立後端資料庫
:::info
1. 建立data model
2. 執行資料庫變更儲存
3. 建立資料庫系統管理者
4. 設計資料庫操作程式
5. 設計快速填充資料程式
6. 建立資料庫系統新使用者
7. 客製化管理者頁面
8. 增加model欄位(修改data schema)
9. 重建資料庫資料
:::
1. 在`article/models.py`建立`Article`與`Comment` 這兩個Data Model
```python=
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=128, unique=True)
content = models.TextField()
def __str__(self):
return self.title
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete =models.CASCADE)
content = models.CharField(max_length=128)
def __str__(self):
return self.article.title + '-' + str(self.id)
```
2. 執行資料庫變更儲存
- 啟用虛擬環境
- $ `python manage.py makemigrations`
- $ `python manage.py migrate`
:::info
常用的欄位資料型態
- CharField: 單行字元
- TextField: 單行字元
- DateField: 日期
- DateTimeField: 日期時間
- EmailField: E-mail
:::
3. 建立資料庫系統管理者與後台資料表管理註冊
- 建立superuser
(blogVenv)$ `python manage.py createsuperuser`
username: admin
email: `自己寫`
Password: `admin12345`
Password(again): `admin12345`
看到以下訊息表示建立成功
`Superuser created successfully`
- 在`article/admin.py`登記資料表
```python=
from django.contrib import admin
from article.models import Article, Comment
admin.site.register(Article)
admin.site.register(Comment)
```
在瀏覽器網址列輸入`localhost:8000/admin/`即可進入管理者頁面
4. 設計快速填充資料程式
- 在專案底下新建一個目錄資料夾`populate`
- 在目錄資料夾`populate`新建一個檔案 \_\_init\_\_.py,空白即可
- 在目錄資料夾`populate`新建一個檔案 base.py,內容如下
```python=
import os
import django
# 視專案名稱修改blog.settings命名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blog.settings')
django.setup()
```
- 在目錄資料夾`populate`新建一個檔案 article.py,內容如下
5. 建立資料庫系統新使用者
6.
7. 增加model欄位(修改data schema)
8. 重建資料庫資料