SurrealDB是multi-model(多模型)数据库,非AI领域的multi-modal(多模态);它统一支持文档、图、关系、时序、地理空间、键值六种数据模型,通过SurrealQL提供一致查询接口,消除多库架构复杂性。

能直接用,但必须绕开“多模态”这个误导性说法——SurrealDB 是 multi-model(多模型),不是 multi-modal(多模态)。AI 领域的“多模态”指文本、图像、音频等异构数据融合,而 SurrealDB 的“多模型”是指它同时支持文档、图、关系、时序、地理空间、键值六种数据组织方式。混淆这两者会导致设计偏差。
Go SDK 初始化时最容易漏掉的 TLS 和命名空间配置
很多 Go 项目在 app.AddSurrealDB() 后跑不通,不是因为连接地址错,而是没处理好 TLS 和命名空间层级。SurrealDB 的权限和数据隔离强依赖 NAMESPACE 和 DATABASE 两级路径,缺一不可;而 TLSEnabled 若设为 true 却没配证书,会静默失败(不是报错,是连接超时)。
-
TLSEnabled设为true时,必须确保服务端启用了 TLS,且客户端信任其 CA(或跳过验证仅限开发) -
NAMESPACE和DATABASE必须提前在 SurrealDB 中用DEFINE NAMESPACE和DEFINE DATABASE创建好,SDK 不会自动创建 - 环境变量名要严格匹配:
SURREAL_NAMESPACE、SURREAL_DATABASE,不是NAMESPACE或DB_NAME
Query() 调用 SurrealQL 时的参数注入陷阱
Query(ctx, query string, vars map[string]any) 看似简单,但 SurrealQL 的变量绑定不支持 SQL 那种位置占位符(如 $1),只认命名参数($name),且 vars 里 key 名必须和查询中一致——少一个 $ 就返回空结果,也不报错。
- 错误写法:
SELECT * FROM person WHERE id = $1+map[string]any{"id": "tobie"}→ 返回空 - 正确写法:
SELECT * FROM person WHERE id = $id+map[string]any{"id": "tobie"} - 嵌套结构(如 JSON 对象)可直接传入
vars,SurrealQL 会自动展开,不需要手动序列化成字符串
用 Create()/Update() 处理图关系时 ID 格式必须显式指定
SurrealDB 的图能力靠记录 ID 的特殊格式(如 person:tobie)隐式建边,但 Go SDK 的 Create() 默认生成 UUID 风格 ID(person:8a7f...e2),无法参与图遍历。想让一条记录成为图节点,ID 必须按 [table]:[key] 格式构造。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 创建带图语义的记录:调用
Create(ctx, "person", map[string]any{"id": "tobie", "name": "Tobie"})→ ID 是自动生成的 UUID - 正确做法:用
Update()或直接Query()插入,ID 显式写死:CREATE person:tobie SET name = "Tobie" - 图遍历语句如
SELECT->product FROM person:tobie中的person:tobie必须存在且格式合规,否则返回空
行级权限规则在 Go 代码里不能替代,但可以触发
你可以在 Go 里调用 Query() 执行 DEFINE TABLE ... PERMISSIONS 语句来动态建规则,但权限检查完全由 SurrealDB 引擎在查询执行前完成,Go 层无法绕过或模拟。这意味着:业务代码里不该再写 if user.Role != "admin" 这类逻辑,而应把规则定义好,然后放心用 Select() 或 Query() —— 返回结果天然已过滤。
- 权限规则一旦定义,所有通过 WebSocket、HTTP API、Go SDK 的请求都受控,无需额外鉴权中间件
- 调试时可用
INFO FOR SESSION查看当前会话的$auth内容,确认 token 是否被正确解析 - 规则中引用的字段(如
$auth.id)必须与登录时签发的 JWT payload 字段名完全一致
真正麻烦的不是怎么连上,而是怎么让 SurrealQL 的表达能力对齐你的领域模型——比如“用户关注的人发布的最新三条帖子”,在 SurrealQL 里是一条语句,但在 Go 里如果拆成多次 Query() 调用,就失去 multi-model 的意义了。别急着封装 DAO 层,先写透几条核心 SurrealQL。

















