// ❌ 旧思路:枚举所有数据库
type Dialect string
const (
PostgreSQL Dialect = "postgresql"
MySQL Dialect = "mysql"
Oracle Dialect = "oracle"
Qdrant Dialect = "qdrant"
Milvus Dialect = "milvus"
// ... 100+ 个数据库
)
// ❌ 问题:
// 1. 框架需要实现所有数据库的逻辑 → 臃肿
// 2. 新数据库出现 → 必须修改框架 → 不可扩展
// 3. 用户特殊需求 → 无法满足 → 不灵活
// 4. AI 时代新数据库层出不穷 → 跟不上
// ✅ 新思路:接口驱动,用户实现
type Custom interface {
Generate(built *Built) (interface{}, error)
}
// ✅ 优势:
// 1. 框架极简:只提供接口,不实现所有数据库
// 2. 用户自由:5 分钟实现任何数据库
// 3. 持续演进:跟随数据库新特性
// 4. AI 时代:向量数据库、图数据库、时序数据库,都能轻松支持
| 数据库 | 特点 | Custom 实现难度 |
|---|---|---|
| Qdrant | 纯向量搜索 | ✅ 5 分钟(官方支持) |
| Milvus | 企业级 | ✅ 30 分钟 |
| Weaviate | GraphQL | ✅ 30 分钟 |
| Pinecone | 云服务 | ✅ 15 分钟 |
| Chroma | 轻量级 | ✅ 10 分钟 |
| LanceDB | 嵌入式 | ✅ 20 分钟 |
| Vespa | 混合搜索 | ✅ 30 分钟 |
| … | … | ✅ 都能实现! |
如果用 Dialect 枚举:
用 Custom 接口:
| 数据库 | 特殊性 | Custom 价值 |
|---|---|---|
| ClickHouse | FORMAT JSONEachRowALTER TABLE UPDATE |
✅ 必须 Custom |
| Oracle | ROWNUM 分页序列语法 |
✅ 必须 Custom |
| TimescaleDB | 超表(Hypertable) 时间分区 |
✅ 必须 Custom |
| CockroachDB | 分布式事务AS OF SYSTEM TIME |
✅ 必须 Custom |
| DuckDB | 嵌入式分析 特殊聚合 |
✅ 必须 Custom |
| YugabyteDB | 分布式 PostgreSQL | ✅ 可选 Custom |
// ✅ 只需一个方法
type Custom interface {
Generate(built *Built) (interface{}, error)
}
// ❌ 不需要多个方法
type Custom interface {
GetDialect() Dialect // ❌ 类型本身就是标识
ApplyParams(bbs, req) error // ❌ 在 Generate 内部处理
ToJSON(built) (string, error) // ❌ 返回类型不统一
ToSQL(built) (string, []interface{}) // ❌ 两个方法不如一个
}
// ✅ 返回 interface{} 支持任意类型
func (c *QdrantCustom) Generate(built *Built) (interface{}, error) {
return `{"vector": [...]}`, nil // string
}
func (c *OracleCustom) Generate(built *Built) (interface{}, error) {
return &SQLResult{SQL: "...", Args: [...]}, nil // *SQLResult
}
func (c *GraphDBCustom) Generate(built *Built) (interface{}, error) {
return &CypherQuery{Query: "...", Params: {...}}, nil // 自定义类型
}
// ✅ built.JsonOfSelect() 自动处理 string
func (built *Built) JsonOfSelect() (string, error) {
result, _ := built.Custom.Generate(built)
if str, ok := result.(string); ok {
return str, nil // ✅ JSON
}
if sqlResult, ok := result.(*SQLResult); ok {
return "", fmt.Errorf("got SQL, use SqlOfSelect()") // ✅ 类型错误提示
}
}
// ✅ built.SqlOfSelect() 自动处理 *SQLResult
func (built *Built) SqlOfSelect() (string, []interface{}, map[string]string) {
if built.Custom == nil {
return built.defaultSQL() // ✅ 默认实现
}
result, _ := built.Custom.Generate(built)
if sqlResult, ok := result.(*SQLResult); ok {
return sqlResult.SQL, sqlResult.Args, sqlResult.Meta // ✅ SQL
}
}
// ❌ 框架臃肿
xb/
├── postgresql_dialect.go (200 行)
├── mysql_dialect.go (200 行)
├── oracle_dialect.go (300 行)
├── clickhouse_dialect.go (400 行)
├── qdrant_dialect.go (300 行)
├── milvus_dialect.go (300 行)
├── weaviate_dialect.go (300 行)
├── pinecone_dialect.go (200 行)
├── chroma_dialect.go (200 行)
├── lancedb_dialect.go (200 行)
└── ... 100+ 个文件
总代码:30,000+ 行
维护成本:极高
新数据库:必须修改框架
用户自定义:不可能
// ✅ 框架极简
xb/
├── dialect.go (170 行) - Custom 接口定义
├── qdrant_custom.go (77 行) - 官方示例(Qdrant)
└── ... 核心代码
总代码:247 行
维护成本:极低
新数据库:用户 5-30 分钟实现
用户自定义:完全自由
// ✅ 用户项目
your-project/
└── db/
├── milvus_custom.go (150 行) - 用户实现
├── oracle_custom.go (200 行) - 用户实现
├── clickhouse_custom.go (250 行) - 用户实现
└── my_special_db.go (100 行) - 自研数据库!
过去 10 年:
AI 时代(现在):
Custom 接口:
向量数据库的进化:
Dialect 方案:
Custom 方案:
X() 扩展点 → 立即可用场景 1:公司自研向量数据库
// ✅ Custom 接口:5 分钟实现
type InternalVectorDBCustom struct {
Endpoint string
}
func (c *InternalVectorDBCustom) Generate(built *Built) (interface{}, error) {
// 生成公司内部的 JSON 格式
return customJSON, nil
}
场景 2:ClickHouse + Milvus 混合部署
// ✅ 运行时切换
var custom xb.Custom
if useClickHouse {
custom = NewClickHouseCustom()
} else {
custom = NewMilvusCustom()
}
built := xb.Of("data").Custom(custom).Build()
interface{}built.Custom.Generate()JsonOfSelect() → 期望 stringSqlOfSelect() → 期望 *SQLResult// ❌ 运行时判断(慢)
func (built *Built) ToJSON() (string, error) {
switch built.Dialect {
case Qdrant:
return toQdrantJSON(built)
case Milvus:
return toMilvusJSON(built)
case Weaviate:
return toWeaviateJSON(built)
// ... 100+ 个 case
}
}
性能:
// ✅ 编译时绑定(快)
built.Custom.Generate(built)
// ↓ 编译器直接调用
QdrantCustom.Generate(built)
// ↓ 无需判断,直接执行
性能:
type MilvusCustom struct { ... }
type WeaviateCustom struct { ... }
type PineconeCustom struct { ... }
type ChromaCustom struct { ... }
type LanceDBCustom struct { ... }
type Neo4jCustom struct { ... }
func (c *Neo4jCustom) Generate(built *Built) (interface{}, error) {
// 生成 Cypher 查询
cypher := "MATCH (n:User) WHERE n.age > $age RETURN n"
return &CypherQuery{Query: cypher, Params: params}, nil
}
type InfluxDBCustom struct { ... }
func (c *InfluxDBCustom) Generate(built *Built) (interface{}, error) {
// 生成 InfluxQL
influxQL := "SELECT mean(temp) FROM weather WHERE time > now() - 1h"
return influxQL, nil
}
type MongoDBCustom struct { ... }
func (c *MongoDBCustom) Generate(built *Built) (interface{}, error) {
// 生成 MongoDB 查询
mongoQuery := bson.M{"age": bson.M{"$gt": 18}}
return mongoQuery, nil
}
type ElasticsearchCustom struct { ... }
func (c *ElasticsearchCustom) Generate(built *Built) (interface{}, error) {
// 生成 ES DSL
dsl := `{"query": {"match": {"content": "golang"}}}`
return dsl, nil
}
type MyCompanyDBCustom struct { ... }
func (c *MyCompanyDBCustom) Generate(built *Built) (interface{}, error) {
// 公司内部数据库的查询格式
return customFormat, nil
}
而是:
// ✅ 完美对称
type QdrantCustom struct { ... } // 向量数据库
type OracleCustom struct { ... } // SQL 数据库
type Neo4jCustom struct { ... } // 图数据库
// 都实现同一个接口
func (c *Custom) Generate(built *Built) (interface{}, error)
// ✅ 用户实现 Milvus 支持
type MilvusCustom struct {
DefaultNProbe int
}
func (c *MilvusCustom) Generate(built *Built) (interface{}, error) {
json, _ := built.toMilvusJSON()
return json, nil
}
// 完成!只需 10 行代码
// ✅ 用户可以组合多个 Custom
type HybridCustom struct {
VectorDB Custom // Qdrant
SQL Custom // PostgreSQL
}
func (c *HybridCustom) Generate(built *Built) (interface{}, error) {
// 混合查询:先向量,后 SQL
vectorResults, _ := c.VectorDB.Generate(built)
sqlResults, _ := c.SQL.Generate(built)
return merge(vectorResults, sqlResults), nil
}
type MyDBCustom struct {}
func (c *MyDBCustom) Generate(built *Built) (interface{}, error) {
return `{"query": "test"}`, nil // 最简实现
}
type MyDBCustom struct {
DefaultConfig map[string]interface{}
}
func (c *MyDBCustom) Generate(built *Built) (interface{}, error) {
// 1. 提取参数
vectorBb := findVectorSearchBb(built.Conds)
// 2. 构建请求
req := buildRequest(vectorBb, c.DefaultConfig)
// 3. 应用过滤器
applyFilters(built.Conds, req)
// 4. 序列化
json, _ := json.Marshal(req)
return string(json), nil
}
type MyDBCustom struct {
DefaultConfig Config
}
func NewMyDBCustom() *MyDBCustom { ... }
func MyDBHighPrecision() *MyDBCustom { ... }
func MyDBHighSpeed() *MyDBCustom { ... }
func (c *MyDBCustom) Generate(built *Built) (interface{}, error) {
// 完整实现:参数提取、过滤器、错误处理、测试
}
// ❌ 框架包含所有方言
org.hibernate.dialect.PostgreSQLDialect
org.hibernate.dialect.MySQLDialect
org.hibernate.dialect.OracleDialect
// ... 50+ 个内置方言
// ❌ 用户想支持新数据库?
// 1. 继承 Dialect 类
// 2. 实现 100+ 个方法
// 3. 提交 PR 到 Hibernate
// 4. 等半年合并
// ✅ 框架极简
type Custom interface {
Generate(built *Built) (interface{}, error)
}
// ✅ 用户想支持新数据库?
// 1. 定义结构体
type MyDBCustom struct { ... }
// 2. 实现一个方法
func (c *MyDBCustom) Generate(built *Built) (interface{}, error) {
return result, nil
}
// 3. 使用
built.Custom(myCustom).Build()
// 完成!5-30 分钟
不是框架做所有事,而是让用户能轻松做任何事!
这就是 xb v1.1.0 Custom 接口的革命性意义! 🚀✨
版本: v1.1.0
设计者: xb Team
理念: 极简、通用、实用、面向未来