PostgreSQL存储需要引用

时间:2017-07-14 19:01:03

标签: sql database postgresql

我在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值是存储一次还是三次?

由于

3 个答案:

答案 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(*)树将以这种方式工作。

所以答案至少是三次,并且在用于搜索引用记录的每个索引中都采用累积方式。