sql - 复合键每组行的序列号

标签 sql postgresql database-design auto-increment

我正在尝试维护一个地址历史表:

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 = 1person_id = 1 的第二行将得到 sequence = 2person_id = 2 的第一行将再次获得 sequence = 1。等等
此外,是否有更好的/内置的方式来维护这样的历史记录?

最佳答案

不要。试过很多次了,很痛苦。

使用普通的 serialIDENTITY专栏:

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打破可能的联系。相关回答:

此外,您要查找的数据类型是 timestamptimestamptz , 不是 datetime 在 Postgres 中:

而你只需要存储previous_address (或更多细节),而不是 address ,也不是 original_address 。在健全的数据模型中,两者都是多余的。

关于sql - 复合键每组行的序列号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24918552/

相关文章:

2 个表之间的 PHP/MySQL 关系

database-design - 是否存在多维数据库模型?

java - JOOQ "IN"查询抛出空指针异常

mysql - #1241 插入到选择中的操作数应包含 1 列

node.js - 指定 SELECT 列时 pg-promise 中未解析的行

sql - 将 1000 个 ID 填充到 SELECT ... WHERE ... IN (...) Postgres 查询中是否合理?

mysql - 存储 1 :1 user relationships in relational database 的最佳方式

sql - 这是在关系数据库中对地址信息建模的好方法吗?

sql - 不同的问题!

sql - 数据库设计 - 可空字段