- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在关注一些关于在 postgresql 中设置时态数据库的信息。首先是问题,然后是技术知识。
问题:当我对 public.countries
表进行一次干净的插入时,为什么我在 temporal.countries
表中得到了双行?我只看到一个插入(在 countries_ins
规则中)。这是功能还是错误?
好的,现在是模式:
DROP SCHEMA IF EXISTS temporal CASCADE;
DROP SCHEMA IF EXISTS history CASCADE;
----------------------------
-- Temporal countries schema
-- vjt@openssl.it
--
create schema temporal; -- schema containing all temporal tables
create schema history; -- schema containing all history tables
-- Current countries data - nothing special
--
create table temporal.countries (
id serial primary key,
name varchar UNIQUE
);
-- Countries historical data.
--
-- Inheritance is used to avoid duplicating the schema from the main table.
-- Please note that columns on the main table cannot be dropped, and other caveats
-- http://www.postgresql.org/docs/9.0/static/ddl-inherit.html#DDL-INHERIT-CAVEATS
--
create table history.countries (
hid serial primary key,
valid_from timestamp not null,
valid_to timestamp not null default '9999-12-31',
recorded_at timestamp not null default now(),
constraint from_before_to check (valid_from < valid_to),
constraint overlapping_times exclude using gist (
box(
point( extract( epoch from valid_from), id ),
point( extract( epoch from valid_to - interval '1 millisecond'), id )
) with &&
)
) inherits ( temporal.countries );
create index timestamps on history.countries using btree ( valid_from, valid_to ) with ( fillfactor = 100 );
create index country_id on history.countries using btree ( id ) with ( fillfactor = 90 );
-- The countries view, what the Rails' application ORM will actually CRUD on, and
-- the core of the temporal updates.
--
-- SELECT - return only current data
--
create view public.countries as select * from only temporal.countries;
-- INSERT - insert data both in the current data table and in the history table
--
create rule countries_ins as on insert to public.countries do instead (
insert into temporal.countries ( name )
values ( new.name )
returning temporal.countries.*;
insert into history.countries ( id, name, valid_from )
values ( currval('temporal.countries_id_seq'), new.name, now() )
);
-- UPDATE - set the last history entry validity to now, save the current data in
-- a new history entry and update the current table with the new data.
--
create rule countries_upd as on update to countries do instead (
update history.countries
set valid_to = now()
where id = old.id and valid_to = '9999-12-31';
insert into history.countries ( id, name, valid_from )
values ( old.id, new.name, now() );
update only temporal.countries
set name = new.name
where id = old.id
);
-- DELETE - save the current data in the history and eventually delete the data
-- from the current table.
--
create rule countries_del as on delete to countries do instead (
update history.countries
set valid_to = now()
where id = old.id and valid_to = '9999-12-31';
delete from only temporal.countries
where temporal.countries.id = old.id
);
-- EOF
当我将它加载到一个空白数据库中并执行一次插入时,会发生以下情况(请查看第 39-40 行以了解令人惊讶的(对我来说)结果)。
1 test=# \i /home/username/temporal.sql
2 psql:/home/sirrobert/temporal.sql:1: NOTICE: drop cascades to 3 other objects
3 DETAIL: drop cascades to table temporal.countries
4 drop cascades to view countries
5 drop cascades to table history.countries
6 DROP SCHEMA
7 DROP SCHEMA
8 CREATE SCHEMA
9 CREATE SCHEMA
10 CREATE TABLE
11 CREATE TABLE
12 CREATE INDEX
13 CREATE INDEX
14 CREATE VIEW
15 CREATE RULE
16 CREATE RULE
17 CREATE RULE
18 test=# SELECT * FROM public.countries;
19 id | name
20 ----+------
21 (0 rows)
22
23 test=# SELECT * FROM temporal.countries;
24 id | name
25 ----+------
26 (0 rows)
27
28 test=# INSERT INTO public.countries (name) VALUES ('USA');
29 INSERT 0 1
30 test=# SELECT * FROM public.countries;
31 id | name
32 ----+------
33 1 | USA
34 (1 row)
35
36 test=# SELECT * FROM temporal.countries;
37 id | name
38 ----+------
39 1 | USA
40 1 | USA
41 (2 rows)
最佳答案
您将数据插入到两个表 temporal.countries
和 history.countries
中,后者继承自前者。这是错误的做法。您应该仅插入具有附加属性的history.countries
。当您随后查询 temporal.countries
时,您会看到一条记录,但没有有效的发件人/发件人信息。
更新记录后,您将获得重复项。您目前的方法无法解决这个问题。但是您实际上并不需要继承。您可以有两个单独的表,然后创建一个 View public.countries
,它从 temporal.countries
返回当前有效的行:
create table temporal.countries (
id serial primary key,
name varchar UNIQUE
);
create table history.countries (
hid serial primary key,
<b>country integer not null references temporal.countries,
name varchar,</b>
valid_from timestamp not null,
valid_to timestamp not null default '9999-12-31',
recorded_at timestamp not null default now(),
constraint from_before_to check (valid_from < valid_to),
constraint overlapping_times exclude using gist (
box(
point( extract( epoch from valid_from), id ),
point( extract( epoch from valid_to - interval '1 millisecond'), id )
) with &&
)
) <strike> inherits ( temporal.countries )</strike>;
现在创建 View 以仅返回当前有效的国家/地区:
create view public.countries as
select c.*
from temporal.countries c
join history.countries h on h.country = c.id
where localtimestamp between h.valid_from and h.valid_to;
还有你的三个规则:
-- INSERT - insert data in temporal.countries <b>and metadata in history.countries</b>
create rule countries_ins as on insert to public.countries do instead (
insert into temporal.countries ( name )
values ( new.name )
returning temporal.countries.*;
insert into history.countries ( <b>country</b>, name, valid_from )
values ( currval('temporal.countries_id_seq'), new.name, now() )
);
-- UPDATE - set the last history entry validity to now, save the current data in
-- a new history entry and update the current table with the new data.
create rule countries_upd as on update to countries do instead (
update history.countries
set valid_to = now()
where id = old.id <strike>and valid_to = '9999-12-31'</strike>; -- view shows only valid data
insert into history.countries ( <b>country</b>, name, valid_from )
values ( old.id, new.name, now() );
update <strike>only</strike> temporal.countries
set name = new.name
where id = old.id
);
-- DELETE - save the current date in the history <strike>and eventually delete the data
-- from the current table.</strike>
create rule countries_del as on delete to countries do instead (
update history.countries
set valid_to = LOCALTIMESTAMP
where id = old.id <strike>and valid_to = '9999-12-31'</strike>;
-- don't delete country data, view won't show it anyway
<strike>delete from only temporal.countries
where temporal.countries.id = old.id</strike>
);
关于sql - 为什么我使用这些 postgresql 时态数据库模式和查询得到重复的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33184166/
我的 postgresql 有问题,我复制了所有文件,然后将其删除。然后,我安装了新的,问题就解决了。现在可以将旧文件和文件导入新文件吗? 最佳答案 如果它们是相同的主要版本(即 9.0 到 9.0.
我想使用 Postgresql 9.2.2 来存储我的应用程序的数据。我不得不构建一个应该基于数据库级别的触发器(当数据库启动时,这个触发器将被触发并执行。),当 postgresql 服务器启动时是
我已经使用下面的查询从 Postgresql 目录表中获取 Sequence 对象的完整信息 select s.sequence_name, s.start_value, s.minimum_valu
Postgres 版本:9.3.4 我需要执行驻留在远程数据库中的函数。该函数根据给定的参数返回一个统计数据表。 我实际上只是在我的本地数据库中镜像该函数,以使用我的数据库角色和授权来锁定对该函数的访
我在 CentOS 7 上,我正在尝试解决“PG::ConnectionBad: FATAL: Peer authentication failed for user”错误。 所以我已经想出我应该更改
我写了一个触发器函数,在触发器表列名上循环,我从具有不同列的不同表调用该函数。该函数将列名插入到数组中并在它们上循环,以便将值插入到另一个模式和表中。 函数和触发器创建脚本: DROP TRIGGER
PostgreSQL 的默认空闲连接超时是多少,我运行了 show idle_in_transaction_session_timeout 查询并返回了 0,但是值 0 表示此选项被禁用,但我想知道默
我需要将十六进制值存储到数据库表中,谁能推荐我需要用于属性的数据类型? 提前致谢 最佳答案 您可以使用bytea 来存储十六进制格式。更多信息 can be found in the postgres
我有一个具有复合主键的(大)表,由 5 列(a、b、c、d、e)组成。 我想高效地选择具有其中两列 (a + e) 的所有行到给定值。 在 PostgreSQL 中,我需要索引吗?或者数据库会使用主键
在阅读 PostreSQL (13) 文档时,我遇到了 this页面,其中列出了不同日期时间类型的存储大小。 除其他外,它指出: Name Storag
我有两个大整数的巨大表(500 000 000 行)。两列都被单独索引。我正在使用语法批量插入此表: INSERT into table (col1, col2) VALUES(x0, y0), (x
有一台 CentOS7 Linux 机器正在运行(不是由我管理;拥有有限的权限)。 请求在其中设置 PostgreSQL。 刚刚从 CentOS 存储库安装了 PostgreSQL: sudo yum
我在 Ubuntu 18.04 上安装了 Postgresql 10,但不知何故坏了,不会重新启动。我可以重新安装它而不破坏它的数据库,以便我可以再次访问数据库吗? pg_dump 不起作用。 最佳答
我想在 UNIX 中使用 crontab 自动备份 PostgreSQL 数据库。我已经尝试过,但它会创建 0 字节备份。 我的 crontab 条目是: 24 * * * * /home/desk
我已经完成了PG服务器的安装。我希望能够使用 pgAdmin 远程连接到它,但不断收到服务器不听错误。 could not connect to server: Connection refused
Oracle 支持波斯历但需要知道 PostgreSQL 是否支持波斯历? 如果是,那么我们如何在 PostgreSQL 中将默认日历类型设置为 Persian 而不是 Gregorian(在 Ora
假设我们有一个带有表的 SQL 数据库 Person以及访问它的几个应用程序。出于某种原因,我们想修改 Person表以向后不兼容的方式。 保持兼容性的一种潜在解决方案是将表重命名为 User并创建一
我使用 PostgreSQL 中的模式来组织我庞大的会计数据库。每年年底,我都会通过为下一年创建一个新模式来进行协调过程。 新模式的文件是否与旧模式物理分离?或者所有模式一起存储在硬盘上? 这对我来说
我正在尝试使用配置文件中的以下配置参数调整 PostgreSQL 服务器: autovacuum_freeze_max_age = 500000000 autovacuum_max_workers =
我的数据包含数据库列中的表情符号,即 message_text ------- 🙂 😀 Hi 😀 我只想查询包含表情符号的数据的行。在 postgres 中是否有一种简单的方法可以做到这一点?
我是一名优秀的程序员,十分优秀!