Postgresql 外键的大小(以字节为单位)?

Postgresql 外键的大小(以字节为单位)?,postgresql,Postgresql,我有两个表,其中一个使用外键引用另一个。我需要知道外键的大小,不是主键本身,而是列中的条目。因此,如果我们有两个表: tb1 tb2 tb1\u id以字节为单位有多大?它是32位的整数吗?我在PostgreSQL规范或文档中找不到答案 外键不是神奇的“引用”,而是存储值的常规列。有了外键约束,只需强制相同的值也必须存在于不同的表中 因此,它占用的空间与该列的数据类型所需的空间相同,该列的数据类型应始终与其引用的列相同 由于serial是integer列的快捷方式,因此tb1\u id也应定义为

我有两个表,其中一个使用外键引用另一个。我需要知道外键的大小,不是主键本身,而是列中的条目。因此,如果我们有两个表:

tb1

tb2


tb1\u id
以字节为单位有多大?它是32位的整数吗?我在PostgreSQL规范或文档中找不到答案

外键不是神奇的“引用”,而是存储值的常规列。有了外键约束,只需强制相同的值也必须存在于不同的表中

因此,它占用的空间与该列的数据类型所需的空间相同,该列的数据类型应始终与其引用的列相同

由于
serial
integer
列的快捷方式,因此
tb1\u id
也应定义为
integer
。因此,“tb_id有多大”的答案是:4字节(整数大小)

不过,Postgres并不阻止您使用不同(但“兼容”)的数据类型。理论上,
tb1_id
可以(但不应该!)定义为
bigint
,然后需要8字节的存储空间。但是定义引用其他具有不同数据类型的列的列是一个坏主意,所以不要这样做


外键约束本身不需要相关表中的任何存储空间(它们只需要存储定义所需的系统表中的一些空间)


请注意,引用序列号的列应定义为序列号。If应定义为
整数
(这是
串行
后面的实际数据类型)

如果使用标识列(本质上是“串行”的ANSI SQL标准语法),这一点会更加明显

与标识列一起使用时,第一个表的DDL如下所示:

create table tb1 
(
  id integer primary key generated by default as identity
);
create table tb2 
(
  id integer primary key generated by default as identity, 
  tb1_id integer references tb1
);
第二张表是这样的:

create table tb1 
(
  id integer primary key generated by default as identity
);
create table tb2 
(
  id integer primary key generated by default as identity, 
  tb1_id integer references tb1
);

您会在第二个表中使用默认生成的
tb1\u id整数作为标识吗?可能不是,但这与使用
tb1\u id serial

外键不是神奇的“引用”,而是存储值的常规列。有了外键约束,只需强制相同的值也必须存在于不同的表中

因此,它占用的空间与该列的数据类型所需的空间相同,该列的数据类型应始终与其引用的列相同

由于
serial
integer
列的快捷方式,因此
tb1\u id
也应定义为
integer
。因此,“tb_id有多大”的答案是:4字节(整数大小)

不过,Postgres并不阻止您使用不同(但“兼容”)的数据类型。理论上,
tb1_id
可以(但不应该!)定义为
bigint
,然后需要8字节的存储空间。但是定义引用其他具有不同数据类型的列的列是一个坏主意,所以不要这样做


外键约束本身不需要相关表中的任何存储空间(它们只需要存储定义所需的系统表中的一些空间)


请注意,引用序列号的列应定义为序列号。If应定义为
整数
(这是
串行
后面的实际数据类型)

如果使用标识列(本质上是“串行”的ANSI SQL标准语法),这一点会更加明显

与标识列一起使用时,第一个表的DDL如下所示:

create table tb1 
(
  id integer primary key generated by default as identity
);
create table tb2 
(
  id integer primary key generated by default as identity, 
  tb1_id integer references tb1
);
第二张表是这样的:

create table tb1 
(
  id integer primary key generated by default as identity
);
create table tb2 
(
  id integer primary key generated by default as identity, 
  tb1_id integer references tb1
);

您会在第二个表中使用默认生成的
tb1\u id整数作为标识吗?可能不是,但这与使用
tb1\u id serial

是的原因
tb1\u id
是一个
serial
。但是它是否会占用持久存储数据中的空间?这意味着它将
|tb1 |=4+255
|tb2 |=4+255+4
还是会因为“只是”一个参考而节省一些数据?这就是我想要的。:)如果我错了,请纠正我。我不认为在这种情况下会节省空间。列上的外键约束只是一个引用,但该值本身仍存在于引用列中。@KamilGosciminsk okay damnit:)外键列首先不应是
序列
列,而应是
整数
。无论哪种方式,该值都按正常方式存储,外键部分只是一个额外的检查。没有神奇的节省空间的方法,因为引用需要能够容纳所有可能的整数值,所以它总是至少和一个整数一样宽。@LarsNielsen:我添加了一个更详细的解释,说明了将FK列定义为serialYes of cause
tb1\U id
是一个
序列的问题。但是它是否会占用持久存储数据中的空间?这意味着它将
|tb1 |=4+255
|tb2 |=4+255+4
还是会因为“只是”一个参考而节省一些数据?这就是我想要的。:)如果我错了,请纠正我。我不认为在这种情况下会节省空间。列上的外键约束只是一个引用,但该值本身仍存在于引用列中。@KamilGosciminsk okay damnit:)外键列首先不应是
序列
列,而应是
整数
。无论哪种方式,该值都按正常方式存储,外键部分只是一个额外的检查。没有神奇的空间节省,因为引用需要能够容纳所有可能的inte