我在SQL布局中大量使用引用,并且想知道这是不是一个坏习惯。当我使用varchar(20)
声明引用时,PostgreSQL是否会将存储使用量加倍,或者仅使用隐藏ID来链接值?
一个例子:
create table if not exists distros(
name varchar(20),
primary key(name)
);
create table if not exists releases(
distro varchar(20) references distros(name),
name varchar(20),
primary key(distro, name)
);
create table if not exists targets(
distro varchar(20) references distros(name),
release varchar(20) references releases(name),
name varchar(20),
primary key (distro, release, name)
);
distro
值是存储一次还是三次?
由于
答案 0 :(得分:1)
我很害怕,你的专栏distro
没有存储一次或三次,但更多。
它位于您的每个表中。但最重要的是,您已将其作为主键的一部分,而这又使其成为您为表格定义的每个索引的一部分。
以这种方式创建表格。它将为您节省大量空间并且速度更快。
create table if not exists distros(
id serial,
name varchar(20),
primary key(id)
);
create table if not exists releases(
id serial,
distro_id int references distros(id),
name varchar(20),
primary key(id)
);
create table if not exists targets(
id serial,
distro_id int references distros(id),
release_id int references releases(id),
name varchar(20),
primary key (id)
);
答案 1 :(得分:0)
重复您的数据。使用外键constraint(a.k.a"引用")只是意味着如果列中没有值,则它不能在引用列中存在。
这tutorial值得一读。
答案 2 :(得分:0)
我不知道Postgres存储布局,但我认为,每条记录应该完全存储在所谓的数据页中,这样在表格扫描的情况下(不使用索引进行搜索)就不需要额外的解除引用。它还包括所有那些引用属性。 此外,它将至少部分地存储在每个索引中,从那里使用某种记录ID找到引用的记录,这取决于您使用的索引技术。正常的B(*)树将以这种方式工作。
所以答案至少是三次,并且在用于搜索引用记录的每个索引中都采用累积方式。