Sql 使用“character”作为主键并从另一个表中引用它

Sql 使用“character”作为主键并从另一个表中引用它,sql,database,postgresql,database-design,Sql,Database,Postgresql,Database Design,考虑以下postgres 9.4版数据库: testbase=# select * from employee; id | name ----+---------------------------------- 1 | johnson, jack 2 | jackson, john (2 rows) testbase=# select * from

考虑以下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)
表“employee”中的列“name”的类型为character32且唯一,“worklog”中的列“employee”引用表“employee”中的“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';
为此,我将“employee”更改为“worklog”中的字符32,并将“name”声明为表“employee”中的主键。当然,“worklog”中的“employee”列将引用表“employee”中的“name”

我的问题:

“worklog”中的每一新行是否需要额外的32字节作为“employee”的名称,或者postgres是否会在内部保留一个指向外部字段的指针,而不复制每一新行的名称

我想我的问题的答案在文档中的某个地方,但我找不到它。如果有人能提供相应的链接,那将非常有帮助


PS:我确实发现,但是,没有一些官方文件的链接。行为也可能已经改变,因为线程已经超过七年了。

Postgres将存储您告诉它要存储的数据。有一些新的数据库将在幕后进行压缩——Postgres可能有一些功能,我不知道Postgres的所有功能

但是,你不应该这样做。整数主键比字符串更有效,原因有三:

它们是以字节为单位的固定长度。 它们比较短。 排序规则不是问题。 继续使用原始查询,但使用联接编写查询:

我之所以建议这样做,是因为这更符合SQL的工作方式,并且更容易选择多个员工


如果您想查看姓名而不是id,请创建一个视图,例如v_worklog并添加员工姓名。

姓名可能会随着时间的推移而改变,请告诉一位离婚的女士,家庭虐待受害者,她必须保留她的前夫姓名,因为您的系统不允许更改姓名……无关,但是:角色几乎总是一个错误的选择。如果要存储字符,请使用varchar或text@Blag这不是一个问题,因为这只是一个例子。@a_horse_和_no_name为什么这是一个错误的选择?我认为字符类型的固定长度允许更有效的处理。字符会丢失很多空间。。。您仅将其用于具有固定长度的文本,如product ref;但我和戈登在一起,只是和后面的join谈一谈;
select wl.*
from worklog wl join
     employee e
     on wl.employee = e.id
where e.name = 'johnson, jack';