【发布时间】:2016-08-24 16:35:31
【问题描述】:
我正在尝试为电话簿开发一个简单的数据库。这是我写的:
CREATE TABLE phone
(
phone_id SERIAL PRIMARY KEY,
phone CHAR(15),
sub_id INT, -- subscriber id --
cat_id INT -- category id --
);
CREATE TABLE category
(
cat_id SERIAL PRIMARY KEY, -- category id --
cat_name CHAR(15) -- category name --
);
CREATE TABLE subscriber
(
sub_id SERIAL PRIMARY KEY,
name CHAR(20),
fname CHAR(20), -- first name --
lname CHAR(20), -- last name --
);
CREATE TABLE address
(
addr_id SERIAL PRIMARY KEY,
country CHAR(20),
city CHAR(20),
street CHAR(20),
house_num INT,
apartment_num INT
);
-- many-to-many relation --
CREATE TABLE sub_link
(
sub_id INT REFERENCES subscriber(sub_id),
addr_id INT
);
我为多对多关系创建了一个链接表,因为很少有人可以住在同一个地址,而一个人可以在不同的时间住在不同的地点。
但我不知道如何像这样在强规范化数据库中添加数据并保持数据的完整性。
第一个改进是我在地址表上添加了唯一键,因为该表不应包含重复数据:
CREATE TABLE address
(
addr_id SERIAL PRIMARY KEY,
country CHAR(20),
city CHAR(20),
street CHAR(20),
house_num INT,
apartment_num INT,
UNIQUE (country, city, street, house_num, apartment_num)
);
现在的问题是如何将关于某人的新记录添加到数据库中。我想我应该使用下一个动作顺序:
在
subscriber表中插入一条记录,因为sub_link和phone表必须使用新订阅者的ID。在
address表中插入一条记录,因为addr_id在向sub_link添加记录之前必须存在。链接
sub_link表中subscriber和address的最后记录。但是在这一步我有一个新问题:如何在PostgreSQL中有效地从步骤1)和2)中获取sub_id和addr_id?然后我需要在
phone表中插入一条记录。在 3) 步骤中,我不知道如何有效地从以前的查询中获取sub_id。
我在 Postgres 中读到了 WITH 块,但我不知道如何在我的情况下使用它。
更新
我已经完成了 ASL 建议的操作:
-- First record --
WITH t0 AS (
WITH t1 AS (
INSERT INTO subscriber
VALUES(DEFAULT, 'Twilight Sparkle', NULL, NULL)
RETURNING sub_id
),
t2 AS (
INSERT INTO address
VALUES(DEFAULT, 'Equestria', 'Ponyville', NULL, NULL, NULL)
RETURNING addr_id
)
INSERT INTO sub_link
VALUES((SELECT sub_id FROM t1), (SELECT addr_id FROM t2))
)
INSERT INTO phone
VALUES (DEFAULT, '000000', (SELECT sub_id FROM t1), 1);
但是我有一个错误:包含数据修改语句的WITH子句必须在顶层 第 2 行:使用 t1 AS (INSERT INTOsubscriber VALUES(DEFAULT,
【问题讨论】:
标签: postgresql postgresql-9.3 postgresql-9.4