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 的环境下全部不区分大小写。
主要分为主键约束、外键约束和字段约束三大类。
主键,是用来唯一标识一条记录,其不能重复且不能为空,一个数据表的主键只能有一个,可以是一个字段,也可以是由多个字段复合组成。
外键,确保了表与表之间引用的完整性。一个表的外键对应另一张表的主键。外键可以是重复的,也可以是空的。
字段约束:
DEFAULT 0.0
;CHECK(height>=0 and height<3)
;教程里提出了一个"三少一多"原则(了解下就行,相当于是理想派理论,并不适用于当下):
RDBMS核心在于实体和联系的定义,数据表越少,说明实体和联系设计的越简洁。
字段数量越多,数据冗余的可能性就越大。保持字段数量少,各个字段间相互独立,而不是某个字段的取值可以由其他字段计算出来。当然这只是个相对概念,我们通常会在数据冗余和检索效率中进行平衡。
因为联合主键的字段数量越多,占用的索引空间就越大,还会增加表使用时的理解难度。
主键和外键越多,说明表之间的关系越多,证明这些实体之间的冗余度越低,利用度越高。在保证了各表独立性的前提下,还提升了相互之间的关联使用率。
所以这里的"三少一多"原则核心就是简单可复用。
简单就是用更少的表、更少的字段、更少的联合主键字段来完成数据表的设计。
可复用是通过主键、外键的使用来增量表之间的复用率。
当然,以上原则并不是绝对的,在生产场景下,很多时候我们需要牺牲数据的冗余度来换取数据处理的效率,即以空间换时间。
而且,关于是否使用外键,是很有争议的。
外键本身的存在,是为了保证数据的强一致性,比如说可以配合级联更新,自动更新(删除)关联的记录。
但其实我们完全可以不用外键,而是在业务层来保证数据的一致性。当然,会增加业务逻辑和数据之间的耦合。
但是对超大型的数据应用场景来讲,在存在外键的情况下,大量的插入、更新和删除记录,会额外增加过多的开销,尤其是在高并发、水平拆分、分库的情况下。因为每次更新数据,都需要检查另外一张表的数据,也很容易造成死锁。所以大型项目一般会取消外键,来提高效率。
互联网公司一般推荐尽量少用或不用外键,比如阿里的Java开发规范里也明确指出,“不得使用外键与级联,一切外键概念必须在应用层解决”,以及"外键与级联更新适用于单机低并发,不适合分布式、高并发集群。级联更新是强阻塞,存在数据库更新风暴的风险。外键也会影响数据的插入速度"。
总结来看,个人的小项目可以上上外键,大型项目还是算了,太过影响数据库的性能。
评论里有个很有意思,“一般在业务层实现外键约束。学院派才喜欢瞎折腾什么外健,触发器,存储过程,还扯出一大堆好的理由出来。事实上工程的主要复杂度往往来源于变化以及规模。 所以各个子母块之间耦合越小越好。存储中间件就安心的做好自己存储的那一块即可。没有必要一个存储中间件天天操着业务如何处理的心”。感觉说的很有道理。