我把5000本书放在一个表格里,表格里有书名、作者、年份和ISBN。现在我正在做一张书评表。哪一种方法更有效或更好,为图书表中的id创建一列,并使用该id将图书的评论存储在评论表中,还是使用存储为字符(10)的图书ISBN号?
当我说“高效”时,我指的是“保存存储空间”。
发布于 2019-09-26 17:53:23
我想说的是,如果表是精心设计的,那么添加一个人工的smallint
主键在存储空间方面会更便宜。
一个smallint
占用2个字节,而一个包含character(10)
字符的character(10)
(反直觉地说,是一个varlena
)将消耗14个字节。
在表中,额外的2个字节将被浪费,但不要忘记,主键列上将有一个索引。因此,索引值实际上将存储两次:一次在表中,一次在索引中。
为了简单起见,让我们忽略元组头和其他开销。
使用ISBN作为主键的
smallint
主键的因此,添加一个smallint
主键可以节省空间。
您不应该忽略对齐问题。所有数据类型都存储在内存地址中,这些地址是某些二次方的倍数。这是处理器的架构所需要的。smallint
通常有对齐2,character
有对齐1,而timestamp
有对齐8。
因此,如果您的表定义为
CREATE TABLE book (
id smallint PRIMARY KEY,
issue_time timestamp with time zone,
isbn character(10)
);
然后,表数据将如下所示:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | |X|X|X|X|X|X| | | | | | | | | ... (ISBN omitted)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
id padding issue_time
行在8字节的边界上对齐,从id
结束到issue_time
开头的6个字节将为空“填充字节”。
因此,为了充分利用它,您必须考虑定义列的顺序。
--为什么所有这一切在现实中都不是很相关:
一张有5,000或10000条条目的表格,不管是什么,都是很小的。
任何花费在优化空间上的东西充其量都是不必要的微观优化。
但是,计划表上的一个聪明想法可能会很容易事与愿违:如果你想在桌子里存储70000本书,你会发现,即使你允许负的smallint
,也是不够的。当你必须改变主键的数据类型时,当你不得不改变主键的数据类型时,你必须忍受的痛苦,以及所有在一个活动系统中引用它的外键,将远远超过通过聪明的优化节省大约100 KB的乐趣。
发布于 2019-09-26 17:59:03
通常-这要看情况。int类型的操作非常快。应该比任何字符类型都快。在Postgres中,类型"char“是"varchar”,char(10)需要11个字节--整数大于4。另一方面,isbn是强制字段,is可能是可选的-因此没有is的表可以更小。
因此int是比varchar更有效的主键类型。但是在这一天的机器上,你需要做很多可能超过100万行的复杂操作,才能找到任何明显的差异。
https://stackoverflow.com/questions/58122176
复制相似问题