假设我们有一个包含字段的数据库表“ id”,“ category”,“ subcategory”,“ brand”,“ name”,“ description”等。为(例如)创建单独的表的好方法是什么“类别”,“子类别”和“品牌”并且原始表中的相应列和行成为外键引用?
概述所涉及的操作:-在原始表的每一列中获取所有唯一值,这些值应成为外键;-为那些创建表-在原始表(或副本)中创建外键引用列]
在这种情况下,PostgreSQL数据库是通过Ruby应用程序中的Sequel访问的,因此可用的界面是命令行,Sequel,PGAdmin或(...)
问题:您将如何做?
-- Some test data
CREATE TABLE animals
( id SERIAL NOT NULL PRIMARY KEY
, name varchar
, category varchar
, subcategory varchar
);
INSERT INTO animals(name, category, subcategory) VALUES
( 'Chimpanzee' , 'mammals', 'apes' )
,( 'Urang Utang' , 'mammals', 'apes' )
,( 'Homo Sapiens' , 'mammals', 'apes' )
,( 'Mouse' , 'mammals', 'rodents' )
,( 'Rat' , 'mammals', 'rodents' )
;
-- [empty] table to contain the "squeezed out" domain
CREATE TABLE categories
( id SERIAL NOT NULL PRIMARY KEY
, category varchar
, subcategory varchar
, UNIQUE (category,subcategory)
);
-- The original table needs a "link" to the new table
ALTER TABLE animals
ADD column category_id INTEGER -- NOT NULL
REFERENCES categories(id)
;
-- FK constraints are helped a lot by a supportive index.
CREATE INDEX animals_categories_fk ON animals (category_id);
-- Chained query to:
-- * populate the domain table
-- * initialize the FK column in the original table
WITH ins AS (
INSERT INTO categories(category, subcategory)
SELECT DISTINCT a.category, a.subcategory
FROM animals a
RETURNING *
)
UPDATE animals ani
SET category_id = ins.id
FROM ins
WHERE ins.category = ani.category
AND ins.subcategory = ani.subcategory
;
-- Now that we have the FK pointing to the new table,
-- we can drop the redundant columns.
ALTER TABLE animals DROP COLUMN category, DROP COLUMN subcategory;
-- show it to the world
SELECT a.*
, c.category, c.subcategory
FROM animals a
JOIN categories c ON c.id = a.category_id
;
我不确定我是否完全理解您的问题,如果这似乎无法回答,请发表评论并可能改善您的问题以进行澄清,但这听起来像您想进行CREATE TABLE xxx AS
。例如:
CREATE TABLE category AS (SELECT DISTINCT(category) AS id FROM parent_table);
然后更改parent_table
以添加外键约束。
ALTER TABLE parent_table ADD CONSTRAINT category_fk FOREIGN KEY (category) REFERENCES category (id);
对要创建的每个表重复此操作。
这里是相关文档:
注意:代码和参考适用于Postgresql 9.4