概述
在 TDSQL Boundless 中,
CREATE TABLE 不仅定义了数据的逻辑结构(列、索引、约束),还一定程度上影响数据在分布式集群中的存储与分布策略。表类型概览
根据数据量级、访问模式及分布需求,TDSQL Boundless 支持以下三种表类型. 在建表前,请务必根据业务场景选择正确的类型:
表类型 | 简介 | 适用场景 |
单表 | 数据不拆分,全量存储在单个存储节点上。 | 数据量小、写入并发度不高的业务表。 |
分区表 | 数据根据分区键打散,分布在多个存储节点上,实现水平扩展。 | 数据量大、增长快、需要高并发写入(如订单、流水)的业务表。 |
同步表/广播表 | 数据全量复制到所有存储节点以实现本地 Join,并强制所有副本强同步写入的表类型(注:目前同步表必须和广播表一起使用) | 适用于数据量小(如字典/配置)、读多写少、且频繁与大表进行关联查询的场景。 |
命名表与基本语法
创建表的第一步是确定表名。表名是数据库治理的基础,请避免使用无意义的名称,这会给后续的开发与维护带来极大的困扰。
在 TDSQL Boundless 中,推荐遵循以下命名规范:
1. 表名应清晰表达业务含义(如 users, order_details)。
2. 长度适中:建议控制在32个字符以内。
CREATE TABLE 语句通常形式如下:CREATE TABLE <table_name> (<create_definitions>) {table_options};
参数描述
<table_name> :必填。表的唯一标识符。<create_definitions> :必填。包含列定义、主键约束等。{table_options} :选填。常用项为 COMMENT='...', CHARSET=utf8mb4,以及一些可能的自定义语法。列定义与类型规范
列通过严格的数据类型定义,将行数据划分为具有特定业务含义的属性。
列的通用定义语法如下:
<column_name> <data_type> {column_qualification}
参数描述
<column_name>:列的标识符。<data_type>:规定该列可存储的数据类别(如整数、字符、时间等)。{column_qualification}:可选的列级约束(如 NOT NULL、DEFAULT)或生成策略。示例:构建库存明细表
CREATE TABLE `warehouse`.`inventory_items` (`sku_id` bigint NOT NULL,`item_name` varchar(150),`storage_zone` enum('Cold_Chain', 'Dry_Goods', 'Hazardous', 'General'),`entry_time` datetime,`quantity` int,`unit_cost` decimal(18,4),PRIMARY KEY (`sku_id`)) COMMENT='商品库存核心表';
字段参数解析
1. sku_id (bigint)
含义:库存量单位 (SKU) 的唯一编号。
解析:使用
bigint(8字节)而非 int,是为了应对大型仓库可能存在的百亿级商品种类。2. item_name (varchar)
含义:商品名称。
解析:
varchar(150) 是变长字符串。如果商品名只有10个字,它只会占用约10个字节的空间(加上长度前缀),不会像 char 那样强制填充空格,非常适合存储长度不一的文本。3. storage_zone (enum)
含义:存储区域(冷链、干货、危化品、普通区)。
解析:仓库的分区通常是固定的。使用
enum 可以强制数据符合预定义规范,防止出现 "ColdChain" 和 "cold_chain" 这种数据不一致的情况。4. entry_time (datetime)
含义:入库扫描时间。
解析:用于记录商品进入仓库的精确时间点。
5. quantity (int)
含义:当前库存数量。
解析:标准的 4 字节整数。选择类型时需预估最大值,
int 最大支持约21亿,对于单品库存通常绰绰有余。6. unit_cost (decimal)
含义:单件商品的采购成本。
解析:这里定义为
decimal(18,4)。精度18:支持极大的总金额,标度4:保留小数点后4位(如12.5678)。选择主键
主键需要指定若干列,这个由所有主键列组合起来的值是数据行的唯一标识。主键约束要求所有受约束的列仅包含非
NULL 值。一个表可以没有主键,主键也可以是非整数类型。但此时 TDSQL Boundless 就会创建一个 隐式主键 (Hidden Primary Key)。由于 RocksDB 基于 LSM-Tree 结构且数据按主键有序排列,隐式主键通常具有单调递增的特性。在分布式场景下,这会导致所有新写入的数据都落在同一个数据分片上,形成写入热点(Write Hotspot),无法充分利用分布式集群的整体吞吐能力。因此推荐使用业务生成的随机唯一 ID 作为主键。
选择主键的建议
1. 尽量选择“区分度高”的业务列作为主键:优先使用具有业务含义且值分布均匀的列(如用户 ID、订单号)作为主键。
2. 严格控制表宽度与行大小:出于性能考虑,尽量避免存储超宽表。表字段数不建议超过60个,建议单行的总数据大小不要超过64K。
3. 尽量使用简单、标准的类型(如
INT, BIGINT, DECIMAL, VARCHAR),减少解析开销,提升存储效率。指定列约束
除主键约束外,TDSQL Boundless 支持标准的 SQL 列约束,如:非空约束
NOT NULL、唯一约束 UNIQUE KEY、默认值 DEFAULT 等。1. 填充默认值 (DEFAULT)
如需在列上设置默认值,请使用
DEFAULT 约束。这样在插入数据时无需指定每一列的值,数据库会自动填充。最常见的场景是:在商品入库时,自动记录入库时间。
示例 SQL:
CREATE TABLE `warehouse`.`inventory_items` (`sku_id` bigint NOT NULL,`item_name` varchar(150),`storage_zone` enum('Cold_Chain', 'Dry_Goods', 'Hazardous', 'General'),-- 使用 DEFAULT CURRENT_TIMESTAMP 自动填入当前时间`entry_time` datetime DEFAULT CURRENT_TIMESTAMP,`quantity` int,`unit_cost` decimal(18,4),PRIMARY KEY (`sku_id`)) COMMENT='商品库存核心表';
2. 防止重复 (UNIQUE)
如果您需要防止列中出现重复值,可以使用
UNIQUE 约束。例如,虽然
sku_id 是主键,但您可能还要求 商品名称 (item_name) 在整个仓库中也不能重复,可以这样改写:CREATE TABLE `warehouse`.`inventory_items` (`sku_id` bigint NOT NULL,-- 添加 UNIQUE 约束,如果插入相同的商品名称会报错`item_name` varchar(150) UNIQUE,`storage_zone` enum('Cold_Chain', 'Dry_Goods', 'Hazardous', 'General'),`entry_time` datetime,`quantity` int,`unit_cost` decimal(18,4),PRIMARY KEY (`sku_id`)) COMMENT='商品库存核心表';
3. 防止空值 (NOT NULL)
如果您需要防止列中出现空值,可以使用
NOT NULL 约束。例如,商品名称不仅要唯一,而且必须填写(不能为空),同时库存数量
quantity 也不能为 NULL(可以默认为0),可以这样改写:CREATE TABLE `warehouse`.`inventory_items` (`sku_id` bigint NOT NULL,-- 既不能重复,也不能为空`item_name` varchar(150) UNIQUE NOT NULL,`storage_zone` enum('Cold_Chain', 'Dry_Goods', 'Hazardous', 'General'),`entry_time` datetime DEFAULT CURRENT_TIMESTAMP,-- 不能为 NULL,且默认值为 0`quantity` int NOT NULL DEFAULT 0,`unit_cost` decimal(18,4),PRIMARY KEY (`sku_id`)) COMMENT='商品库存核心表';
常见问题 (FAQ)
Q: 我创建了单表,以后数据量变大了怎么办?
A: TDSQL Boundless 支持平滑演进。如果单表数据量增长超过预期,您可以使用
ALTER TABLE ... PARTITION BY ... 语句将其在线转换为分区表,数据会自动重分布到集群的其他节点,无需停机迁移。Q: 单表支持分布式事务吗?
A: 支持。单表可以参与到跨节点的分布式事务中(例如:一个事务同时修改单表 A 和分区表 B),TDSQL Boundless 会自动保证全局一致性。
Q: 为什么不建议所有表都建成单表?
A: 单表的数据和计算压力集中在单个存储节点上。如果核心高频业务使用单表,该节点极易成为整个集群的性能瓶颈(热点),且无法利用多节点的并行计算能力。