首页 > 解决方案 > SQL 使用另一列上的链接设置默认值

问题描述

我正在尝试使用 PostgreSQL 创建表:

create table words
(
    id                bigint                default nextval('words_sequence') primary key,
    english           varchar(255) not null,
    word_type         varchar(255) not null,
    created           date         not null,
    plus_one_day      date         default (created + interval '1 day'),
    plus_two_days     date         default (created + interval '2 day'),
    plus_five_days    date         default (created + interval '5 day'),
    plus_ten_days     date         default (created + interval '10 day'),
    plus_two_weeks    date         default (created + interval '15 day'),
    plus_four_weeks   date         default (created + interval '30 day'),
    plus_six_weeks    date         default (created + interval '45 day'),
    plus_three_months date         default (created + interval '90 day'),
    plus_six_months   date         default (created + interval '180 day'),
    user_id           bigint       not null,
    deleted           boolean      not null default false
);

我想在另一个上引用几列,但我的方法default (created + interval 'n day')不起作用。如何将列的值与“创建”列连接起来?

PS 我不能使用“now()”方法,因为“created”可以是未来的日期

标签: sqlpostgresql

解决方案


可以使用STORED像 Adrian 提供的那样生成的列。看:

但是根本不要将功能相关的值实现为单独的列。这只是冗余数据,使您的表膨胀,浪费存储和缓存/RAM,并降低整体性能。尤其是当派生值的计算像您的示例中那样简单时。

动态计算这些值通常更简单、更便宜、更安全、更方便。VIRTUAL生成的列可能是一个完美的解决方案。但是那些还没有实现(从 Postgres 13 开始)。

使用VIEW

CREATE TABLE words (
  id        bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY -- ① Postgres 10+
, user_id   bigint  NOT NULL
, created   date    NOT NULL
, deleted   boolean NOT NULL DEFAULT false
, english   text    NOT NULL   -- ② varchar(255) ?
, word_type text    NOT NULL
);

CREATE VIEW words_plus AS
SELECT id, english, word_type, created  -- ③ optionally rearrange columns
     , created + 1 AS plus_one_day      -- ④
     , created + 2 AS plus_two_days
     , created + 5 AS plus_five_days
     -- etc.
     , user_id, deleted  
FROM   words;

① 使用适当的bigserialIDENTITY列。看:

② 在 Postgres中,通常varchar(255)是一种误解。看:

③ 在做的时候,我还重新排列了表格列以节省更多存储空间。看:

当然完全可选。然后,您可以根据需要重新排列视图中的列顺序。

④ 在 Postgres 中,只需添加一个integer到您date的添加天数。更简单,更便宜。有关的:


推荐阅读