首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有一种在PostgreSQL数据库中高效生成复合密钥的方法?

是否有一种在PostgreSQL数据库中高效生成复合密钥的方法?
EN

Stack Overflow用户
提问于 2022-07-23 15:18:30
回答 2查看 57关注 0票数 -1

假设我有一个以id作为主键的学生表,该表包含所有学生的信息。

代码语言:javascript
运行
复制
id | name
---+------
 1 | aaron
 2 | bob

此外,还有一个表,其中id和tid形成一个复合键,它保存每个测试的分数。

代码语言:javascript
运行
复制
id | tid | score 
---| --- | -----  

注:不同的学生有不同的考试,不同的数字和没有相关性。tid根本不代表一个特定的测试,但是对于一个学生来说,测试序列号。id=1和id=2,如果tid=1的话,并不意味着它是相同的测试。

产生tid的方法有两种,一种是全局唯一的,每插入一条记录就增加1条。

代码语言:javascript
运行
复制
id | tid | score 
-- | --- | -----  
 1 |  1  | 99
 1 |  2  | 98
 2 |  3  | 97
 2 |  4  | 96

另一个在特定id中是唯一的,不同的id可以具有相同的tid值,例如

代码语言:javascript
运行
复制
id | tid | score 
-- | --- | -----  
 1 |  1  | 99
 1 |  2  | 98
 2 |  1  | 97
 2 |  2  | 96  

在以前的方法中,id=2的学生可能会根据他的潮水变化猜出整个学校在中间经历了多少次考试。由于每个学生的年龄在全球范围内都有变化,这是我不想要的。当然,我可以考虑不重复地使用随机数或方案。但是我更喜欢一个更紧凑的增量整数来描述它。

对于后者,是否有更有效和更简单的方法来实现它?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-23 15:30:53

备选案文1。

代码语言:javascript
运行
复制
create table student(id integer PRIMARY KEY, name varchar);
create table test(tid integer PRIMARY KEY, name varchar, test_date date);
create table test_score(sid integer, tid integer references test, score integer, PRIMARY KEY(sid, tid);

更新

备选案文2。

创建一个BEFORE INSERT触发器,该触发器使用的函数大致可以:

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION tid_incr()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
DECLARE 
   max_ct integer;
BEGIN
   SELECT INTO max_ct max(tid) FROM score WHERE id = NEW.id;
   NEW.tid = max_ct + 1;
RETURN NEW;
END;
$function$
票数 0
EN

Stack Overflow用户

发布于 2022-07-23 15:27:07

正确的设计是选项2,因为tid应该(作为外键)引用正在进行的测试(即一系列问题)(无论测试是否针对每个学生定制)。

如果学生可以多次参加相同的测试,则添加日期列(如果同一天可能多次尝试,则添加时间戳),以区分同一测试中重复尝试的结果。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73091887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档