【发布时间】:2011-11-15 12:09:27
【问题描述】:
架构更改后,我必须迁移 Postgres 数据库中的大量现有数据。
在旧模式中,国家属性将存储在用户表中。现在国家属性已经被移动到一个单独的地址表中:
users:
country # OLD
address_id # NEW [1:1 relation]
addresses:
id
country
架构实际上更复杂,地址不仅包含国家/地区。因此,每个用户都需要有自己的地址(1:1 关系)。
迁移数据时,我在插入地址后在用户表中设置外键时遇到问题:
INSERT INTO addresses (country)
SELECT country FROM users WHERE address_id IS NULL
RETURNING id;
如何传播插入行的 ID 并在 users 表中设置外键引用?
到目前为止,我能想到的唯一解决方案是在地址表中创建一个临时 user_id 列,然后更新 address_id:
UPDATE users SET address_id = a.id FROM addresses AS a
WHERE users.id = a.user_id;
但是,结果证明这非常慢(尽管在 users.id 和addresses.user_id 上都使用了索引)。
users 表包含大约 300 万行,其中 300k 缺少关联地址。
有没有其他方法可以将派生数据插入到一个表中,并将外键引用设置为另一个表中插入的数据(不更改架构本身)?
我正在使用 Postgres 8.3.14。
谢谢
我现在已经通过使用 Python/sqlalchemy 脚本迁移数据解决了这个问题。结果证明(对我来说)比用 SQL 尝试同样的方法要容易得多。不过,如果有人知道在 Postgres SQL 中处理 INSERT 语句的返回结果的方法,我会很感兴趣。
【问题讨论】:
-
这是旧的,你解决了它。但是在这种情况下,1:1 的关系是没有意义的。您不应该创建一个国家/地区表吗?
-
地址实际上包含每个用户的街道、城市、邮政编码、...和国家。我只是对其进行了简化以使其更具可读性。
-
国家、邮政编码、城市、县等都有自己的表格。剩下街道、号码等。除非每个用户可能有多个地址,否则在单独的表中仍然没有任何意义。
标签: sql postgresql data-migration