考虑以下postgres(版本9.4)数据库:
testbase=# select * from employee;
id | name
----+----------------------------------
1 | johnson, jack
2 | jackson, john
(2 rows)
testbase=# select * from worklog;
id | activity | employee | time
----+----------------------------------+----------+----------------------------
1 | department alpha | 1 | 2018-01-27 20:32:16.512677
2 | department beta | 1 | 2018-01-27 20:32:18.112356
5 | break | 1 | 2018-01-27 20:32:22.255563
3 | department gamma | 2 | 2018-01-27 20:32:20.073173
4 | department gamma | 2 | 2018-01-27 20:32:21.05962
(5 rows)
列名称'在表格'员工'属于character(32)
类型且唯一,列'员工'在' worklog'引用' id'来自表'员工'。列' id'是两个表中的主键。
我可以通过发出以下内容来查看某位员工的所有活动:
testbase=# select * from worklog where employee=(select id from employee where name='johnson, jack');
id | activity | employee | time
----+----------------------------------+----------+----------------------------
1 | department alpha | 1 | 2018-01-27 20:32:16.512677
2 | department beta | 1 | 2018-01-27 20:32:18.112356
5 | break | 1 | 2018-01-27 20:32:22.255563
(3 rows)
我宁愿将查询简化为
testbase=# select * from worklog where employee='johnson, jack';
为此,我会改变员工的身份。在' worklog'中输入character(32)
并声明' name'作为表'员工'的主键。专栏'员工'在' worklog'当然,会引用' name'来自表'员工'。
我的问题:
' worklog'中的每一个新行需要额外的32个字节来代表'员工的名字。或者postgres内部只保留指向外部字段的指针而不重复每个新行的名称?
我想我的问题的答案在文档中的某个地方,但我找不到它。如果有人可以提供相应的链接,将会非常有帮助。
PS:我确实找到了this thread,但是没有链接到某些官方文档。行为也可能已经改变,因为该线程已经超过七年了。
答案 0 :(得分:2)
Postgres将存储您告诉它存储的数据。有些新的数据库会在引擎盖下进行压缩 - 而且Postgres可能具有启用它的功能(我不知道Postgres的所有功能)。
但是,你不应该这样做。由于三个原因,整数主键比字符串更有效:
坚持使用原始查询,但使用join
:
select wl.*
from worklog wl join
employee e
on wl.employee = e.id
where e.name = 'johnson, jack';
我建议这样做,因为这与SQL的工作方式更加一致,并且更容易选择多名员工。
如果您想查看姓名而不是ID,请创建一个视图(例如v_worklog
)并添加员工姓名。