返回文章列表

資料函式庫操作與進階查詢技術

本文探討資料函式庫的 CRUD 操作與進階查詢技術,涵蓋新增、讀取、更新、刪除記錄的 SQL 語法與實務案例,並解析子查詢、連線查詢、聚合函式、HAVING 篩選條件以及視窗函式等進階查詢技巧。同時,文章也介紹資料函式庫遷移與版本控制的重要性,說明如何使用 Alembic

資料函式庫 後端開發

資料函式庫操作是應用程式開發的根本,有效管理和查詢資料對於系統效能和穩定性至關重要。本文從 CRUD 操作開始,逐步介紹 SQL 的基本語法和使用方法,並搭配實際案例說明如何在資料函式庫中新增、讀取、更新和刪除記錄。接著,文章探討進階查詢技術,例如子查詢、連線查詢、聚合函式等,幫助開發者編寫更複雜、更具效率的 SQL 查詢。此外,文章也涵蓋了資料函式庫遷移和版本控制的議題,說明如何使用 Alembic 等工具管理資料函式庫結構變更,確保資料函式庫與應用程式碼同步更新,避免資料函式庫版本衝突。最後,文章介紹了 Python ORM 的概念和使用方法,特別是 SQLAlchemy,示範如何使用 Python 程式碼簡化資料函式庫操作,提升開發效率。

資料函式庫操作與進階查詢技術

在大學管理系統的資料函式庫設計中,CRUD(新增、讀取、更新、刪除)操作是基本且重要的功能。以下將詳細說明這些操作的實作方式及其重要性,並進一步探討進階查詢技術。

CRUD 操作實務

新增記錄(CREATE)

資料的新增是透過 SQL 的 INSERT INTO 陳述式來完成。以下範例展示如何新增學生、課程以及學生的選課記錄。

-- 新增一名學生
INSERT INTO Students (Student_ID, Name, Email, Enrollment_Date)
VALUES (1, 'John Doe', '[email protected]', '2023-01-01');

-- 新增一門課程
INSERT INTO Courses (Course_ID, Course_Name, Course_Description)
VALUES (101, 'Introduction to SQL', 'A beginner course on SQL.');

-- 新增選課記錄
INSERT INTO Enrollments (Enrollment_ID, Student_ID, Course_ID, Enrollment_Date)
VALUES (1, 1, 101, '2023-01-10');

內容解密:

  1. INSERT INTO Students 將新的學生資料加入 Students 表格中,需指定 Student_IDNameEmailEnrollment_Date
  2. INSERT INTO Courses 將新的課程資料加入 Courses 表格中,需指定 Course_IDCourse_NameCourse_Description
  3. INSERT INTO Enrollments 將學生的選課記錄加入 Enrollments 表格,需指定 Enrollment_IDStudent_IDCourse_IDEnrollment_Date
  4. 這些操作將資料新增至相應的表格中,以建立學生、課程和選課記錄之間的關聯。

讀取記錄(READ)

資料的讀取是透過 SQL 的 SELECT 陳述式來完成。以下範例展示如何從表格中檢索資料。

-- 檢索 Students 表格中的所有欄位
SELECT * FROM Students;

-- 根據 Course_ID 檢索特定的課程
SELECT * FROM Courses WHERE Course_ID = 101;

-- 檢索包含學生和課程詳細資訊的選課記錄
SELECT s.Name, c.Course_Name, e.Enrollment_Date
FROM Enrollments e
JOIN Students s ON e.Student_ID = s.Student_ID
JOIN Courses c ON e.Course_ID = c.Course_ID;

內容解密:

  1. SELECT * FROM Students; 用於檢索 Students 表格中的所有資料。
  2. SELECT * FROM Courses WHERE Course_ID = 101; 用於根據 Course_ID 檢索特定的課程資訊。
  3. 第三個查詢使用 JOIN 操作將 EnrollmentsStudentsCourses 表格結合,以檢索學生的選課記錄和相關的學生及課程資訊。
  4. 這些查詢展示瞭如何從資料函式庫中檢索所需的資料。

更新記錄(UPDATE)

現有記錄的修改是透過 SQL 的 UPDATE 陳述式來完成。以下範例展示如何更新 StudentsCourses 表格中的資料。

-- 更新學生的電子郵件地址
UPDATE Students
SET Email = '[email protected]'
WHERE Student_ID = 1;

-- 更新課程描述
UPDATE Courses
SET Course_Description = 'An updated description of the course.'
WHERE Course_ID = 101;

內容解密:

  1. 第一個 UPDATE 陳述式更新特定學生的電子郵件地址,需指定 Student_ID
  2. 第二個 UPDATE 陳述式更新特定課程的描述,需指定 Course_ID
  3. 這些操作確保資料的正確性和時效性。

刪除記錄(DELETE)

記錄的刪除是透過 SQL 的 DELETE 陳述式來完成。以下範例展示如何從 EnrollmentsStudents 表格中刪除記錄。

-- 刪除一筆選課記錄
DELETE FROM Enrollments
WHERE Enrollment_ID = 1;

-- 刪除一名學生及其所有選課記錄(需設定 CASCADE DELETE)
DELETE FROM Students
WHERE Student_ID = 1;

內容解密:

  1. 第一個 DELETE 陳述式刪除特定的選課記錄,需指定 Enrollment_ID
  2. 第二個 DELETE 陳述式刪除特定的學生,需先確保相關的選課記錄已刪除,或設定外部索引鍵約束為 CASCADE DELETE 以自動刪除相關的選課記錄。
  3. 這類別操作需謹慎進行,以保持資料的一致性。

進階查詢技術

子查詢(Subqueries)

子查詢是用於巢狀在另一個 SQL 查詢中的查詢,通常用於篩選或計算。

-- 找出尚未有學生選修的課程
SELECT Course_ID, Course_Name
FROM Courses
WHERE Course_ID NOT IN (SELECT Course_ID FROM Enrollments);

內容解密:

  1. 子查詢 (SELECT Course_ID FROM Enrollments) 用於取得所有已開課的 Course_ID
  2. 主查詢則找出不在子查詢結果中的課程,即尚未有學生選修的課程。
  3. 這類別查詢可用於多步驟的資料篩選和計算。

連線查詢(Joins)

連線查詢用於結合多個表格中的資料,根據相關的欄位。

-- 列出學生及其選修的課程
SELECT s.Name, s.Email, c.Course_Name
FROM Students s
JOIN Enrollments e ON s.Student_ID = e.Student_ID
JOIN Courses c ON e.Course_ID = c.Course_ID;

內容解密:

  1. 使用 JOIN 操作將 StudentsEnrollmentsCourses 表格結合,根據相關的欄位。
  2. 這類別查詢提供了一個綜合檢視,顯示哪些學生選修了哪些課程。

聚合函式(SQL Aggregate Functions)

聚合函式對一組值進行計算並傳回單一值,通常與 GROUP BY 陳述式一起使用。

-- 統計每門課程的學生人數
SELECT c.Course_Name, COUNT(*) as Student_Count
FROM Courses c
JOIN Enrollments e ON c.Course_ID = e.Course_ID
GROUP BY c.Course_Name;

內容解密:

  1. 使用聚合函式 COUNT(*) 統計每門課程的學生人數。
  2. 結果按課程名稱分組,顯示每門課程的選修人數。

HAVING 篩選條件

HAVING 子句用於篩選分組後的結果,通常與聚合函式一起使用。

-- 列出選修人數超過5人的課程
SELECT c.Course_Name, COUNT(*) as Student_Count
FROM Courses c
JOIN Enrollments e ON c.Course_ID = e.Course_ID
GROUP BY c.Course_Name
HAVING COUNT(*) > 5;

內容解密:

  1. 使用 HAVING COUNT(*) > 5 篩選出選修人數超過5人的課程。
  2. 這類別查詢可用於進一步分析聚合後的資料。

視窗函式(Window Functions)

視窗函式對一組相關的行進行計算,但不將結果合併為單一行。

-- 按選課日期對每門課程中的學生進行排序
SELECT s.Name, c.Course_Name, e.Enrollment_Date,
RANK() OVER (PARTITION BY e.Course_ID ORDER BY e.Enrollment_Date) as Enrollment_Rank
FROM Enrollments e
JOIN Students s ON e.Student_ID = s.Student_ID
JOIN Courses c ON e.Course_ID = c.Course_ID;

內容解密:

  1. 使用視窗函式 RANK() 對每門課程中的學生按選課日期進行排序。
  2. 結果顯示每個學生在其選修課程中的相對順序,而不會合併結果。

資料函式庫遷移與版本控制

隨著時間的推移,資料函式庫結構的變更需要在不丟失資料的情況下進行處理。這就是資料函式庫遷移的作用。在敏捷開發環境中開發的應用程式經常需要對資料函式庫結構進行反覆變更,使得這個過程變得至關重要。為了妥善管理資料函式庫遷移,需要以可以套用、回復和版本控制的方式追蹤所有結構變更,使其與應用程式碼保持同步。

瞭解資料函式庫遷移

資料函式庫遷移通常包括新增或刪除資料表、修改資料表以新增或移除欄位,或是變更索引和約束條件等修改。這些變更被儲存在遷移指令碼中,這些指令碼是可以執行以修改資料函式庫結構的檔案。這些指令碼不僅更新結構,還確保現有資料符合新的結構而不丟失。

有多種工具可用於促進資料函式庫遷移,每種工具都與不同型別的資料函式庫和框架相容。對於根據 Python 的應用程式,特別是那些使用 SQLAlchemy 的應用程式,經常使用像 Alembic 這樣的工具。Alembic 為 SQLAlchemy 提供了一個遷移框架,可以可靠且有效地遷移資料函式庫。

設定 Alembic

要設定 Alembic 進行資料函式庫遷移管理:

  1. 安裝 Alembic:

    pip install alembic
    
  2. 初始化 Alembic: 前往您的專案目錄並執行:

    alembic init alembic
    

    此命令會建立一個名為 alembic 的新目錄,其中包含您的遷移指令碼和一個 alembic.ini 設定檔。

  3. 設定 Alembic: 修改 alembic.ini 檔案以指定到您的資料函式庫的連線字串。您還需要在 alembic 目錄內的 env.py 檔案中設定如何使用 SQLAlchemy 連線到您的資料函式庫。

    from myapp.models import Base  # 假設您的模型在 myapp/models.py 中
    target_metadata = Base.metadata
    

建立和套用遷移

一旦設定好 Alembic,您就可以建立和套用遷移:

  1. 建立遷移: 要根據您的模型和目前資料函式庫結構之間的差異自動產生新的遷移指令碼,請執行:

    alembic revision --autogenerate -m "變更描述"
    

    此命令會在您的 Alembic 目錄內的 versions 資料夾中新增一個新的指令碼。檢閱此指令碼以確保它準確代表所需的變更。

  2. 編輯遷移指令碼: 有時候,自動產生可能無法完美捕捉複雜的變更或特定的資料函式庫操作。在這種情況下,手動編輯 versions 目錄中的遷移指令碼以修正或改進操作。

  3. 套用遷移: 要將資料函式庫更新到最新版本,請使用:

    alembic upgrade head
    

    此命令會將所有待處理的遷移套用到資料函式庫。若要回復,可以使用:

    alembic downgrade -1
    

    此命令會還原最後套用的遷移。

管理結構變更

使用版本控制管理資料函式庫結構變更涉及:

  • 版本控制:每個遷移指令碼都有時間戳記,並與您的應用程式碼一起儲存在版本控制儲存函式庫中。這種同步允許您將應用程式碼的每個狀態與對應的資料函式庫結構狀態相匹配。
  • 協作:在團隊中工作時,遷移確保所有成員都在使用相同的資料函式庫結構。在提取包含新遷移的變更後,團隊成員可以將這些遷移套用到他們的本地開發資料函式庫。
  • 佈署:在佈署過程中,遷移會作為佈署過程的一部分被套用。這確保生產資料函式庫結構與佈署版本的應用程式所期望的結構相匹配。

將 Python 與 ORM 結合使用於資料函式庫操作

Python ORM 總覽

Python ORM 充當 Python 程式碼和資料函式庫之間的橋樑,允許使用 Python 操作與資料函式庫互動。這消除了手動建構 SQL 查詢的大部分需求,從而減少了 SQL 注入攻擊和語法錯誤的可能性。流行的 Python ORM 包括 SQLAlchemy、Django ORM 和 Peewee。本文將探討 SQLAlchemy,因為它在所有可用選項中具有豐富的功能。

SQLAlchemy 總覽

SQLAlchemy 是 Python 生態系統中最具特色的靈活 ORM 之一。它為關聯式資料函式庫提供了全面的支援,並提供了兩種不同的使用正規化之間的選擇:SQLAlchemy Core 和 SQLAlchemy ORM。

SQLAlchemy Core

Core 以使用 Python 物件表示的 SQL 表示式為中心,並且是以結構為中心的。它允許對 SQL 進行精確控制,非常適合不完全符合 Active Record 模式的複雜資料函式庫操作。

SQLAlchemy ORM

ORM 是更高層次的介面,允許您處理與資料表相關聯的模型和類別。它包括一個關係系統,可以用來自動儲存物件及其相關物件中的變更。

將 SQLAlchemy ORM 與 Python 結合

要將 SQLAlchemy ORM 整合到 Python 應用程式中,您需要遵循幾個步驟來設定並利用 ORM 操作資料函式庫條目。

安裝

首先使用 pip 安裝 SQLAlchemy。

pip install SQLAlchemy

定義模型

SQLAlchemy 中的模型是定義資料表結構的類別。類別的每個屬性對應於資料表中的一個欄位。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)

# 建立一個儲存在本地目錄中的引擎
engine = create_engine('sqlite:///mydatabase.db')
Base.metadata.create_all(engine)

建立工作階段

SQLAlchemy 使用工作階段來管理與資料函式庫繫結的物件上的操作。工作階段建立了與資料函式庫的所有對話,並代表了在其生命週期內載入或與其關聯的所有物件的「暫存區」。

Session = sessionmaker(bind=engine)
session = Session()

執行資料函式庫操作

  1. 建立

    new_user = User(name='John Doe', email='[email protected]')
    session.add(new_user)
    session.commit()
    
  2. 讀取

    user = session.query(User).filter_by(name='John Doe').first()
    print(user.email)
    
  3. 更新

    user.email = '[email protected]'
    session.commit()
    
  4. 刪除

    session.delete(user)
    session.commit()
    

透過將 SQLAlchemy 整合到您的 Python 應用程式中,您可以使資料函式庫互動變得更加容易。它能夠抽象出原始 SQL 查詢,使程式碼更乾淨、更易於維護。此外,它還提供了強大的工具,如自動結構遷移、關係管理和工作單元實作,可以處理甚至最複雜的資料模型。

# 示範如何建立 User 物件並將其新增至工作階段
new_user = User(name='Jane Doe', email='[email protected]')
session.add(new_user)
session.commit()

#### 內容解密:
1. **`new_user = User(name='Jane Doe', email='[email protected]')`**建立一個新的 `User` 物件代表一個名為 'Jane Doe' 且電子郵件為 '[email protected]' 的使用者
2. **`session.add(new_user)`**將新建立的使用者物件新增至工作階段使其成為待處理的操作
3. **`session.commit()`**提交工作階段中的待處理操作將新的使用者記錄插入到 'users' 資料表中
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 資料函式庫操作與進階查詢技術

package "資料庫架構" {
    package "應用層" {
        component [連線池] as pool
        component [ORM 框架] as orm
    }

    package "資料庫引擎" {
        component [查詢解析器] as parser
        component [優化器] as optimizer
        component [執行引擎] as executor
    }

    package "儲存層" {
        database [主資料庫] as master
        database [讀取副本] as replica
        database [快取層] as cache
    }
}

pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中

master --> replica : 資料同步

note right of cache
  Redis/Memcached
  減少資料庫負載
end note

@enduml