将表的列移动到新表中,并在PostgreSQL中作为外键引用

问题描述 投票:0回答:2

假设我们有一个包含字段的数据库表“ id”,“ category”,“ subcategory”,“ brand”,“ name”,“ description”等。为(例如)创建单独的表的好方法是什么“类别”,“子类别”和“品牌”并且原始表中的相应列和行成为外键引用?

概述所涉及的操作:-在原始表的每一列中获取所有唯一值,这些值应成为外键;-为那些创建表-在原始表(或副本)中创建外键引用列]

在这种情况下,PostgreSQL数据库是通过Ruby应用程序中的Sequel访问的,因此可用的界面是命令行,Sequel,PGAdmin或(...)

问题:您将如何做?

ruby postgresql data-modeling sequel
2个回答
3
投票
        -- 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
        ;

2
投票

我不确定我是否完全理解您的问题,如果这似乎无法回答,请发表评论并可能改善您的问题以进行澄清,但这听起来像您想进行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);

对要创建的每个表重复此操作。

这里是相关文档:

CREATE TABLE

ALTER TABLE

注意:代码和参考适用于Postgresql 9.4

© www.soinside.com 2019 - 2024. All rights reserved.