最近正进行达梦数据库的SQL审核工作研究,和Oracle相比,还是有些细节上的差异,从设计角度,也给了我们一些新的思路,不同的数据库,设计实现的路径,各有各的特长,有些经验值得我们做系统设计借鉴。
以”外键”这个关系型数据库的一个对象为引子,众所周知,外键是从数据库的角度保证主子表关联正确的一种设计,在Oracle中,创建外键不会自动创建索引,这个有什么影响?
根据经验来讲,除非主子表存在以下情况,否则外键字段应该创建索引,避免锁表,以及提升关联查询的效率,
(a) 不会删除主表的记录;
(b) 不会更新主表的主键;
(c) 子表不用外键字段做查询。
因此,某些场景下,如果外键无索引,还是会产生一些隐患的,此时的解决方案,需要在应用端实现外键约束,或者添加外键的索引,避免产生锁表等的现象。
但是达梦数据库,如果创建外键,则会自动创建一个索引,示例如下,创建主表t01,子表t02,
CREATE TABLE t01(id int PRIMARY key, a varchar(1));
CREATE TABLE t02(id int PRIMARY key, id_t01 int, a varchar(1));
子表t02的id_t01字段,关联到主表t01的主键id字段,
ALTER TABLE t02 ADD CONSTRAINT fk_t02_t01 FOREIGN KEY (id_t01) REFERENCES t01(id);
可以看到t02共有三个索引,
其中,INDEX33555494是t02表的聚集索引,达梦中的表默认都是索引组织表,INDEX_TYPE是CLUSTER,INDEX33555495是主键索引,INDEX33555496是自动创建的外键索引,INDEX_TYPE是VIRTUAL。
从表的定义可以证明以上信息,
CREATE TABLE TEST."t02" (
"id" INT NOT NULL,
"id_t01" INT,
"a" VARCHAR(1),
CONSTRAINT CONS134218805 PRIMARY KEY ("id"),
CONSTRAINT "fk_t02_t01" FOREIGN KEY ("id_t01") REFERENCES TEST."t01"("id")
);
CREATE UNIQUE INDEX INDEX33555495 ON TEST."t02" ("id");
CREATE INDEX INDEX33555496 ON TEST."t02" ("id_t01");
因此,在达梦数据库中通过自动给外键创建了索引,避免了缺少索引可能带来的隐患,但是为什么Oracle不这么做?我猜一种可能,从精细的角度,外键是否需要索引存在场景限定,不是说所有场景都会有问,因此Oracle将这个判断交给了用户,毕竟索引会占用空间,可能影响数据增删改的性能,这就是时间和空间的平衡。
声明:来自bisal的个人杂货铺,仅代表创作者观点。链接:https://eyangzhen.com/3351.html