Trong loạt bài viết này, chúng ta sẽ tìm hiểu cách thiết kế cơ sở dữ liệu cho ứng dụng RESTful API sử dụng Flask Python. Cơ sở dữ liệu là một phần quan trọng trong việc lưu trữ và truy xuất dữ liệu cho ứng dụng của bạn. Trước khi chúng ta bắt đầu xây dựng cơ sở dữ liệu, hãy tìm hiểu về một số khái niệm cơ bản và quyết định thiết kế cơ sở dữ liệu của chúng ta.
1. Khái niệm cơ bản.
a. Cơ sở dữ liệu.
Cơ sở dữ liệu là nơi lưu trữ dữ liệu của bạn. Có nhiều loại cơ sở dữ liệu khác nhau, như cơ sở dữ liệu SQL (ví dụ: MySQL, PostgreSQL), cơ sở dữ liệu NoSQL (ví dụ: MongoDB, Redis), và nhiều hệ thống cơ sở dữ liệu khác.
b. Bảng (Table).
Trong cơ sở dữ liệu SQL, dữ liệu được tổ chức thành các bảng. Mỗi bảng chứa dữ liệu về một loại đối tượng cụ thể. Ví dụ, bạn có thể có một bảng “Users” để lưu trữ thông tin người dùng và một bảng “Posts” để lưu trữ bài đăng.
c. Cột (Column).
Mỗi bảng chứa các cột, đại diện cho các thuộc tính của đối tượng. Ví dụ, bảng “Users” có thể có các cột như “id”, “username”, “email”, và “password”.
d. Dòng (Row).
Dòng trong bảng chứa dữ liệu cụ thể cho một đối tượng hoặc một bản ghi. Ví dụ, một dòng trong bảng “Users” có thể chứa thông tin về một người dùng cụ thể.
2. Thiết kế Cơ sở Dữ liệu.
a. Xác định Loại Dữ liệu.
Trước hết, bạn cần xác định loại dữ liệu bạn muốn lưu trữ. Điều này có thể bao gồm thông tin về người dùng, bài đăng, bình luận, và nhiều loại dữ liệu khác. Dựa trên loại dữ liệu này, bạn có thể bắt đầu xác định các bảng cần thiết.
b. Xác định Các Bảng.
Dựa trên loại dữ liệu, bạn sẽ tạo các bảng tương ứng trong cơ sở dữ liệu của mình. Ví dụ, nếu bạn đang xây dựng một ứng dụng blog, bạn có thể cần tạo các bảng “Users”, “Posts”, và “Comments”.
c. Xác định Các Cột.
Đối với mỗi bảng, xác định các cột cần thiết để lưu trữ thông tin liên quan đến loại dữ liệu tương ứng. Điều này bao gồm các trường thông tin như tên người dùng, tiêu đề bài viết, nội dung bài viết, và thời gian tạo.
d. Xác định Khóa Chính (Primary Key).
Mỗi bảng cần có một cột hoặc một tập hợp các cột đại diện cho khóa chính. Khóa chính là một giá trị duy nhất dùng để xác định một dòng trong bảng. Ví dụ, trong bảng “Users”, khóa chính có thể là cột “id”.
e. Xác định Khóa Ngoại (Foreign Key).
Nếu có mối quan hệ giữa các bảng, bạn cần xác định các khóa ngoại để liên kết chúng với nhau. Ví dụ, trong bảng “Comments”, bạn có thể có một khóa ngoại trỏ đến bài viết tương ứng trong bảng “Posts”.
3. Thiết Kế và Triển Khai Model Cơ Sở Dữ Liệu.
Thiết kế model cơ sở dữ liệu là quá trình quan trọng trong phát triển ứng dụng, nó định nghĩa cách dữ liệu sẽ được tổ chức, lưu trữ và quản lý trong hệ thống của bạn. Model cơ sở dữ liệu là biểu đồ hoặc bản mô tả cụ thể về cách dữ liệu tương tác với nhau trong ứng dụng của bạn. Chúng ta sẽ thảo luận về một số khái niệm cơ bản trong thiết kế model cơ sở dữ liệu và sau đó cung cấp một ví dụ cụ thể.
Dưới đây là một số Khái niệm cơ bản.
- Entities (Thực thể): đại diện cho các đối tượng hoặc khái niệm trong thế giới thực mà bạn muốn lưu trữ thông tin về. Ví dụ: trong một ứng dụng quản lý học sinh, thực thể có thể là “Học sinh”, “Giáo viên”, hoặc “Khóa học”.
- Attributes (Thuộc tính) là các đặc điểm hoặc thông tin liên quan đến một thực thể cụ thể. Ví dụ: trong thực thể “Học sinh”, các thuộc tính có thể là “Tên”, “Tuổi”, “Địa chỉ”.
- Relationships (Mối quan hệ) là cách các thực thể tương tác hoặc liên kết với nhau. Ví dụ: Một học sinh “tham gia” một khóa học hoặc một giáo viên “dạy” nhiều học sinh.
- Constraints (Ràng buộc) là các quy tắc hoặc điều kiện áp dụng cho dữ liệu trong cơ sở dữ liệu. Ví dụ: Ràng buộc “Tuổi không thể âm” đảm bảo rằng tuổi của học sinh không bao giờ là số âm.
Ví dụ về Thiết Kế Model Cơ Sở Dữ Liệu.
Giả sử chúng ta đang phát triển một ứng dụng quản lý thư viện. Trước hết, chúng ta cần xác định các thực thể, thuộc tính và mối quan hệ chính trong ứng dụng này.
- Thực thể:
- Sách (Book):
- Thuộc tính: Mã sách (ID), Tiêu đề, Tác giả, Năm xuất bản, Số lượng tồn kho.
- Thành viên (Member):
- Thuộc tính: Mã thành viên (ID), Tên, Địa chỉ email, Số điện thoại.
- Phiếu mượn (Borrowing):
- Thuộc tính: Mã phiếu mượn (ID), Mã thành viên (ID), Mã sách (ID), Ngày mượn, Ngày trả dự kiến.
- Sách (Book):
- Mối quan hệ:
- Mối quan hệ Một-nhiều giữa Thành viên và Phiếu mượn:
- Một thành viên có thể mượn nhiều sách, nhưng mỗi phiếu mượn chỉ thuộc về một thành viên.
- Điều này được thể hiện qua việc sử dụng Mã thành viên trong Phiếu mượn.
- Mối quan hệ Một-nhiều giữa Sách và Phiếu mượn:
- Một quyển sách có thể được mượn nhiều lần bởi các thành viên khác nhau.
- Điều này được thể hiện qua việc sử dụng Mã sách trong Phiếu mượn.
- Mối quan hệ Một-nhiều giữa Thành viên và Phiếu mượn:
4. Thực hành.
Ở phần này chúng ta chỉ làm các file theo cây thư mục này nhé.
../devnet
├── cisco_os
│ ├── __init__.py
│ ├── backend
│ │ └── arp
│ │ ├── controller.py
│ │ └── services.py
│ ├── config.py
│ ├── extension.py
│ └── model.py
├── network.py
└── venv
├── db_install.sh
└── requirements.txt
- config.py
import os
from dotenv import load_dotenv
load_dotenv()
SECRET_KEY = os.environ.get("KEY")
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL")
SQLALCHEMY_TRACK_MODIFICATIONS = False
- .env
KEY = "hoanghd-secret-key"
DATABASE_URL = 'mysql://hoanghd:Hoanghd164@192.168.13.200/cisco_info'
- __init__.py
from flask import Flask
from .backend.arp.controller import get_arp_bl
from .model import db
def create_db(app):
with app.app_context():
db.create_all()
print("Created DB!")
def create_cisco_os_app(config_file="config.py"):
cisco_os = Flask(__name__)
cisco_os.config.from_pyfile(config_file)
db.init_app(cisco_os)
create_db(cisco_os)
cisco_os.register_blueprint(get_arp_bl)
return cisco_os
- controller.py
from flask import Blueprint
from .services import route_demo_service
get_arp_bl = Blueprint("get_arp_bl", __name__)
@get_arp_bl.route("/route_demo", methods=['GET'])
def route_demo():
return route_demo_service()
- services.py
def route_demo_service():
return "Hello world"
- model.py
from .extension import db
class cisco_arp(db.Model):
id = db.Column(db.Integer, primary_key=True)
address = db.Column(db.String(255))
device = db.Column(db.String(255))
interface = db.Column(db.String(255))
mac_address = db.Column(db.String(255))
ports = db.Column(db.String(255))
def __init__(self, address, device, interface, mac_address, ports):
self.address = address
self.device = device
self.interface = interface
self.mac_address = mac_address
self.ports = ports
- extension.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
- network.py
from cisco_os import create_cisco_os_app
if __name__ == "__main__":
cisco_network = create_cisco_os_app()
cisco_network.run(debug=True, host='0.0.0.0', port=5000)
Cấu trúc thư mục và mã nguồn của dự án trên là một ứng dụng web Python sử dụng Flask và SQLAlchemy để quản lý cơ sở dữ liệu.
Dưới đây là giải thích về cách chúng hoạt động:
- config.py: Đây là file cấu hình của ứng dụng. Nó được sử dụng để cấu hình ứng dụng bằng cách đọc các biến môi trường từ file
.env
.SECRET_KEY
vàSQLALCHEMY_DATABASE_URI
là các biến cấu hình được sử dụng trong ứng dụng. - .env: Đây là file chứa các biến môi trường, chẳng hạn như
SECRET_KEY
vàDATABASE_URL
. Các biến này được đọc bởiconfig.py
để cấu hình ứng dụng. - init.py: Đây là một file
__init__.py
trong góicisco_os
. Nó chứa hai hàm quan trọng:create_db(app)
: Hàm này được sử dụng để tạo cơ sở dữ liệu. Nó sử dụngapp.app_context()
để làm việc với ứng dụng Flask và gọidb.create_all()
để tạo bảng trong cơ sở dữ liệu.create_cisco_os_app(config_file="config.py")
: Hàm này tạo và cấu hình ứng dụng Flask. Nó sử dụngconfig_file
để cấu hình ứng dụng. Sau đó, nó kết nối cơ sở dữ liệu thông qua SQLAlchemy, gọicreate_db
để tạo cơ sở dữ liệu và đăng ký blueprintget_arp_bl
.
- controller.py: Đây là module điều khiển của blueprint
get_arp_bl
. Nó định nghĩa một tuyến đường (route
)/route_demo
, mà khi được gọi, nó sẽ gọi hàmroute_demo_service
và trả về chuỗi “Hello world”. - services.py: Đây là module chứa logic xử lý dịch vụ (service) cho ứng dụng. Trong trường hợp này, nó chỉ đơn giản trả về chuỗi “Hello world” khi được gọi bởi tuyến đường
/route_demo
. - model.py: Đây là module chứa định nghĩa của một model cơ sở dữ liệu sử dụng SQLAlchemy. Model
cisco_arp
đại diện cho một bảng trong cơ sở dữ liệu với các cột nhưid
,address
,device
,interface
,mac_address
, vàports
. - extension.py: Đây là module chứa khởi tạo đối tượng SQLAlchemy (
db
) để làm việc với cơ sở dữ liệu. - network.py: Đây là module chính của ứng dụng. Nó sử dụng hàm
create_cisco_os_app
để tạo ứng dụng Flask và sau đó chạy ứng dụng trên máy chủ cục bộ với debug mode được bật và lắng nghe trên cổng 5000.
Khi bạn chạy file network.py
, nó sẽ tạo ứng dụng Flask, kết nối đến cơ sở dữ liệu và lắng nghe các yêu cầu HTTP tới cổng 5000 trên máy tính của bạn. Các tuyến đường (routes) được định nghĩa trong controller.py
và gọi các dịch vụ xử lý logic từ services.py
để xử lý các yêu cầu và trả về kết quả tương ứng.
(.venv) root@flask-13-200:/home/devnet# python3 network.py
Created DB!
* Serving Flask app 'cisco_os'
* Debug mode: on
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://192.168.13.200:5000
Press CTRL+C to quit
* Restarting with stat
Created Table!
* Debugger is active!
* Debugger PIN: 101-494-363
Bạn sẽ nhận được một thông báo Created Table! chúng ta đã thực hiện trong hàm tạo DB ở trên, bây giờ mình dùng Navicat để vào DB kiểm tra và bạn sẽ thấy các bảng đã được tạo.
4. Kết luận.
Thiết kế model cơ sở dữ liệu là bước quan trọng trong quá trình phát triển ứng dụng. Nó giúp bạn tổ chức dữ liệu một cách hiệu quả và xác định cách dữ liệu tương tác với nhau. Khi bạn đã thiết kế mô hình cơ sở dữ liệu của mình, bạn có thể triển khai nó bằng cách sử dụng hệ quản trị cơ sở dữ liệu phù hợp và ORM (Object-Relational Mapping) nếu cần thiết.
Trong bài viết này, chúng ta đã tìm hiểu về cách thiết kế cơ sở dữ liệu cho ứng dụng RESTful API bằng Flask Python. Việc thiết kế cơ sở dữ liệu là một phần quan trọng trong việc phát triển ứng dụng và đảm bảo rằng bạn có thể lưu trữ và truy xuất dữ liệu một cách hiệu quả. Tiếp theo, chúng ta sẽ xem xét cách sử dụng Flask và SQLAlchemy để tương tác với cơ sở dữ liệu của chúng ta trong ứ