我正在尝试维护地址历史记录表:
CREATE TABLE address_history (
person_id int,
sequence int,
timestamp datetime default current_timestamp,
address text,
original_address text,
previous_address text,
PRIMARY KEY(person_id, sequence),
FOREIGN KEY(person_id) REFERENCES people.id
);
我想知道是否有一种简单的方法可以自动编号/约束sequence
address_history
,以便自动从每个person_id
的1开始计数。
换句话说,person_id = 1
的第一行将获得sequence = 1
; person_id = 1
的第二行将获得sequence = 2
。 person_id = 2
的第一行会再次获得sequence = 1
。等
另外,有更好的/内置的方式来维护这样的历史记录吗?
答案 0 :(得分:15)
别。它经过多次尝试,很痛苦。
使用普通serial
列:
CREATE TABLE address_history (
address_history_id serial PRIMARY KEY
,person_id int NOT NULL REFERENCES people(id)
,created_at timestamp NOT NULL DEFAULT current_timestamp
,previous_address text
);
使用窗口函数row_number()
获取序列号,每个person_id
没有间隙。您可以保留一个VIEW
,您可以将其用作查询中表格的替代品,以准备好这些数字:
CREATE VIEW address_history_nr AS
SELECT *, row_number() OVER (PARTITION BY person_id
ORDER BY address_history_id) AS adr_nr
FROM address_history;
或者您可能想要ORDER BY
其他内容。也许created_at
?更好created_at, address_history_id
打破可能的联系。相关回答:
此外,您要查找的数据类型为timestamp
或timestamptz
,而不是Postgres中的 :datetime
您只需要存储previous_address
(或更多详细信息),而不是 ,也不需要address
。在理智的db布局中,两者都是多余的。original_address