• SQL基础理论篇(三):数据表的创建原则


    简介

    DDL中常用的功能是增删改,分别对应的命令是create、drop和alter。

    执行DDL的时候,不需要commit,就可以完成执行任务。

    下面是MySQL里的一个典型的表创建语句:

    DROP TABLE IF EXISTS `player`;
    CREATE TABLE `player`  (
      `player_id` int(11) NOT NULL AUTO_INCREMENT,
      `team_id` int(11) NOT NULL,
      `player_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
      `height` float(3, 2) NULL DEFAULT 0.00,
      PRIMARY KEY (`player_id`) USING BTREE,
      UNIQUE INDEX `player_name`(`player_name`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意,数据类型里的int(11)表示整数类型,其显示长度为11,所以括号里面的数字11表示的是最大有效显示长度,与类型包含的数值范围大小无关。

    varchar(255)也是一样,显示最大长度是255。

    Decimal(a,b)中,a代表整数部分和小数部分加起来的最大位数,b代表小数位数。如Decimal(8, 2)表示精度为8位(整数加小数位最多为8位),小数位为2位的数据类型。

    排序规则是utf8_general_ci,表示大小写不敏感,如果设置为utf8_bin,表示大小写敏感。

    我们对player_name字段设置了唯一索引。也可以设置普通索引NORMAL INDEX。两者的区别在于,唯一索引对字段添加了唯一性约束。

    在索引方式上,可以选择BTREE或者HASH,这里我们用了BTREE,即USING BTREE

    需要注意,MySQL 在 Linux 的环境下,数据库名、表名、变量名是严格区分大小写的,而字段名是忽略大小写的。而 MySQL 在 Windows 的环境下全部不区分大小写。

    数据表的常见约束

    主要分为主键约束、外键约束和字段约束三大类。

    主键,是用来唯一标识一条记录,其不能重复且不能为空,一个数据表的主键只能有一个,可以是一个字段,也可以是由多个字段复合组成。

    外键,确保了表与表之间引用的完整性。一个表的外键对应另一张表的主键。外键可以是重复的,也可以是空的。

    字段约束:

    • 唯一性约束。表明字段的值在表中是唯一的,主键默认具有唯一性约束和非空约束。
    • NOT NULL约束。字段不应为null;
    • DEFAULT。表明了字段的默认值。如DEFAULT 0.0
    • CHECK约束。检查特定字段取值范围的有效性,check约束的检查结果不能为FALSE,比如我们对身高字段height做check约束,即CHECK(height>=0 and height<3);

    设计数据表的原则

    教程里提出了一个"三少一多"原则(了解下就行,相当于是理想派理论,并不适用于当下):

    • 数据表的个数越少越好

    RDBMS核心在于实体和联系的定义,数据表越少,说明实体和联系设计的越简洁。

    • 数据表中的字段越少越好

    字段数量越多,数据冗余的可能性就越大。保持字段数量少,各个字段间相互独立,而不是某个字段的取值可以由其他字段计算出来。当然这只是个相对概念,我们通常会在数据冗余和检索效率中进行平衡。

    • 数据表中的联合主键的字段个数越少越好

    因为联合主键的字段数量越多,占用的索引空间就越大,还会增加表使用时的理解难度。

    • 使用主键和外键越多越好

    主键和外键越多,说明表之间的关系越多,证明这些实体之间的冗余度越低,利用度越高。在保证了各表独立性的前提下,还提升了相互之间的关联使用率。

    所以这里的"三少一多"原则核心就是简单可复用。

    简单就是用更少的表、更少的字段、更少的联合主键字段来完成数据表的设计。

    可复用是通过主键、外键的使用来增量表之间的复用率。

    当然,以上原则并不是绝对的,在生产场景下,很多时候我们需要牺牲数据的冗余度来换取数据处理的效率,即以空间换时间。

    而且,关于是否使用外键,是很有争议的

    外键本身的存在,是为了保证数据的强一致性,比如说可以配合级联更新,自动更新(删除)关联的记录。

    但其实我们完全可以不用外键,而是在业务层来保证数据的一致性。当然,会增加业务逻辑和数据之间的耦合。

    但是对超大型的数据应用场景来讲,在存在外键的情况下,大量的插入、更新和删除记录,会额外增加过多的开销,尤其是在高并发、水平拆分、分库的情况下。因为每次更新数据,都需要检查另外一张表的数据,也很容易造成死锁。所以大型项目一般会取消外键,来提高效率。

    互联网公司一般推荐尽量少用或不用外键,比如阿里的Java开发规范里也明确指出,“不得使用外键与级联,一切外键概念必须在应用层解决”,以及"外键与级联更新适用于单机低并发,不适合分布式、高并发集群。级联更新是强阻塞,存在数据库更新风暴的风险。外键也会影响数据的插入速度"。

    总结来看,个人的小项目可以上上外键,大型项目还是算了,太过影响数据库的性能。

    评论里有个很有意思,“一般在业务层实现外键约束。学院派才喜欢瞎折腾什么外健,触发器,存储过程,还扯出一大堆好的理由出来。事实上工程的主要复杂度往往来源于变化以及规模。 所以各个子母块之间耦合越小越好。存储中间件就安心的做好自己存储的那一块即可。没有必要一个存储中间件天天操着业务如何处理的心”。感觉说的很有道理。

    参考文献

    1. 04丨使用DDL创建数据库&数据表时需要注意什么?
  • 相关阅读:
    01创建型设计模式——单例模式
    Java前缀和算法
    【重走 java 路】数组
    arm day2(9.15)数据操作指令,跳转指令,特殊功能寄存器指令,+XMind
    hugetlb核心组件
    每日一题9.17打家劫舍2
    3款windows实用软件,免费又良心,真正懂你的需求
    Windows server部署filebeat到kafka
    删除字符串字符,使输出结果不包含回文串
    pcd点云格式介绍
  • 原文地址:https://blog.csdn.net/wlh2220133699/article/details/134453143