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;

注意,数据类型里的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创建数据库&数据表时需要注意什么?

你可能感兴趣的:(#,SQL基础,sql,数据库)