DB/driver 包实现了 Go 标准库 database/sql/driver 接口,让任意基于
database/sql 的工具与 ORM(xorm、sqlx、自研 ORM 等)直接对接 VRTX 引擎,
无需引入任何第三方依赖(解析器为内置的 ORM 子集翻译器)。
import (
"database/sql"
_ "git.ycl.pub/yl32940/TsDB2/DB/driver" // 注册 "vrtx" 驱动
)
db, err := sql.Open("vrtx", "/path/to/data.db") // DSN = 数据库文件路径
if err != nil { ... }
defer db.Close()
db.SetMaxOpenConns(1) // 引擎单写者模型: 1 路连接即可 (见下文"连接与并发")
同一进程内相同路径的多个 sql.DB 共享同一个引擎实例(注册表 + 引用计数),
不会出现一个库被打开成两个实例的撕裂。
完整可运行示例见 demo/sql_driver。
SELECT * FROM t
SELECT 列1, 列2 FROM t -- 投影 (AS 别名可写, 展示以表列名为准)
SELECT ... FROM t WHERE 条件
SELECT ... FROM t WHERE 条件 ORDER BY 列 [ASC|DESC], ... LIMIT n [OFFSET m]
SELECT COUNT(*) | COUNT(列) | SUM(列) | MIN(列) | MAX(列) | AVG(列) FROM t [WHERE ...]
JOIN(INNER / LEFT [OUTER],等值条件,链式多表):
SELECT 列清单 FROM 表1 [AS] a
JOIN 表2 [AS] b ON a.x = b.y -- INNER JOIN 可省 INNER
LEFT JOIN 表3 [AS] c ON b.m = c.n
[WHERE 条件] [ORDER BY ...] [LIMIT n [OFFSET m]]
列清单: * | t.* | 列名 | t.列名 -- WHERE/ORDER BY 同样支持限定名
执行策略:左表全扫描(本表条件下推索引)→ 逐行取 ON 左列值对右表做
Eq 索引点查的嵌套循环;INNER 无匹配丢行、LEFT 补全 NULL;跨表条件
(列比较 / 跨表 OR)作残余谓词在组合行上过滤;投影后内存排序再 LIMIT。
非等值 ON / RIGHT / FULL JOIN 明确报错;JOIN+聚合暂不支持。
WHERE 条件族(? 为参数占位符,字面量同样可用):
| 语法 | 说明 |
|---|---|
= != <> < <= > >= |
比较;NULL 参与比较恒不成立(SQL 语义) |
AND OR NOT |
逻辑组合,支持 ( ... ) 分组 |
列 IN (v1, v2, ...) / NOT IN (...) |
走索引展开定位,不退化全表扫描 |
列 IS NULL / 列 IS NOT NULL |
按行内 NULL 位图判定 |
列 LIKE '前缀%' / NOT LIKE |
通配符 % _ |
INSERT INTO t VALUES (...)
INSERT INTO t (列...) VALUES (...), (...) -- 多行
INSERT INTO t (列...) VALUES (?, ?) -- 参数占位
LastInsertId 返回它);
未提供 → 引擎自增分配。UPDATE t SET 列=值, ... [WHERE 条件]
DELETE FROM t [WHERE 条件]
WHERE 定位到行号后逐行生效,RowsAffected 真实。省略 WHERE = 作用于全表。
CREATE TABLE [IF NOT EXISTS] t (
列 类型 [(参数)] [NULL|NOT NULL] [UNIQUE] [PRIMARY KEY] [DEFAULT NULL] ...,
[PRIMARY KEY (列)],
[KEY|INDEX 名 (列)],
[UNIQUE KEY 名 (列)]
)
CREATE [UNIQUE] INDEX 名 ON t (列)
DROP TABLE [IF EXISTS] t
列类型映射:
| SQL 类型 | 引擎类型 | 备注 |
|---|---|---|
BIGINT (+UNSIGNED) |
Int64 / Uint64 |
主键列必须是整数类型 |
INT/INTEGER SMALLINT TINYINT (+UNSIGNED) |
Int32/16/8 / Uint* |
|
DOUBLE FLOAT |
Float64/32 |
|
BOOL BOOLEAN |
Bool |
|
VARCHAR(n) CHAR(n) |
String(定长档) |
n ≤ 2048;超出请用 TEXT |
TEXT |
动态列 | 不可建索引 |
BLOB |
Blob 列 | 行内 8B 引用,SELECT 出见限制 |
DECIMAL(p,s) |
Decimal |
s 落列级参数 |
DATETIME TIMESTAMP |
Uint64 |
约定:毫秒时间戳 |
UUID |
UUID |
列级 AUTO_INCREMENT / COMMENT '...' 可写(被忽略);DEFAULT 仅支持
DEFAULT NULL,其它默认值报错(避免静默错配)。
| 类别 | 内容 |
|---|---|
| 多表 | 除 INNER/LEFT 等值 JOIN 外的连接形式(RIGHT/FULL JOIN、笛卡尔积) |
| 嵌套 | 子查询、INSERT ... SELECT |
| 分组 | GROUP BY、HAVING、DISTINCT |
| 函数 | WHERE/SELECT 中的任意函数表达式(UPPER/CASE WHEN/COALESCE(SUM(..)) 等) |
| 索引 | 多列(复合)索引、复合主键 PRIMARY KEY (a, b) |
| 变更 | ALTER TABLE 全部 |
| 语法糖 | BETWEEN(用 >= AND <= 代替)、ON DUPLICATE KEY UPDATE、REPLACE INTO |
| DDL 附加 | DEFAULT 非 NULL 值、VIEW/TRIGGER/过程 |
| 其它 | 事务隔离级别设置、` |
NULL 参与任何比较恒不成立;聚合的 AVG 分母
是"该列非 NULL 的行数";COUNT(*) 数全行。字符串结果统一以 []byte 返回
(Scan 到 string / []byte 均可),NULL 扫描为 nil。time.Time 参数按毫秒时间戳存入 DATETIME 列;读出走引擎类型。db.Begin() / tx.Commit() / tx.Rollback(),语义即引擎的
BeginTransaction;BEGIN 会把此前自动提交挂起的修改先落盘(SQL 标准语义:
BEGIN 是"之前工作已提交"的边界)。事务内的 DDL 报错(引擎 DDL 隐式提交语义)。引擎是单写者模型。驱动内所有操作经一把全局锁串行化:同一时刻只有一个
操作在跑,事务期间其它连接的操作排队等待(拥有事务的连接自身不会被卡死)。
因此 SetMaxOpenConns(1) 是最优配置;不设也能正确运行,只是并发请求会排队。
DATETIME 列是引擎的 DateTime 类型
(行内 uint64 毫秒);GORM 把时间值内联成 SQL 字面量传入,驱动会解析
'YYYY-MM-DD HH:MM:SS[.fff]' 形式,零时间(0001-01-01...)按 NULL
写入(软删除 DeletedAt 语义);纯毫秒数值同样接受。DATETIME
且按时间非递减写入即可。仓库提供官方风格的 GORM Dialector:gormvrtx/ 是独立子模块(自带
go.mod,主仓库保持零依赖):
import (
"gorm.io/gorm"
vrtx "git.ycl.pub/yl32940/TsDB2/gormvrtx"
)
db, err := gorm.Open(vrtx.Open("/path/to/data.db"), &gorm.Config{})
Joins()(等值)同样可用。gormvrtx 实现了 GORM 的 Migrator 接口,
schema 自省与变更直连引擎元数据 API(不经 SQL):建表 / 加列 /
删列 / 唯一与普通索引的自动比对与补齐都能跑通(AlterColumn 改类型、
重命名等少数操作返回"不支持")。带索引标签的字符串字段若会落成动态列
(无 size 或 size>2048),建表阶段即给出可操作的中文提示。Save:按 gorm.io/gorm v1.31 开发验证;Save() 在 v1.31
生成 INSERT ... ON CONFLICT upsert 语法,驱动不支持(明确报错),
请用 Select("*").Updates(...) 代替。演示:cd gormvrtx/demo && go run main.go。
go test ./DB/driver/(CRUD/查询全链路、事务、不支持语法、
共享引擎共 4 组)。cd demo/sql_driver && go run main.go —— M1/M2/M3 全特性走查。