我正在尝试维护一个地址历史表:
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
);
我想知道是否有一种简单的方法可以自动编号/约束 address_history
中的 sequence
以自动从 1 开始为每个 person_id
计数。
换句话说,person_id = 1
的第一行将得到 sequence = 1
; person_id = 1
的第二行将得到 sequence = 2
。 person_id = 2
的第一行将再次获得 sequence = 1
。等等
此外,是否有更好的/内置的方式来维护这样的历史记录?
最佳答案
不要。试过很多次了,很痛苦。
使用普通的 serial
或 IDENTITY
专栏:
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
original_address
罢工>。在健全的数据模型中,两者都是多余的。
关于sql - 复合键每组行的序列号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24918552/