后端主流数据库分析
一、关系型数据库(RDBMS)
1. MySQL:金融支付系统核心
行业场景:
- 金融支付:银行交易流水、支付订单(ACID事务保障)。
- 电商平台:商品库存管理、订单状态跟踪(高并发OLTP)。
- SaaS服务:多租户用户管理(分库分表隔离数据)。
Python实战代码:
# 金融交易事务操作(原子性保障)
import pymysql
from contextlib import contextmanager
@contextmanager
def mysql_transaction():
conn = pymysql.connect(host='localhost', user='root', password='******', db='******')
try:
with conn.cursor() as cursor:
yield cursor
conn.commit() # 事务提交
except Exception as e:
conn.rollback() # 事务回滚
raise e
finally:
conn.close()
# 使用示例:转账操作
def transfer_money(from_account, to_account, amount):
with mysql_transaction() as cursor:
# 扣除转出账户
cursor.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", (amount, from_account))
# 增加转入账户
cursor.execute("UPDATE accounts SET balance = balance + %s WHERE id = %s", (amount, to_account))
# 记录交易流水
cursor.execute("INSERT INTO transactions (from_id, to_id, amount) VALUES (%s, %s, %s)",
(from_account, to_account, amount))
# 调用:从账户1转100元到账户2
transfer_money(1, 2, 100)
性能技巧:
- 使用连接池(如
DBUtils.PooledDB
)避免频繁创建连接 - 对
account_id
和transaction_time
字段建立联合索引加速查询
性能优化:
- 索引设计:避免全表扫描,对高频查询字段(如user_id)建B+树索引。
- 读写分离:用ProxySQL或MaxScale分离读写流量,主库写,从库读。
灾难恢复:
- 每日全量备份 + Binlog 增量备份,通过 mysqldump 或 Percona XtraBackup 实现。
- 快速恢复:mysqlbinlog 重放 Binlog 到指定时间点。
2. PostgreSQL:地理信息分析系统
行业场景:
- 地理信息(GIS):物流路径规划(PostGIS扩展支持空间数据)。
- 科研计算:基因序列分析(数组类型和PL/Python扩展)。
- 金融风控:复杂SQL分析(窗口函数计算用户行为聚合)。
Python实战代码:
# 使用PostGIS计算两个坐标距离
import psycopg2
from geoalchemy2 import WKTElement
from sqlalchemy import create_engine
# 创建空间数据表
engine = create_engine('postgresql+psycopg2://user:pass@localhost/gis_db')
with engine.connect() as conn:
conn.execute("""
CREATE TABLE IF NOT EXISTS warehouses (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
location GEOGRAPHY(Point)
)
""")
# 插入坐标点(北京首都机场)
point = WKTElement('POINT(*.*.*.*)', srid=4326)
insert_sql = "INSERT INTO warehouses (name, location) VALUES (%s, %s)"
with engine.connect() as conn:
conn.execute(insert_sql, ('Beijing Airport', point))
# 查询距离某点50公里内的仓库
query = """
SELECT name, ST_Distance(location, ST_GeogFromText('POINT(*.*.*.*)')) as distance
FROM warehouses
WHERE ST_DWithin(location, ST_GeogFromText('POINT(*.*.*.*)'), 50000)
"""
result = engine.execute(query)
for row in result:
print(f"{
row.name} 距离天安门 {
row.distance:.2f