glmos-code-explain

一、三个模型介绍

1. EAV 模型(Entity-Attribute-Value)

核心:实体-属性-值,三表搞定一切动态字段

结构:

  • entity:商品/用户/订单
  • attribute:字段名(颜色、尺寸、功率…)
  • value:具体值(红、L、200W)

理解: 字段不固定、随时加,用行存代替列存。

2. CPV 模型(Category-Property-Value)

核心:类目绑定属性,属性绑定值,强业务结构化

结构:

  • Category:类目(手机、衣服、家电)
  • Property:该类目下的固定属性(手机=品牌、内存、摄像头)
  • Value:属性值

理解:按类目管属性,电商最常用,比EAV更规整、更业务化。

3. 元数据模型(Metadata Model)

核心:描述“数据的数据”,管表结构、字段、类型、校验、展示

结构: 表元数据、字段元数据、类型、长度、是否必填、枚举、关联关系…

理解:管 schema 的模型,不是存业务数据,是存“表长什么样”。


二、核心区别

维度 EAV CPV 元数据模型
存什么 业务动态数据 类目+属性+业务值 表/字段/规则定义
结构 三行模型 类目驱动属性 配置化Schema
灵活性 极高 中高 极高(管结构)
查询性能 差(多表join) 较好(按类目隔离) 极好(配置读多)
复杂度 低结构、高维护 中等、业务清晰 高抽象、低业务侵入
典型场景 动态表单、自定义字段 电商商品、类目化产品 低代码、表单引擎、数据中台

三、各自适用场景

1. EAV 模型

适合:字段完全不固定、用户自定义、无法提前枚举

场景:

  • CRM 自定义字段
  • 低代码表单
  • 灵活配置类系统
  • 少量数据、查询简单的动态属性

不适合:

  • 大数据量
  • 复杂查询、统计、筛选
  • 电商商品(太乱)

2. CPV 模型

适合:类目固定、属性跟着类目走、电商/供应链/商品中心

场景:

  • 电商商品中心
  • 供应链物料
  • 家电、3C、服饰类目化商品
  • 需要按类目录属性、做筛选、做规格

理解:这是国内最常用、最稳的商品模型)

3. 元数据模型

适合:管结构、管规则、管表单、管数据表定义

场景:

  • 低代码平台
  • 数据中台、数据标准
  • 表单引擎、流程引擎
  • 需要动态建表、动态字段、动态校验

理解:不存业务数据,只存“数据怎么存”


四、对比总结

区别:

  • 元数据模型:管所有表、字段、类型、校验
  • CPV模型:管商品类目+属性+值
  • EAV:只做小范围动态扩展,不做主模型

场景适用

  1. 做电商商品 → CPV
  2. 做自定义表单/动态字段 → EAV
  3. 做低代码/数据中台/表单引擎 → 元数据模型
  4. 既要动态又要结构化 → CPV + 元数据(最主流架构)
  5. 大数据量、强查询 → 不能用EAV

五、数据模型结构示例

1. EAV模型(实体-属性-值)

-- 1. 实体表(存储核心业务对象,如商品、用户、订单)
CREATE TABLE `eav_entity` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '实体ID',
  `entity_type` varchar(50) NOT NULL COMMENT '实体类型(goods/user/order)',
  `entity_name` varchar(100) DEFAULT '' COMMENT '实体名称',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_entity_type` (`entity_type`) COMMENT '按实体类型检索'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='EAV-实体表';

-- 2. 属性表(存储可扩展的字段定义)
CREATE TABLE `eav_attribute` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '属性ID',
  `attribute_code` varchar(50) NOT NULL COMMENT '属性编码(唯一,如color/size/power)',
  `attribute_name` varchar(100) NOT NULL COMMENT '属性名称(颜色/尺寸/功率)',
  `value_type` varchar(20) NOT NULL COMMENT '值类型(string/int/decimal/date)',
  `entity_type` varchar(50) NOT NULL COMMENT '关联实体类型',
  `is_required` tinyint DEFAULT 0 COMMENT '是否必填 0-否 1-是',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_attr_code_entity` (`attribute_code`,`entity_type`) COMMENT '属性编码+实体类型唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='EAV-属性表';

-- 3. 值表(存储实体-属性的具体值)
CREATE TABLE `eav_value` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '值ID',
  `entity_id` bigint NOT NULL COMMENT '关联实体ID',
  `attribute_id` bigint NOT NULL COMMENT '关联属性ID',
  `value_string` varchar(500) DEFAULT '' COMMENT '字符串值',
  `value_int` int DEFAULT NULL COMMENT '整数值',
  `value_decimal` decimal(10,2) DEFAULT NULL COMMENT '浮点值',
  `value_date` date DEFAULT NULL COMMENT '日期值',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_entity_attr` (`entity_id`,`attribute_id`) COMMENT '实体+属性检索'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='EAV-值表';

2. CPV模型(类目-属性-值)

-- 1. 类目表(商品类目,如手机/衣服/家电)
CREATE TABLE `cpv_category` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '类目ID',
  `category_name` varchar(100) NOT NULL COMMENT '类目名称',
  `parent_id` bigint DEFAULT 0 COMMENT '父类目ID(0为顶级)',
  `level` tinyint NOT NULL COMMENT '类目层级(1/2/3)',
  `sort` int DEFAULT 0 COMMENT '排序',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`) COMMENT '父类目检索'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='CPV-类目表';

-- 2. 属性表(类目下的属性,如手机的品牌/内存)
CREATE TABLE `cpv_property` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '属性ID',
  `category_id` bigint NOT NULL COMMENT '关联类目ID',
  `property_code` varchar(50) NOT NULL COMMENT '属性编码(brand/memory)',
  `property_name` varchar(100) NOT NULL COMMENT '属性名称(品牌/内存)',
  `value_type` varchar(20) NOT NULL COMMENT '值类型(string/int/枚举)',
  `is_spec` tinyint DEFAULT 0 COMMENT '是否规格属性 0-否 1-是(如尺寸/颜色)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_prop_code_category` (`property_code`,`category_id`) COMMENT '属性编码+类目唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='CPV-属性表';

-- 3. 属性值表(属性的可选值,如品牌:苹果/华为)
CREATE TABLE `cpv_value` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '值ID',
  `property_id` bigint NOT NULL COMMENT '关联属性ID',
  `value_name` varchar(100) NOT NULL COMMENT '属性值名称(苹果/华为/128G)',
  `sort` int DEFAULT 0 COMMENT '排序',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_property_id` (`property_id`) COMMENT '属性检索'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='CPV-属性值表';

-- 4. 商品-属性值关联表(绑定具体商品的属性值)
CREATE TABLE `cpv_goods_prop_value` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '关联ID',
  `goods_id` bigint NOT NULL COMMENT '商品ID',
  `property_id` bigint NOT NULL COMMENT '属性ID',
  `value_id` bigint NOT NULL COMMENT '属性值ID',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_goods_prop` (`goods_id`,`property_id`) COMMENT '商品+属性唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='CPV-商品属性值关联表';

3. 元数据模型(描述数据的数据)

-- 1. 表元数据(描述数据库表的定义)
CREATE TABLE `metadata_table` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '表元数据ID',
  `table_name` varchar(100) NOT NULL COMMENT '物理表名',
  `table_alias` varchar(100) NOT NULL COMMENT '表别名(如商品表/用户表)',
  `business_module` varchar(50) NOT NULL COMMENT '所属业务模块(商品/订单/用户)',
  `is_active` tinyint DEFAULT 1 COMMENT '是否启用 0-否 1-是',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_table_name` (`table_name`) COMMENT '表名唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='元数据-表定义表';

-- 2. 字段元数据(描述表字段的定义)
CREATE TABLE `metadata_column` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '字段元数据ID',
  `table_id` bigint NOT NULL COMMENT '关联表元数据ID',
  `column_name` varchar(100) NOT NULL COMMENT '物理字段名',
  `column_alias` varchar(100) NOT NULL COMMENT '字段别名(如商品名称/价格)',
  `data_type` varchar(20) NOT NULL COMMENT '数据类型(varchar/int/decimal)',
  `data_length` int DEFAULT NULL COMMENT '字段长度',
  `is_required` tinyint DEFAULT 0 COMMENT '是否必填 0-否 1-是',
  `is_unique` tinyint DEFAULT 0 COMMENT '是否唯一 0-否 1-是',
  `enum_values` json DEFAULT NULL COMMENT '枚举值(如["男","女"])',
  `validate_rule` varchar(200) DEFAULT '' COMMENT '校验规则(如手机号/邮箱正则)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_table_column` (`table_id`,`column_name`) COMMENT '表+字段唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='元数据-字段定义表';

六、架构图

1. EAV模型架构图

erDiagram eav_entity { bigint id PK varchar entity_type varchar entity_name datetime create_time datetime update_time } eav_attribute { bigint id PK varchar attribute_code varchar attribute_name varchar value_type varchar entity_type tinyint is_required datetime create_time } eav_value { bigint id PK bigint entity_id FK bigint attribute_id FK varchar value_string int value_int decimal value_decimal date value_date datetime create_time } eav_entity ||--o{ eav_value : "1对多" eav_attribute ||--o{ eav_value : "1对多"

2. CPV模型架构图

erDiagram cpv_category { bigint id PK varchar category_name bigint parent_id tinyint level int sort datetime create_time } cpv_property { bigint id PK bigint category_id FK varchar property_code varchar property_name varchar value_type tinyint is_spec datetime create_time } cpv_value { bigint id PK bigint property_id FK varchar value_name int sort datetime create_time } cpv_goods_prop_value { bigint id PK bigint goods_id bigint property_id FK bigint value_id FK datetime create_time } cpv_category ||--o{ cpv_property : "1对多" cpv_property ||--o{ cpv_value : "1对多" cpv_property ||--o{ cpv_goods_prop_value : "1对多" cpv_value ||--o{ cpv_goods_prop_value : "1对多"

3. 元数据模型架构图

erDiagram metadata_table { bigint id PK varchar table_name varchar table_alias varchar business_module tinyint is_active datetime create_time } metadata_column { bigint id PK bigint table_id FK varchar column_name varchar column_alias varchar data_type int data_length tinyint is_required tinyint is_unique json enum_values varchar validate_rule datetime create_time } metadata_table ||--o{ metadata_column : "1对多"

4企业落地组合架构图

graph TB A[业务层] --> B[CPV模型核心层] A --> C[EAV模型扩展层] A --> D[元数据配置层] B --> B1[类目管理] B --> B2[属性管理] B --> B3[属性值管理] B --> B4[商品属性绑定] C --> C1[自定义实体] C --> C2[自定义属性] C --> C3[自定义值] D --> D1[表结构配置] D --> D2[字段规则配置] D --> D3[校验规则配置] D --> B[管控CPV结构] D --> C[管控EAV结构]

七、数据模型和架构图总结

  1. 表结构核心:EAV三表(实体/属性/值)侧重动态字段;CPV四表(类目/属性/值/商品绑定)侧重类目化属性;元数据两表(表/字段)侧重结构定义。
  2. 架构核心:EAV是“行存替代列存”,CPV是“类目驱动属性”,元数据是“配置驱动结构”;企业落地通常用元数据管控CPV/EAV,CPV做主模型,EAV做扩展。
  3. 使用关键:电商选CPV,自定义表单选EAV,低代码/数据中台选元数据,三者组合可覆盖90%的动态数据场景。