嘿馬頭條專案從到完整開發筆記總結完整教程(附程式碼資料)主要內容講述:課程簡介,ToutiaoWeb虛擬機器使用說明,Pycharm遠端開發,產品與開發,資料庫1 產品介紹,2 原型圖與UI圖,3 技術架構,4 開發。OSS物件儲存,七牛雲端儲存,CDN,快取。快取,快取架構,快取資料,快取有效期與淘汰策略,快取模式快取資料的型別,快取資料的儲存方式,有效期 TTL (Time to live),快取淘汰 eviction。快取,快取問題,頭條專案快取與儲存設計,頭條專案快取實現,專案Redis持久儲存實現,APScheduler定時任務,APScheduler使用1 快取穿透,2 快取雪崩,快取設計,持久儲存設計。APScheduler定時任務,定時修正統計資料,RPC,RPC簡介,RPC結構,gRPC,簡介1. 什麼是RPC,2. 背景與用途,3. 概念說明,4. 優缺點,架構,使用方法。RPC,Protocol Buffers,推薦系統介面定義,補全服務端1 文件結構,2 註釋,3 資料型別,4 訊息型別,5 map對映,6 oneof,7 定義服務,程式碼生成。RPC,編寫客戶端,頭條首頁新聞推薦介面編寫,即時通訊,即時通訊簡介,WebSocket。即時通訊,Socket.IO,頭條聊天服務實現,頭條線上訊息推送實現,Elasticsearch1 簡介,2 Python伺服器端開發,3 Python客戶端。Elasticsearch,簡介與原理。Elasticsearch,概念與叢集,IK中文分析器,索引與型別概念,Elasticsearch 叢集(cluster),索引,型別和對映。Elasticsearch,文件,Logstash匯入資料,查詢,頭條全文檢索實現,聯想提示,頭條suggest查詢實現。資料庫,資料庫設計1 需求,2 注意事項,3 頭條專案資料庫。單元測試,部署相關,Gunicorn,Supervisor。資料庫,理解ORM,SQLAlchemy對映構建1 簡介,2 安裝,3 資料庫連線設定,4 模型類欄位與選項,5 構建模型類對映。資料庫,SQLAlchemy操作1 新增,2 查詢,3 更新,4 刪除,5 事務。資料庫,資料庫理論1. 複製集與分散式,2. MySQL。資料庫,分散式ID,資料庫最佳化1 方案選擇,2 黑馬頭條,1 理解索引,2 SQL查詢最佳化,3 資料庫最佳化。資料庫,Redis,Git工用流1 Redis事務,2 Redis持久化,3 Redis高可用,4 Redis叢集,5 用途,6 相關補充閱讀。Git工用流,Gitflow工作流,Git總結,頭條專案目錄1 Gitflow工作流分支,2 Confict衝突解決。Git工用流,除錯方法,JWT認證方案,JWT & JWS & JWE,JWT的Python庫,頭條專案實施方案,JWT禁用問題,OSS物件儲存。
全套筆記資料程式碼移步: 前往gitee倉庫檢視
感興趣的小夥伴可以自取哦,歡迎大家點贊轉發~
全套教程部分目錄:
部分檔案圖片:
資料庫
-
資料庫設計
-
SQLAlchemy
-
資料庫理論
-
分散式ID
-
Redis
理解ORM
作用
-
省去自己拼寫SQL,保證SQL語法的正確性
-
一次編寫可以適配多個資料庫
-
防止注入
-
在資料庫表名或欄位名發生變化時,只需修改模型類的對映,無需修改資料庫操作的程式碼
(相比SQL的話,可能需要同步修改涉及到的每一個SQL語句)
思考:
可否在已經存在資料庫表的情況下,使用模型類進行操作?
使用ORM的方式選擇
-
先建立模型類,再遷移到資料庫中
- 優點:簡單快捷,定義一次模型類即可,不用寫sql
- 缺點:不能盡善盡美的控制建立表的所有細節問題,表結構發生變化的時候,也會難免發生遷移錯誤
-
先用原生SQL建立資料庫表,再編寫模型類作對映
- 優點:可以很好的控制資料庫表結構的任何細節,避免發生遷移錯誤
- 缺點:可能編寫工作多(編寫sql與模型類,似乎有些牽強)
頭條專案採用編寫原生SQL建立表,之後再編寫模型類進行對映的方式。
SQLAlchemy對映構建
1 簡介
SQLAlchemy是Python程式語言下的一款開源軟體。提供了SQL工具包及物件關係對映(ORM)工具,使用MIT許可證發行。
SQLAlchemy“採用簡單的Python語言,為高效和高效能的資料庫訪問設計,實現了完整的企業級持久模型”。
SQLAlchemy首次發行於2006年2月,並迅速地在Python社群中最廣泛使用的ORM工具之一,不亞於Django的ORM框架。
Flask-SQLAlchemy是在Flask框架的一個擴充套件,其對SQLAlchemy進行了封裝,目的於簡化在 Flask 中 SQLAlchemy 的 使用,提供了有用的預設值和額外的助手來更簡單地完成日常任務。
2 安裝
安裝Flask-SQLAlchemy
pip install flask-sqlalchemy
如果使用的是MySQL資料庫,還需要安裝MySQL的Python客戶端庫
pip install mysqlclient
3 資料庫連線設定
在Flask中使用Flask-SQLAlchemy需要進行配置,主要配置以下幾項:
-
SQLALCHEMY_DATABASE_URI
資料庫的連線資訊- Postgres:
postgresql://user:password@localhost/mydatabase
* MySQL:
```python
mysql://user:password@localhost/mydatabase
- Oracle:
oracle://user:password@127.0.0.1:1521/sidname
- SQLite (注意開頭的四個斜線):
sqlite:////absolute/path/to/foo.db
-
SQLALCHEMY_TRACK_MODIFICATIONS
在Flask中是否追蹤資料修改 -
SQLALCHEMY_ECHO
顯示生成的SQL語句,可用於除錯
這些配置引數需要放在Flask的應用配置(app.config
)中。
from flask import Flask
app = Flask(__name__)
class Config(object):
SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1:3306/toutiao'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
app.config.from_object(Config)
其他配置參考如下:
名字 | 備註 |
---|---|
SQLALCHEMY_DATABASE_URI | 用於連線的資料庫 URI 。例如:sqlite:////tmp/test.dbmysql://username:password@server/db |
SQLALCHEMY_BINDS | 一個對映 binds 到連線 URI 的字典。更多 binds 的資訊見[用 Binds 操作多個資料庫]( |
SQLALCHEMY_ECHO | 如果設定為Ture, SQLAlchemy 會記錄所有 發給 stderr 的語句,這對除錯有用。(列印sql語句) |
SQLALCHEMY_RECORD_QUERIES | 可以用於顯式地禁用或啟用查詢記錄。查詢記錄 在除錯或測試模式自動啟用。更多資訊見get_debug_queries()。 |
SQLALCHEMY_NATIVE_UNICODE | 可以用於顯式禁用原生 unicode 支援。當使用 不合適的指定無編碼的資料庫預設值時,這對於 一些資料庫介面卡是必須的(比如 Ubuntu 上 某些版本的 PostgreSQL )。 |
SQLALCHEMY_POOL_SIZE | 資料庫連線池的大小。預設是引擎預設值(通常 是 5 ) |
SQLALCHEMY_POOL_TIMEOUT | 設定連線池的連線超時時間。預設是 10 。 |
SQLALCHEMY_POOL_RECYCLE | 多少秒後自動回收連線。這對 MySQL 是必要的, 它預設移除閒置多於 8 小時的連線。注意如果 使用了 MySQL , Flask-SQLALchemy 自動設定 這個值為 2 小時。 |
4 模型類欄位與選項
欄位型別
型別名 | python中型別 | 說明 |
---|---|---|
Integer | int | 普通整數,一般是32位 |
SmallInteger | int | 取值範圍小的整數,一般是16位 |
BigInteger | int或long | 不限制精度的整數 |
Float | float | 浮點數 |
Numeric | decimal.Decimal | 普通整數,一般是32位 |
String | str | 變長字串 |
Text | str | 變長字串,對較長或不限長度的字串做了最佳化 |
Unicode | unicode | 變長Unicode字串 |
UnicodeText | unicode | 變長Unicode字串,對較長或不限長度的字串做了最佳化 |
Boolean | bool | 布林值 |
Date | datetime.date | 時間 |
Time | datetime.datetime | 日期和時間 |
LargeBinary | str | 二進位制檔案 |
列選項
選項名 | 說明 |
---|---|
primary_key | 如果為True,代表表的主鍵 |
unique | 如果為True,代表這列不允許出現重複的值 |
index | 如果為True,為這列建立索引,提高查詢效率 |
nullable | 如果為True,允許有空值,如果為False,不允許有空值 |
default | 為這列定義預設值 |
關係選項
選項名 | 說明 |
---|---|
backref | 在關係的另一模型中新增反向引用 |
primary join | 明確指定兩個模型之間使用的聯結條件 |
uselist | 如果為False,不使用列表,而使用標量值 |
order_by | 指定關係中記錄的排序方式 |
secondary | 指定多對多關係中關係表的名字 |
secondary join | 在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件 |
5 構建模型類對映
例用虛擬機器中已有的頭條資料庫,構建模型類對映,以下面三張表為例
CREATE TABLE `user_basic` (
`user_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '使用者ID',
`account` varchar(20) COMMENT '賬號',
`email` varchar(20) COMMENT '郵箱',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '狀態,是否可用,0-不可用,1-可用',
`mobile` char(11) NOT NULL COMMENT '手機號',
`password` varchar(93) NULL COMMENT '密碼',
`user_name` varchar(32) NOT NULL COMMENT '暱稱',
`profile_photo` varchar(128) NULL COMMENT '頭像',
`last_login` datetime NULL COMMENT '最後登入時間',
`is_media` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是自媒體,0-不是,1-是',
`is_verified` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否實名認證,0-不是,1-是',
`introduction` varchar(50) NULL COMMENT '簡介',
`certificate` varchar(30) NULL COMMENT '認證',
`article_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '發文章數',
`following_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '關注的人數',
`fans_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '被關注的人數',
`like_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '累計點贊人數',
`read_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '累計閱讀人數',
PRIMARY KEY (`user_id`),
UNIQUE KEY `mobile` (`mobile`),
UNIQUE KEY `user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者基本資訊表';
CREATE TABLE `user_profile` (
`user_id` bigint(20) unsigned NOT NULL COMMENT '使用者ID',
`gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性別,0-男,1-女',
`birthday` date NULL COMMENT '生日',
`real_name` varchar(32) NULL COMMENT '真實姓名',
`id_number` varchar(20) NULL COMMENT '身份證號',
`id_card_front` varchar(128) NULL COMMENT '身份證正面',
`id_card_back` varchar(128) NULL COMMENT '身份證背面',
`id_card_handheld` varchar(128) NULL COMMENT '手持身份證',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
`register_media_time` datetime NULL COMMENT '註冊自媒體時間',
`area` varchar(20) COMMENT '地區',
`company` varchar(20) COMMENT '公司',
`career` varchar(20) COMMENT '職業',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者資料表';
CREATE TABLE `user_relation` (
`relation_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
`user_id` bigint(20) unsigned NOT NULL COMMENT '使用者ID',
`target_user_id` bigint(20) unsigned NOT NULL COMMENT '目標使用者ID',
`relation` tinyint(1) NOT NULL DEFAULT '0' COMMENT '關係,0-取消,1-關注,2-拉黑',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`relation_id`),
UNIQUE KEY `user_target` (`user_id`, `target_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者關係表';
首先需要建立SQLAlchemy物件:
- 方式一:
db = SQLAlchemy(app)
- 方式二:
db = SQLAlchemy()
db.init_app(app)
注意此方式在單獨執行除錯時,對資料庫操作需要在Flask的應用上下文中進行,即
with app.app_context():
User.query.all()
定義模型類
class User(db.Model):
"""
使用者基本資訊
"""
__tablename__ = 'user_basic'
class STATUS:
ENABLE = 1
DISABLE = 0
id = db.Column('user_id', db.Integer, primary_key=True, doc='使用者ID')
mobile = db.Column(db.String, doc='手機號')
password = db.Column(db.String, doc='密碼')
name = db.Column('user_name', db.String, doc='暱稱')
profile_photo = db.Column(db.String, doc='頭像')
last_login = db.Column(db.DateTime, doc='最後登入時間')
is_media = db.Column(db.Boolean, default=False, doc='是否是自媒體')
is_verified = db.Column(db.Boolean, default=False, doc='是否實名認證')
introduction = db.Column(db.String, doc='簡介')
certificate = db.Column(db.String, doc='認證')
article_count = db.Column(db.Integer, default=0, doc='發帖數')
following_count = db.Column(db.Integer, default=0, doc='關注的人數')
fans_count = db.Column(db.Integer, default=0, doc='被關注的人數(粉絲數)')
like_count = db.Column(db.Integer, default=0, doc='累計點贊人數')
read_count = db.Column(db.Integer, default=0, doc='累計閱讀人數')
account = db.Column(db.String, doc='賬號')
email = db.Column(db.String, doc='郵箱')
status = db.Column(db.Integer, default=1, doc='狀態,是否可用')
class UserProfile(db.Model):
"""
使用者資料表
"""
__tablename__ = 'user_profile'
class GENDER:
MALE = 0
FEMALE = 1
id = db.Column('user_id', db.Integer, primary_key=True, doc='使用者ID')
gender = db.Column(db.Integer, default=0, doc='性別')
birthday = db.Column(db.Date, doc='生日')
real_name = db.Column(db.String, doc='真實姓名')
id_number = db.Column(db.String, doc='身份證號')
id_card_front = db.Column(db.String, doc='身份證正面')
id_card_back = db.Column(db.String, doc='身份證背面')
id_card_handheld = db.Column(db.String, doc='手持身份證')
ctime = db.Column('create_time', db.DateTime, default=datetime.now, doc='建立時間')
utime = db.Column('update_time', db.DateTime, default=datetime.now, onupdate=datetime.now, doc='更新時間')
register_media_time = db.Column(db.DateTime, doc='註冊自媒體時間')
area = db.Column(db.String, doc='地區')
company = db.Column(db.String, doc='公司')
career = db.Column(db.String, doc='職業')
class Relation(db.Model):
"""
使用者關係表
"""
__tablename__ = 'user_relation'
class RELATION:
DELETE = 0
FOLLOW = 1
BLACKLIST = 2
id = db.Column('relation_id', db.Integer, primary_key=True, doc='主鍵ID')
user_id = db.Column(db.Integer, doc='使用者ID')
target_user_id = db.Column(db.Integer, doc='目標使用者ID')
relation = db.Column(db.Integer, doc='關係')
ctime = db.Column('create_time', db.DateTime, default=datetime.now, doc='建立時間')
utime = db.Column('update_time', db.DateTime, default=datetime.now, onupdate=datetime.now, doc='更新時間')