Rust in Everything
基于 sqlx 0.9.0

设计取舍

前六部分按代码讲机制,每一章都顺带碰到一些「这样做换来了什么、付出了什么」。这一部分只有一页,把它们收到一起:每一条取舍先说收益,再说代价,代价都配着一个在本卷某一页上跑出来的现象,链接指向那一页,这里不重讲机制。

  1. 设计取舍:十条取舍。写 SQL 不写 DSL,动态 SQL 只能靠 QueryBuilder 或数组参数;编译期连库检查真实 schema,可空性推断是启发式的;纯 Rust 协议真异步、没有 unsafe,代价是协议细节的 bug 要自己修(RUSTSEC-2024-0363、取消安全)、没有 CancelRequest;默认预备语句加按连接 LRU 缓存,省一个来回,换来 cached plan 和服务端常驻语句;一条连接一次一个查询,并发全靠池;关联类型零开销,泛型签名长、运行时选库只剩 Any 的十种值;Drop 里不能 await,归还和回滚都只能排队;连接池把连不上库当作暂时故障重试,最后只剩 PoolTimedOut;SqlSafeStr 是一道能被搜到的减速带;迁移用 advisory lock 和校验和,出错时锁留在连接上。
flowchart TB
  sql["写 SQL"] --> chk["编译期连库检查"]
  sql --> prep["默认预备语句"]
  prep --> cache["按连接缓存"]
  proto["纯 Rust 协议"] --> async["全程异步"]
  async --> dropq["Drop 里只能排队"]
  conn["一条连接一个查询"] --> pool["并发靠池"]
  pool --> dropq
  assoc["关联类型"] --> mono["单态化"]
  safe["SqlSafeStr"] --> sql

💬 关联讨论

发起讨论
加载中...