简单的例子:有一张客户表。
create table Customers (
id integer,
constraint CustomersPK primary key (id)
)
Run Code Online (Sandbox Code Playgroud)
数据库中的所有其他数据都应该链接到 a Customer
,例如Orders
看起来像这样:
create table Orders (
id integer,
customer integer,
constraint OrdersPK primary key (customer, id),
constraint OrdersFKCustomers foreign key (customer) references Customers (id)
)
Run Code Online (Sandbox Code Playgroud)
假设现在有一个表链接到Orders
:
create table Items (
id integer,
customer integer,
order integer,
constraint ItemsPK primary key (customer, id),
constraint ItemsFKOrders foreign key (customer, order) references Orders (customer, id)
)
Run Code Online (Sandbox Code Playgroud)
我应该从Items
to添加一个单独的外键Customers
吗?
...
constraint ItemsFKCustomers …
Run Code Online (Sandbox Code Playgroud) 我正在使用 PostgreSQL 9.3pg_dump
工具仅使用以下方法提取公共模式定义:
pg_dump -s -n public -h host -U postgres --dbname=db > ./schema.sql
Run Code Online (Sandbox Code Playgroud)
但是当我检查时schema.sql
,我们的一个观点出现在CREATE TABLE
声明中而不是CREATE VIEW
声明中。
但是,如果我pg_dump
使用以下特定视图:
pg_dump -s -t myview -h host -U postgres --dbname=db > ./schema.sql
Run Code Online (Sandbox Code Playgroud)
然后schema.sql
包含实际的视图定义。
那么,为什么会发生这种情况?谢谢你们!
我正在使用 PostgreSQL 9.3。假设我们正在制造某种类型的某些物品,在任何时候我们最多只能生产某种类型的一件物品。下表记录了我们制造物品的历史记录,其中可能有一行manufactured_until
是null
- 这些是当前生产的物品。
create table item
(
id int,
type_id int,
manufactured_from timestamp,
manufactured_until timestamp
)
Run Code Online (Sandbox Code Playgroud)
样本数据:
1 | 101 | 1.1.2000 | 31.12.2012
2 | 102 | 1.4.2003 | 1.1.2010
3 | 101 | 1.1.2013 |
4 | 102 | 2.1.2010 | 4.5.2014
5 | 102 | 5.5.2014 |
Run Code Online (Sandbox Code Playgroud)
以下逻辑应该成立:对于每种物品类型,此时最多应该生产一个物品 ( manufactured IS NULL
)。在示例中,我应该无法添加记录(6, 101, 27.8.2014, NULL)
。
我想写一个UNIQUE
约束来保护它。是否可以?对于奖励积分,是否有一种相当复杂的方法来保护一种项目类型的间隔不重叠?
postgresql database-design exclusion-constraint unique-constraint
在 PostgreSQL 9.6 我有一个T
这样的表
category | id | data
---------+----+------
A | 1 | foo
A | 2 | bar
A | 3 | baz
B | 4 | eh
B | 5 | whatcomesafterfoobarbaz
Run Code Online (Sandbox Code Playgroud)
有一个视图V
为我提供了数据T
,所以它有列category, id, data
。T
本质上是 的物化视图V
,除了我需要以比“刷新所有内容”更多的粒度来刷新它。
所以我会选择V
例如
SELECT * FROM V WHERE category = 'A';
Run Code Online (Sandbox Code Playgroud)
或者
SELECT * FROM V WHERE category = 'A' AND id = 2;
Run Code Online (Sandbox Code Playgroud)
并T
用任何data
V …
假设一个简单的查询:
(SELECT MAX(timestamp) FROM events e WHERE e.id < some_id)
+ ((SELECT MIN(timestamp) FROM events e WHERE e.id > some_id)
- (SELECT MAX(timestamp) FROM events e WHERE e.id < some_id)) / 2
Run Code Online (Sandbox Code Playgroud)
如果 some_id
是参数,它会根据某些事件序列找到近似时间戳(它采用前一个和后一个事件并平均它们的时间戳)。
这个查询很好用,现在我想把它打包成一个函数:
CREATE FUNCTION id_to_timestamp(integer) RETURNS timestamp with time zone AS
$BODY$
(SELECT MAX(timestamp) FROM events e WHERE e.id < $1)
+ ((SELECT MIN(timestamp) FROM events e WHERE e.id > $1)
- (SELECT MAX(timestamp) FROM events e WHERE e.id < $1)) / 2
$BODY$
LANGUAGE sql; …
Run Code Online (Sandbox Code Playgroud)