首页 > 数据库 >后端程序员必备:15个MySQL表设计的经验准则

后端程序员必备:15个MySQL表设计的经验准则

时间:2024-10-17 21:20:39浏览次数:9  
标签:COMMENT 15 索引 id 程序员 MySQL NULL 主键

15 个 MySQL 表设计的经验准则

在数据库设计中,MySQL 表的设计至关重要。一个良好的表设计可以提高数据库的性能、可维护性和数据的准确性。以下是 15 个 MySQL 表设计的经验准则,希望能为你的数据库设计提供有益的指导。

一、通用字段的设置

在设计表时,尽量包含以下几个通用字段:

  1. id:作为主键,是表中每行数据的唯一标识,必不可少。
  2. create_time:记录数据的创建时间。
  3. modifed_time:用于记录数据的修改时间,每次更新记录时同步更新。
  4. version:数据记录的版本号,通常用于乐观锁,非必需。
  5. modifier:修改人,非必需。
  6. creator:创建人,非必需。

二、字段注释的重要性

  1. 设计表时,每个字段都应添加注释,尤其是涉及枚举字段时,要详细列出每个枚举值,并在后续有变更时及时维护注释内容。
  2. 例如,对于订单表的正确示例如下:
CREATE TABLE order_tab (
    id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单项的唯一标识符,自增主键',
    order_id BIGINT UNIQUE COMMENT '订单的唯一标识符,在整个系统中唯一',
    user_id BIGINT NOT NULL COMMENT '用户的唯一标识符,关联到用户表',
    total_amount DECIMAL(10, 2) NOT NULL COMMENT '订单的总金额,精确到小数点后两位',
    status VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '订单的状态,例如:PENDING(待处理)、COMPLETED(已完成)等',
    payment_status VARCHAR(20) DEFAULT 'not_paid' COMMENT '订单的支付状态,如:not_paid(未支付)、paid(已支付)等',
    version INT DEFAULT 0 COMMENT '乐观锁版本号,用于并发控制',
    created_time DATETIME COMMENT '订单的创建时间',
    updated_time DATETIME COMMENT '订单的最后一次更新时间',
    creator VARCHAR(255) COMMENT '订单的创建者,通常记录创建订单的用户或系统的用户名',
    modifier VARCHAR(255) COMMENT '订单的修改者,通常记录最后修改订单的用户或系统的用户名'
);

三、命名规范

  1. 数据库表名、字段名、索引名等应遵循命名规范,具有高可读性,一般要求使用英文命名,让人一眼就能明白字段的含义。
  2. 表名、字段名必须使用小写字母或者数字,禁止以数字开头,禁止使用拼音,且一般不使用英文缩写。
  3. 主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。

四、选择合适的字段类型

  1. 在设计表时,需根据实际需求选择合适的字段类型:
    • 尽可能选择存储空间小的字段类型,如数字类型可从 tinyint、smallint、int、bigint 依次选择。
    • 对于小数类型如金额,应选择 decimal,避免使用 float 和 double。
    • 若存储的字符串长度几乎相等,可使用 char 定长字符串类型。
    • varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000。
    • 如果存储的值太大,可将字段类型修改为 text,并抽出单独一张表,用主键与之对应。
    • 同一表中,所有 varchar 字段的长度加起来不能大于 65535,若有此需求,可使用 TEXT/LONGTEXT 类型。

五、合理的主键设计

  1. 主键设计应避免与业务逻辑关联。例如,虽然身份证是唯一的,但不建议将其作为主键。
  2. 主键最好是毫无意义的一串独立不重复的数字,如 UUID、自增主键或雪花算法生成的主键等。

六、选择合适的字段长度

  1. 在 MySQL 中,varchar 和 char 类型表示字符长度,其他类型表示的长度都为字节长度。例如,char(10)表示字符长度是 10,而 bigint(4)表示显示长度是 4 个字节,但实际长度为 8 个字节。
  2. 设计表时,要充分考虑字段长度。如用户名字段长度为 5 - 20 个字符,可设置为 username varchar(32),且字段长度一般设置为 2 的幂次方。

七、优先考虑逻辑删除

  1. 物理删除是将数据从硬盘中删除,可释放存储空间;逻辑删除则是给数据添加一个字段(如 is_deleted)来标记数据已被逻辑删除。
  2. 推荐使用逻辑删除而非物理删除的原因如下:
    • 物理删除后恢复数据困难。
    • 会使自增主键不再连续。
    • 核心业务表的数据不适合物理删除,只适合做状态变更。

八、控制表的字段数量

  1. 建表时要牢记,一张表的字段不宜过多,一般尽量不超过 20 个字段。若表的字段过多,可能导致数据量大,查询效率降低。
  2. 若业务需求确实需要很多字段,可以将大表拆成多张小表,它们的主键相同即可。当表的字段数非常多时,可将表分成两张表,一张作为条件查询表,一张作为详细内容表,以提高性能。

九、尽可能使用 NOT NULL 定义字段

  1. 若无特殊理由,建议将字段定义为 NOT NULL。原因如下:
    • 可以防止出现空指针问题。
    • NULL 值存储需要额外空间,且会使比较运算更为复杂,让优化器难以优化 SQL。
    • NULL 值可能导致索引失效。
    • 若将字段默认设置成一个空字符串或常量值不影响应用逻辑,可将该字段设置为 NOT NULL。

十、评估字段是否需要加索引

  1. 首先评估表的数据量,若数据量只有一百几十行,无需加索引。设计表时,有查询条件的字段一般需要建立索引,但索引不能滥用:
    • 索引数量不宜过多,一般单表索引个数不要超过 5 个,过多索引会降低写入速度。
    • 区分度不高的字段(如性别)不能加索引。
    • 要注意避免索引失效的情况,如使用 MySQL 的内置函数会导致索引失效。索引过多时,可以通过联合索引进行优化,同时要遵循覆盖索引、最左匹配原则等。
  2. 例如,对于用户表:
CREATE TABLE user_info_tab (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `user_id` int(11) NOT NULL,
    `age` int(11) DEFAULT NULL,
    `name` varchar(255) NOT NULL,
    `create_time` datetime NOT NULL,
    `modifed_time` datetime NOT NULL,
    PRIMARY KEY (`id`),
    KEY `idx_name` (`name`) USING BTREE,
    UNIQUE KEY un_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

十一、避免使用 MySQL 保留字

  1. 库名、表名、字段名等属性应避免使用 MySQL 保留字,如 select、interval、desc 等。若使用保留字,SQL 语句必须用反引号来引用属性名称,会使 SQL 语句书写和 SHELL 脚本中变量的转义变得复杂。

十二、选择合适的存储引擎

  1. 一般选择 INNODB 存储引擎,除非读写比率小于 1%,才考虑使用 MyISAM。其他存储引擎一般在 DBA 的指导下使用。

十三、选择合适统一的字符集

  1. 数据库库、表、开发程序等应统一字符集,通常中英文环境下使用 utf8。
  2. MySQL 支持的字符集有 utf8、utf8mb4、GBK、latin1 等。其中,utf8 支持中英文混合场景,3 个字节长度;utf8mb4 完全兼容 utf8,4 个字节长度,一般用于存储 emoji 表情;GBK 支持中文,但不支持国际通用字符集,2 个字节长度;latin1 是 MySQL 默认字符集,1 个字节长度。

十四、时间类型的选择

  1. 设计表时通常需要添加通用时间字段,如 create_time、modified_time 等。对于时间类型的选择,MySQL 主要有 date、datetime、time、timestamp 和 year。推荐优先使用 datetime 类型来保存日期和时间,因为其存储范围更大,且与时区无关。

十五、安全性考虑

  1. 数据加密:对于敏感信息,如用户密码,应进行加密存储。对于手机号、邮箱等信息,建议进行脱敏处理。

标签:COMMENT,15,索引,id,程序员,MySQL,NULL,主键
From: https://blog.csdn.net/yuanmomoya/article/details/143028914

相关文章

  • Lnmp(mysql分离)(nginx 1.13.6+mysql5.5+php5.3)环境一键搭建
    Lnmp(mysql分离)(nginx 1.13.6+mysql5.5+php5.3)环境一键搭建如果对运维课程感兴趣,可以在b站上、csdn或微信视频号上搜索我的账号:运维实战课程,可以关注我,学习更多免费的运维实战技术视频在192.168.37.128服务器上:(mysql只到makeinstall即可)nginx默认站点html1.上传lnmp的安装......
  • 比较相同机器上 redis和mysql分别单独承载的 最大连接数量
    在相同的机器上,Redis和MySQL的最大连接数量会受到硬件配置(如CPU、内存、网络等)、配置参数和应用场景的影响。以下是对Redis和MySQL在单机环境下最大连接数的比较:Redis最大连接数量默认配置:Redis默认的最大连接数为10,000。这个值可以通过配置文件中的maxcl......
  • MySql基础:基本查询
    目录1.INSERT(插入)1.1全列插入1.2指定列插入 1.3插入更新  1.4插入替换2.SELECT查询2.1SELECT列2.1.1全列查询2.1.2指定列查询2.1.3查询字段为表达式2.1.4为查询结果指定别名2.1.5查询结果去重 2.2WHERE查询 2.2.1比较运算查询2.2.1.1  >,......
  • CitrixPVS 7.15 PXE模式创建虚拟机-----流向导(精华)
    CitrixPVS7.15PXE模式创建虚拟机-----流向导(精华)在做PXE创建虚机教程之前,我们先做一些貌似与此教程不相关的操作,有句老话说水到渠成或者船到桥头自然直....不管恰当不恰当,先按此教程做吧。我们先在DNS服务器上创建pvs.com的正向查找区域,这个在BDM模式创建虚机那个教程中也能用......
  • 《程序员修炼之道:从小工到专家》读书笔记 01
    编程原则与最佳实践编程原则DRY(Don'tRepeatYourself):避免重复代码。通过抽象和封装来提高代码的复用性,减少维护成本。KISS(KeepItSimple,Stupid):强调简洁性。程序越简单,出错的可能性越小,理解和维护也越容易。YAGNI(YouAren'tGonnaNeedIt):不要过早地为未来的需求设计复......
  • 细说STC15单片机I/O口的四种工作模式
    STC15单片机I/O口有四种模式,分别是准双向口、推挽输出、高阻输入和开漏输出。那么什么是准双向口、推挽输出、高阻输入和开漏输出呢?单片机的这四种模式又是怎么体现出来呢?我们来看看STC15芯片手册上各种模式的说明如下图所示。准双向口:与传统8051的P1、P2和P3口相同模式,灌电流达......
  • mysql慢sql优化思路
    开启慢sql查询配置,或使用云服务厂商的慢sql统计,找到慢sql看下是不是使用了select*,如果是的话,改为查找字段,因为这样可以避免优化器去解析字段,单次查询可能效果不明显,但是一旦并发上来以后,这个就比较明显了,还有就是减少网络IO的消耗看下对应的数据量级,如果连表的话,是不是小表驱......
  • 2024/10/17日 日志 --》关于MySQL中的 约束、多表查询的初步学习笔记与整理
    今天推进了关于约束以及多表查询的内容,下一步是事务以及关于连接数据库JDBC的学习。点击查看代码----约束--1.概念:--·约束是作用于列上的规则用于限制加入表的数据--·约束的存在保证了数据库中数据的正确性、有效性和完整性--2.约束的分类--非空约束NOTNULL:......
  • 一文彻底弄懂mysql的事务日志,undo log 和 redo log
    在数据库事务管理中,UndoLog和RedoLog是两种关键日志,用于保障事务的原子性和持久性。它们的作用是确保数据库在出现崩溃、断电、宕机等故障时,能够进行恢复操作,从而保障数据一致性和完整性。它们通常用于支持事务的ACID特性中的原子性和持久性。下面将分别介绍UndoLo......
  • 【MySQL】[HY000][1366] Incorrect string value: ‘\xE4\xB8\xA4\xE6\x95\xB0.
    问题描述在导入中文数据时遇到错误。[2024-10-1610:49:49][HY000][1366]Incorrectstringvalue:'\xE4\xB8\xA4\xE6\x95\xB0...'forcolumn'title'atrow1尝试将某些数据插入到名为’title’的列时,遇到了不正确的字符串值。原因分析MySQL5.7创建数据库的默......