database-design.mdc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. ---
  2. description: 数据库设计规范(命名、表/字段/索引、SQL、跨库兼容 MySQL/PG/Oracle/达梦)
  3. globs: "**/*.sql,**/mapper/**/*.xml,**/*.md"
  4. alwaysApply: false
  5. ---
  6. # 数据库设计规范(通用版)
  7. ## 1. 目的
  8. 统一数据库设计标准,提高数据存储效率、可维护性和安全性。本规范适用于 **MySQL、PostgreSQL、Oracle、达梦** 等主流关系型数据库。
  9. ## 2. 适用范围
  10. 所有基于关系型数据库的项目开发与迭代,包括新系统开发及历史系统重构。
  11. ## 3. 命名规范
  12. ### 3.1 标识符通用规则
  13. - **组成**:仅由小写英文字母、数字和下划线(`_`)组成,首字符必须为小写英文字母。
  14. - **唯一性**:同一数据库内表标识符唯一;同一表内字段标识符唯一。
  15. - **对应关系**:标识符应与其中文业务含义简单明了,能直接体现标识内容。
  16. - **语言一致性**:在同一数据库表中,应统一使用英文缩写。
  17. - **大小写规范**:为便于跨数据库迁移,**统一使用小写**。
  18. > **Oracle / 达梦 特别说明**:规范层面统一按小写命名书写;实际建库时不建议为保持小写而强制使用双引号包裹对象名。双引号会导致后续 SQL 必须精确匹配大小写,容易增加 ORM、脚本和运维维护成本。
  19. ### 3.2 标识符的缩写规则
  20. #### 3.2.1 采用英文译名缩写
  21. - 按中文词组对应的英文单词缩写顺序排列。
  22. - 有规范缩写的(如 `id`、`no`、`qty`)直接采用;无规范缩写的,取前1~3个字母,顺序保留辅音字母,首字母为元音时保留该元音。
  23. - 英文单词长度 ≤6 个字母时可直接全拼。
  24. - 同一项目内优先使用英文命名或英文缩写;常用业务词汇应维护统一术语表,避免同一含义出现多种写法。
  25. #### 3.2.2 采用汉语拼音缩写
  26. - 按汉字拼音首辅音顺序排列,元音开头的汉字保留该元音。
  27. - 若产生歧义或重复,可取某些汉字全拼。
  28. - 拼音缩写仅用于无稳定英文译名或行业内已有固定拼音缩写的场景,并应登记到统一术语表。
  29. ### 3.3 表标识符(表名)命名
  30. 表名格式:`{行业代号与业务代码}_{主体标识}_{分类后缀}`,全部小写。
  31. **三段内部禁止下划线**:表名**全局固定为两根下划线**、划分为 **x1、x2、x3** 三段,因此 **x1、x2、x3 各自内部不得再包含 `_`**。若主体含多词语义(如「系统用户」),须在段内用**连续拼写或缩写**合并为一个标识(如 `sysuser`),不得写成 `sys_user`。拆分与索引命名依赖三段边界清晰;混用段内 `_` 将导致主题(x2)无法唯一解析。
  32. | 部分 | 说明 | 示例 |
  33. |------|------|------|
  34. | x1 | **全小写**,固定 **6** 位:`{行业代号 3 位}{业务代码 3 位}`。行业代号:水利 `wrs`、燃气 `gas`、排水 `dns`、供水 `wss`、综合管网/智慧园区 `uut`、公共 `com`、城市安全 `uls`。业务代码为三位小写英文字母,与具体系统一一对应,见下表「各行业系统 x1 对照」。 | `wrswrm` |
  35. | x2 | 主体标识(业务核心名称),**段内无下划线** | `rainfall`、`sysuser` |
  36. | x3 | 分类后缀(基本信息类 `b`、实时信息类 `r`、统计信息类 `s`、交换信息类 `e`、字典信息类 `d`、系统信息类 `x`、公共信息类 `p`、业务信息表 `w`) | `b` |
  37. **各行业系统 x1 对照**(行业 + 系统名称 → x1,均为小写):
  38. | 行业 | 系统名称 | x1 代码 |
  39. |------|----------|---------|
  40. | **供水行业** | 制水成本管理系统 | `wsscsm` |
  41. | | 管网数据采集系统 | `wssdac` |
  42. | | 管网巡检系统 | `wssinp` |
  43. | | 营销收费系统 | `wssbil` |
  44. | | 表务管理系统 | `wssmet` |
  45. | | 掌上办公APP | `wssmob` |
  46. | | 物资管理系统 | `wssmtl` |
  47. | | 数据治理分析系统 | `wssdgv` |
  48. | | 供水监测系统 | `wssmon` |
  49. | | 管网GIS系统 | `wssgis` |
  50. | | 二次供水运行管理系统 | `wsssws` |
  51. | | 数电发票 | `wssinv` |
  52. | | 客服热线系统 | `wsscss` |
  53. | | 水表普查系统 | `wsscen` |
  54. | | 工单管理系统 | `wsswos` |
  55. | | 供水水力模型应用系统 | `wsshyd` |
  56. | | 管网数据管理系统 | `wssdms` |
  57. | | 管网漏损管控系统 | `wsslea` |
  58. | | 电子合同系统 | `wssect` |
  59. | | 报装管理系统 | `wssrqs` |
  60. | | 第三方缴费/微信公众号/微网厅 | `wsspay` |
  61. | | 工程管理系统 | `wssems` |
  62. | | 数字孪生水厂 | `wssdtw` |
  63. | | 设备管理系统 | `wsseqm` |
  64. | | BI可视化展示大屏 | `wssdsh` |
  65. | **排水行业** | 管网数据采集系统 | `dnsdac` |
  66. | | 管网清疏管理系统 | `dnscln` |
  67. | | 污水厂运行管理系统 | `dnswtp` |
  68. | | 掌上办公APP | `dnsmob` |
  69. | | 工单管理系统 | `dnswos` |
  70. | | 排水运行调度系统 | `dnsdsp` |
  71. | | 数据智能分析系统 | `dnsdia` |
  72. | | 管网数据管理系统 | `dnsdms` |
  73. | | 管网监测系统 | `dnsmon` |
  74. | | 泵站运行管理系统 | `dnspsm` |
  75. | | 协同办公系统 | `dnscol` |
  76. | | 工程管理系统 | `dnsems` |
  77. | | 排涝应急指挥系统 | `dnsfec` |
  78. | | 大屏展示系统 | `dnsdsh` |
  79. | | 管网共享应用系统 | `dnsshr` |
  80. | | 管网巡检系统 | `dnsinp` |
  81. | | 排水户管理系统 | `dnsdus` |
  82. | | 设备管理系统 | `dnseqm` |
  83. | | 水力模型综合度应用系统 | `dnshyd` |
  84. | | 数字孪生厂站 | `dnsdts` |
  85. | | 排水检测成果管理系统 | `dnsdrm` |
  86. | | 内涝点监管系统 | `dnswlp` |
  87. | | 物资管理系统 | `dnsmtl` |
  88. | **燃气行业** | 管网数据采集系统 | `gasdac` |
  89. | | 管网GIS系统 | `gasgis` |
  90. | | 管网数据管理系统 | `gasdms` |
  91. | | 管网巡检系统 | `gasinp` |
  92. | | 燃气站场运行管理系统 | `gasstn` |
  93. | | 掌上办公APP | `gasmob` |
  94. | | 物资管理系统 | `gasmtl` |
  95. | | 营销收费系统 | `gasbil` |
  96. | | 表务管理系统 | `gasmet` |
  97. | | 数据智能分析系统 | `gasdia` |
  98. | | 安全监管系统 | `gassaf` |
  99. | | 工单管理系统 | `gaswos` |
  100. | | 数电发票 | `gasinv` |
  101. | | 客服热线系统 | `gascss` |
  102. | | 数字孪生厂站 | `gasdts` |
  103. | | 工程管理系统 | `gasems` |
  104. | | 入户安检系统 | `gashic` |
  105. | | 电子合同系统 | `gasect` |
  106. | | 第三方缴费/微信公众号/微网厅 | `gaspay` |
  107. | | 大屏展示系统 | `gasdsh` |
  108. | | 设备管理系统 | `gaseqm` |
  109. | | 报装管理系统 | `gasrqs` |
  110. | **水利行业** | 河长制管理平台 | `wrsrch` |
  111. | | 水库管家 | `wrsres` |
  112. | | 水电站生态下泄流量系统 | `wrsecf` |
  113. | | 流域水文气象预报系统 | `wrsfhp` |
  114. | | 流域地质灾害监测系统 | `wrsgeo` |
  115. | | 发电运行系统 | `wrsgen` |
  116. | | 水资源管理与调配系统 | `wrswrm` |
  117. | | 设备资产系统 | `wrsast` |
  118. | | 工程安全智能系统 | `wrsesi` |
  119. | | 流域水文气象监测系统 | `wrshmm` |
  120. | | 发电仿真培训系统 | `wrstrn` |
  121. | | 防洪“四预”系统 | `wrsfps` |
  122. | | 流域生态环境监测系统 | `wrseco` |
  123. | | 巡查管护系统 | `wrspat` |
  124. | | 生态监测系统 | `wrsemo` |
  125. | **城市安全行业** | 城市生命安全线监测预警处置平台 | `ulsmew` |
  126. | **智慧园区行业** | 园区(校园)节能一体化管理平台 | `uuteim` |
  127. | **公共支撑平台** | 管网二三维一体化平台 | `comtdp` |
  128. | | 运维管理平台 | `comops` |
  129. | | 空间数据管理平台 | `comsdm` |
  130. | | 统一视频监控平台 | `comvms` |
  131. | | 飞云物联网平台 | `comiot` |
  132. | | 统一工作台 | `comwrk` |
  133. | | 知识库 | `comkbs` |
  134. | | 数据中台 | `comdmp` |
  135. | | 报表平台 | `comrpt` |
  136. 正例:`wrswrm_rainfall_b`(x1=`wrswrm`,x2=`rainfall`,x3=`b`);`comwrk_sysuser_x`(x2=`sysuser`)。
  137. 反例:`comwrk_sys_user_x`(段 `sys_user` 内含 `_`,违规)。
  138. ### 3.4 字段标识符(字段名)命名
  139. #### 3.4.1 基本规则
  140. - **允许字符**:小写字母、数字、下划线,必须以字母开头。
  141. - **长度限制**:不超过 30 个字符(Oracle 限制为 30,其他数据库更长,为统一取 30)。
  142. - **禁止符号**:字段名中禁止使用 `/`、`>` 等特殊字符,需要时在注释中说明。
  143. - **避免保留字**:不使用 `order`、`desc`、`key`、`group` 等 SQL 保留字。
  144. - **避免无意义单词**:`name`、`code`、`type` 等应加业务前缀(如 `user_name`、`product_code`、`data_type`)。
  145. #### 3.4.2 具体字段风格
  146. - 主键统一为 `id`。
  147. - 外键格式:`{关联表主体标识}_id`(如 `rainfall_id`)。
  148. - 布尔字段建议 `is_`、`has_` 前缀(如 `is_active`)。
  149. - 时间字段后缀 `_time`(`create_time`),日期字段后缀 `_date`。
  150. - 审计字段遵循第 4.2 节命名。
  151. ### 3.5 索引命名
  152. 格式:`idx_{表名缩写}_{字段名}` 或 `uk_{表名缩写}_{字段名}`。
  153. **表名缩写**仅取表名 **`{x1}_{x2}_{x3}` 中的 x2(主体标识)**;因 §3.3 要求 x2 段内不含 `_`,索引中的主体缩写与 x2 **完全一致**即可。
  154. **禁止**用完整表名、或 x1+x2+x3 拼接作为缩写(❌ `uk_comwrk_sysuser_x_login_account`)。
  155. 示例:
  156. | 表名 | x2(主体) | 单列索引示例 |
  157. |------|------------|--------------|
  158. | `wrswrm_rainfall_b` | `rainfall` | `idx_rainfall_station_id` |
  159. | `comwrk_sysuser_x` | `sysuser` | `uk_sysuser_login_account` |
  160. - 多字段联合索引:字段名以下划线组合,如 `idx_rainfall_station_id_measure_time`。
  161. ## 4. 表设计规范
  162. ### 4.1 存储引擎与字符集(按数据库区分)
  163. - **MySQL**:引擎 InnoDB,字符集 utf8mb4,排序规则 utf8mb4_unicode_ci。
  164. - **PostgreSQL**:默认存储引擎即可,字符集 UTF8。
  165. - **Oracle** / **达梦**:表空间按项目分配,字符集 AL32UTF8(Oracle)或 UTF-8。
  166. ### 4.2 表必备字段(审计字段)
  167. 审计字段回答的是「这条记录从哪来,最后被谁碰过」。
  168. 每个**具有业务语义的表**必须包含以下字段:
  169. | 字段名 | 通用数据类型建议 | 说明 |
  170. | -------------- | ------------------------------- | ------------------------------------------------------------ |
  171. | `id` | BIGINT | 主键,默认使用数据库自增或全局 ID(具体实现见 6.2 节) |
  172. | `create_time` | TIMESTAMP / DATETIME | 创建时间,自动设为当前时间 |
  173. | `create_user` | VARCHAR(64) | 创建人标识,**NOT NULL**(可用默认值占位,见下文) |
  174. | `create_dept` | VARCHAR(64) | 创建部门标识;**仅当表名分类后缀为业务信息表 `w` 时必填**,用于追溯记录归属组织;其它分类后缀不含该字段时应在表注释中说明 |
  175. | `update_time` | TIMESTAMP / DATETIME | 更新时间,自动更新 |
  176. | `update_user` | VARCHAR(64) | 更新人标识,**NOT NULL** |
  177. | `is_delete` | TINYINT(1) / SMALLINT / NUMBER(1) | 逻辑删除标志:0-未删除,1-已删除,默认 0,**NOT NULL** |
  178. #### 4.2.1 列名与 DDL 约束(强制)
  179. - **列名必须与上表一致**:数据库列使用 **`create_user`、`update_user`、`is_delete`**(蛇形)。禁止使用语义相近的别名建表(❌ `create_by`、`update_by`、`del_flag`、`deleted`、`is_deleted`、`delete_flag`),以免 ORM、全局逻辑删除、SQL 规范(如性能文档中的 `is_delete` 过滤)无法对齐。
  180. - **`create_dept` 处理**:非 `w` 后缀表**不包含**该列;须在 `COMMENT ON TABLE`(或等价注释)中写明「不含 create_dept,分类后缀为 `{x3}`」。
  181. - **NOT NULL 落地**:`create_user`、`update_user` 在数据库层声明 **NOT NULL**;若无自然人上下文的首批数据,可用默认值 `''` 或 `'system'`(须在 COMMENT 中说明约定)。
  182. - **交付前自检**:新建/变更 DDL 后逐项核对 **§4.2 表内字段是否齐全、拼写是否完全一致、`is_delete` 默认值是否为 0**;禁止「业务字段齐全但审计列缺项或使用别名」。
  183. > **例外**:纯粹的多对多关系表(仅关联两个主键,无独立业务语义)可以省略 `create_time`、`create_user`、`update_time`、`update_user`、`is_delete`,但必须**在表注释中明确说明省略理由**,且仍需保留 `id` 主键。
  184. > **主键补充**:如系统存在多项目部署、跨库同步、离线数据导入或后期数据汇聚需求,应优先考虑雪花 ID、号段 ID 等全局唯一 ID,避免单库自增 ID 在数据合并时发生冲突。
  185. ### 4.3 范式与反范式
  186. - 至少满足第三范式(3NF),避免冗余。
  187. - 性能需要时可适度冗余,但需注释说明。
  188. ### 4.4 分表原则
  189. - 单表超过 500 万行或 10GB 时考虑分表(水平/垂直)。
  190. - 分表策略:按时间(月/年)或哈希(如 `user_id % 8`)。
  191. ## 5. 字段设计规范
  192. ### 5.1 数据类型选择(通用指导)
  193. - **整型**:优先使用 `INT`、`BIGINT`,避免 `BIGINT` 滥用。
  194. - **小数**:金额等精确数值使用 `DECIMAL(precision, scale)`,禁止 `FLOAT`/`DOUBLE`。
  195. - **字符串**:变长用 `VARCHAR(n)`,`n` 按需设定(如 `VARCHAR(255)`)。固定长度用 `CHAR`。
  196. - **大文本**:`TEXT` / `CLOB` 应独立成表,避免频繁查询。
  197. - **时间**:统一使用 `TIMESTAMP`(ISO 标准)或 `DATETIME`。不建议使用 `VARCHAR` 存储时间。
  198. > 各数据库具体类型映射参见第 6 节。
  199. ### 5.2 约束规范
  200. - 每个表必须有主键,且为单一 `id` 字段(关系表例外见 4.2)。
  201. - 外键推荐采用**逻辑外键**(应用层维护),避免数据库级联约束影响性能。
  202. - 大部分字段应设为 `NOT NULL` 并给出默认值。
  203. - 业务唯一字段(如手机号、邮箱)必须建立唯一索引。
  204. - 对包含 `is_delete` 的表,唯一约束需明确是否只约束未删除数据。必要时应将 `is_delete` 纳入唯一索引,或使用数据库支持的部分唯一索引。
  205. ### 5.3 默认值与注释
  206. #### 5.3.1 注释(强制)
  207. - **每一列**(含 `id`、审计字段、可空业务字段)均须有数据库侧注释:PostgreSQL 使用 `COMMENT ON COLUMN`,MySQL 使用 `COMMENT '...'`,Oracle/达梦使用 `COMMENT ON COLUMN`,语义一致即可。
  208. - 注释至少包含:**业务含义**;若为枚举/状态码,须列出**取值及含义**(如 `1启用 0禁用`);若有物理单位须写明(参见 §5.4)。
  209. - **表级**须有 `COMMENT ON TABLE`(或等价),说明对象用途;若不含 §4.2 某字段(如非 `w` 表不含 `create_dept`),须在表注释或设计文档中说明。
  210. - **交付自检**:DDL 中不存在「无 COMMENT 的列」;禁止仅依赖应用代码或离线文档代替库内注释。
  211. #### 5.3.2 默认值(强制)
  212. - **状态 / 布尔 / 标志类**字段(如 `status`、`is_delete`、`is_active`):必须有 **DEFAULT**,并与注释中的枚举定义一致(通常 `is_delete` 默认 `0`,状态默认业务约定的「正常」值)。
  213. - **时间戳**:`create_time`/`update_time` 宜 `DEFAULT` 当前时间(或由触发器/应用统一写入),须在注释中说明维护方式。
  214. - **字符串审计字段**若声明 `NOT NULL`:`DEFAULT ''` 或 `'system'` 等须在注释中约定含义。
  215. - **尽量不为业务核心可空列静默省略 DEFAULT**:若刻意不设默认值,须在注释写明「由应用必填写入」及例外原因。
  216. #### 5.3.3 反模式(禁止)
  217. - ❌ 仅对部分列写注释、`id`/时间列不写注释。
  218. - ❌ 状态类字段无 DEFAULT、仅靠应用层记忆。
  219. - ❌ 注释与 DEFAULT 或代码枚举不一致(注释为准,变更须同步 DDL)。
  220. ### 5.4 常用要素计量单位与精度
  221. 除特别说明外,要素的计量单位和精度按下表执行:
  222. | 要素 | 单位(符号) | 精度要求 | 建议数据类型 |
  223. | ------------ | ----------------- | ---------------------------- | --------------------- |
  224. | 高程 | 米(M) | 精确到 0.001 | `DECIMAL(10,3)` |
  225. | 水位 | 米(M) | 精确到 0.001 | `DECIMAL(10,3)` |
  226. | 流量 | 立方米每秒(M³/S)| 保留三位有效数字 | `DECIMAL(8,2)` 或配合应用控制 |
  227. | 压力 | 兆帕(MPA) | 保留三位有效数字 | `DECIMAL(8,2)` |
  228. | 雨量/降水量 | 毫米(MM) | 精确到 0.1 | `DECIMAL(8,1)` |
  229. | 管径 | 毫米(MM) | 整数 | `INT` |
  230. ## 6. 数据库兼容性指南
  231. 本规范在跨数据库使用时,需要注意以下实现差异:
  232. ### 6.1 数据类型映射表
  233. | 通用概念 | MySQL | PostgreSQL | Oracle | 达梦 |
  234. | --------------- | -------------------- | ------------------- | -------------------------- | ------------------------ |
  235. | 自增主键 | `BIGINT AUTO_INCREMENT` | `BIGSERIAL` | `NUMBER(19) GENERATED AS IDENTITY` | `BIGINT IDENTITY` |
  236. | 布尔/删除标志 | `TINYINT(1)` | `SMALLINT` | `NUMBER(1)` (CHECK IN (0,1)) | `NUMBER(1)` |
  237. | 可变长字符串 | `VARCHAR(n)` | `VARCHAR(n)` | `VARCHAR2(n)` | `VARCHAR(n)` |
  238. | 大文本 | `TEXT` | `TEXT` | `CLOB` | `TEXT` 或 `CLOB` |
  239. | 时间戳 | `DATETIME` / `TIMESTAMP` | `TIMESTAMP` | `TIMESTAMP` | `TIMESTAMP` |
  240. | 精确小数 | `DECIMAL(p,s)` | `DECIMAL(p,s)` | `NUMBER(p,s)` | `DECIMAL(p,s)` |
  241. | 整数 | `INT` / `BIGINT` | `INT` / `BIGINT` | `NUMBER(10)` / `NUMBER(19)` | `INT` / `BIGINT` |
  242. ### 6.2 自增主键实现方式
  243. - **MySQL**:`id BIGINT AUTO_INCREMENT PRIMARY KEY`
  244. - **PostgreSQL**:`id BIGSERIAL PRIMARY KEY` 或 `id BIGINT GENERATED ALWAYS AS IDENTITY`
  245. - **Oracle**(12c+):`id NUMBER(19) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY`
  246. - **达梦**:`id BIGINT IDENTITY(1,1) PRIMARY KEY`
  247. - **全局 ID**:如采用雪花 ID、号段 ID 等方式,字段统一为 `BIGINT` / `NUMBER(19)`,由应用层或统一 ID 服务生成。
  248. ### 6.3 注释语法
  249. - **MySQL**:`COMMENT '注释内容'`(表或字段)
  250. - **PostgreSQL**:`COMMENT ON TABLE/COLUMN 名称 IS '注释内容';`
  251. - **Oracle / 达梦**:`COMMENT ON TABLE/COLUMN 名称 IS '注释内容';`
  252. ### 6.4 分页查询
  253. - **MySQL / PostgreSQL**:`LIMIT {limit} OFFSET {offset}`
  254. - **Oracle**:`OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY`(12c+)或使用 `ROWNUM`
  255. - **达梦**:支持 `LIMIT` 和 `OFFSET`,也支持 `ROWNUM`
  256. ### 6.5 自增字段值获取
  257. - **MySQL**:`LAST_INSERT_ID()`
  258. - **PostgreSQL**:`RETURNING id` 或 `currval()`
  259. - **Oracle**:使用 `RETURNING ... INTO` 或查询序列的 `CURRVAL`
  260. - **达梦**:`IDENT_CURRENT('表名')` 或 `@@IDENTITY`
  261. ### 6.6 保留字处理
  262. 各数据库保留字略有不同,建议统一避免使用常见保留字。若必须使用,需用双引号或反引号包裹:
  263. - MySQL:`` `order` ``
  264. - PostgreSQL / Oracle / 达梦:`"order"`
  265. ### 6.7 布尔值查询
  266. - **MySQL**(TINYINT):`WHERE is_delete = 0`
  267. - **PostgreSQL**(SMALLINT):`WHERE is_delete = 0`
  268. - **Oracle**(NUMBER(1)):`WHERE is_delete = 0`
  269. 为统一起见,推荐**应用层传递 0/1**,SQL 中统一使用 `= 0` / `= 1`。
  270. ## 7. 索引设计规范
  271. ### 7.1 基本原则
  272. - 普通业务表建议单表索引数控制在 5 个以内(不含主键);核心查询表、统计表、报表表可结合执行计划和压测结果适当调整。
  273. - 低区分度字段不建索引。
  274. - 排序字段可建索引,注意最左前缀。
  275. ### 7.2 组合索引
  276. - 等值查询字段在前,范围查询字段在后。
  277. - 避免冗余索引。
  278. ### 7.3 索引禁忌
  279. - 不在 `TEXT`/`CLOB` 上直接建索引(需指定前缀长度)。
  280. - 不在长 `VARCHAR(255)` 上建完整索引(使用前缀索引)。
  281. ## 8. SQL 编写规范
  282. ### 8.1 通用写法
  283. - 关键字大写:`SELECT`、`INSERT`、`UPDATE`、`DELETE`、`FROM`、`WHERE`。
  284. - 显式列出字段,禁止 `SELECT *`。
  285. - 使用表别名。
  286. ### 8.2 WHERE 条件优化
  287. - 避免在字段上使用函数或计算。
  288. - 避免 `LIKE '%keyword%'`。
  289. - `IN` 列表不超过 200 个值,否则考虑临时表。
  290. ### 8.3 分页优化
  291. - 大偏移量使用游标或子查询:`WHERE id > last_id ORDER BY id LIMIT 20`。
  292. ### 8.4 事务与锁
  293. - 短事务,避免长时间锁等待。
  294. - 批量操作分片(1000~5000 行/次)。
  295. ## 9. 注释规范
  296. - 表注释:业务用途、数据来源、清理策略、是否省略审计字段。
  297. - 字段注释:业务含义、单位、枚举值说明。需要时可用 `/` 或 `>` 描述路径或或关系。
  298. - 涉及 5.4 节要素的字段,注释中必须标注单位和精度。
  299. ## 10. 安全规范
  300. - 敏感信息(密码、信用卡)必须加密或哈希存储。
  301. - 数据库账户按最小权限原则分配。
  302. - 生产环境禁止物理删除,应使用 `is_delete` 软删除,查询默认过滤 `is_delete=0`。
  303. ## 11. 版本管理与变更
  304. - DDL 脚本纳入 Git 管理,建议采用带时间和说明的命名方式:`V202604291430__create_xxx_table.sql`。
  305. - 变更需通过预发布环境验证。
  306. - 对大表结构变更使用在线工具(如 `pt-online-schema-change`,或各数据库的原生在线 DDL)。
  307. - 已上线的 DDL 脚本禁止直接修改;后续调整必须新增变更脚本。
  308. - 高风险变更(删字段、改类型、重建大索引、批量数据修正)必须提供回滚方案或数据备份方案。
  309. ## 12. 常见反模式与禁止项
  310. | 反模式 | 原因 |
  311. | ------------------------------ | ---------------------------------------- |
  312. | 使用外键级联删除 | 高并发下锁竞争严重 |
  313. | 存储 JSON 并作为查询条件 | 无法有效索引,性能差 |
  314. | 使用 ENUM 类型 | 扩展性差,跨数据库兼容性差 |
  315. | 一列存储多个值(逗号分隔) | 违反第一范式,查询困难 |
  316. | 不使用 `is_delete` 而物理删除 | 数据无法追溯,恢复困难 |
  317. | 跨数据库直接使用特有 SQL 语法 | 可移植性差(如 MySQL 的 `LIMIT` 需适配) |
  318. ## 13. 附录:跨数据库建表示例
  319. ### 13.1 业务表(含审计字段)
  320. **MySQL**:
  321. ```sql
  322. CREATE TABLE `wrswrm_rainfall_b` (
  323. `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  324. `station_id` VARCHAR(32) NOT NULL COMMENT '测站编号',
  325. `rainfall_value` DECIMAL(8,1) NOT NULL DEFAULT 0.0 COMMENT '降雨量(mm),精确到0.1',
  326. `measure_time` DATETIME NOT NULL COMMENT '测量时间',
  327. `data_status` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1-有效 2-可疑 3-无效',
  328. `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  329. `create_user` VARCHAR(64) NOT NULL COMMENT '创建人',
  330. `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  331. `update_user` VARCHAR(64) NOT NULL COMMENT '更新人',
  332. `is_delete` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标志',
  333. PRIMARY KEY (`id`),
  334. UNIQUE KEY `uk_rainfall_station_time` (`station_id`, `measure_time`),
  335. KEY `idx_rainfall_measure_time` (`measure_time`)
  336. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='雨量监测表';
  337. ```
  338. **PostgreSQL**:
  339. ```sql
  340. CREATE TABLE wrswrm_rainfall_b (
  341. id BIGSERIAL PRIMARY KEY,
  342. station_id VARCHAR(32) NOT NULL,
  343. rainfall_value DECIMAL(8,1) NOT NULL DEFAULT 0.0,
  344. measure_time TIMESTAMP NOT NULL,
  345. data_status SMALLINT NOT NULL DEFAULT 1,
  346. create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  347. create_user VARCHAR(64) NOT NULL,
  348. update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  349. update_user VARCHAR(64) NOT NULL,
  350. is_delete SMALLINT NOT NULL DEFAULT 0,
  351. UNIQUE (station_id, measure_time)
  352. );
  353. CREATE INDEX idx_rainfall_measure_time ON wrswrm_rainfall_b (measure_time);
  354. COMMENT ON TABLE wrswrm_rainfall_b IS '雨量监测表';
  355. COMMENT ON COLUMN wrswrm_rainfall_b.rainfall_value IS '降雨量(mm),精确到0.1';
  356. -- 需创建触发器自动更新 update_time,或使用函数
  357. ```
  358. **Oracle**:
  359. ```sql
  360. CREATE TABLE wrswrm_rainfall_b (
  361. id NUMBER(19) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  362. station_id VARCHAR2(32) NOT NULL,
  363. rainfall_value NUMBER(8,1) NOT NULL,
  364. measure_time TIMESTAMP NOT NULL,
  365. data_status NUMBER(1) NOT NULL,
  366. create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
  367. create_user VARCHAR2(64) NOT NULL,
  368. update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
  369. update_user VARCHAR2(64) NOT NULL,
  370. is_delete NUMBER(1) DEFAULT 0 NOT NULL,
  371. CONSTRAINT uk_rainfall_station_time UNIQUE (station_id, measure_time)
  372. );
  373. CREATE INDEX idx_rainfall_measure_time ON wrswrm_rainfall_b (measure_time);
  374. COMMENT ON TABLE wrswrm_rainfall_b IS '雨量监测表';
  375. COMMENT ON COLUMN wrswrm_rainfall_b.rainfall_value IS '降雨量(mm),精确到0.1';
  376. -- 需创建触发器自动更新 update_time
  377. ```
  378. - 达梦:语法与 Oracle 类似,使用 IDENTITY,注释和约束兼容
  379. ### 13.2 多对多关系表(省略审计字段)
  380. ```sql
  381. -- 以 MySQL 为例,其他数据库修改自增语法即可
  382. CREATE TABLE `wrswrm_user_role_rel` (
  383. `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  384. `user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
  385. `role_id` BIGINT UNSIGNED NOT NULL COMMENT '角色ID',
  386. PRIMARY KEY (`id`),
  387. UNIQUE KEY `uk_user_role` (`user_id`, `role_id`)
  388. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户-角色关系表,纯关系表无业务语义,省略审计字段';
  389. ```