【问题标题】:Convert String Column to Array Column in Postrgresql 9.3在 Postgresql 9.3 中将字符串列转换为数组列
【发布时间】:2015-09-28 19:33:00
【问题描述】:

我在数据库中有一个字符串列需要转换为数组类型。在我还需要设置索引的过程中,不应该锁定数据库。

ALTER TABLE sites ALTER COLUMN rtb_id TYPE varchar[] USING string_to_array(rtb_id, '');
CREATE INDEX CONCURRENTLY rtb_id_search ON sites(rtb_id) USING array_to_string;
DROP INDEX CONCURRENTLY ix_sites_bundle_trgm_gin ON sites;
DROP INDEX CONCURRENTLY ix_sites_name_trgm_gin ON sites;

这是这样做的吗?

编辑:

ALTER TABLE sites ADD COLUMN rtb_ids varchar[]
...
BEFORE INSERT OR UPDATE ... FOR EACH ROW trigger that sets NEW.rtb_id_new := string_to_array(NEW.rtb_id,' ') for each row.
In batches, UPDATE sites SET rtb_id_new = string_to_array(rtb_id,' ')
...
VACUUM sites; 
CREATE INDEX CONCURRENTLY rtb_ids_search ON sites(rtb_ids) USING array_to_string(rtb_ids, '');

ALTER TABLE sites DROP COLUMN rtb_id; 

谢谢

【问题讨论】:

  • 很难说。请提供基本信息:表和索引定义、rtb_id 的示例值,并描述您的用例和基本原理。 非常奇怪的是,ID 列将是一个数组。数组列上的默认 btree 索引似乎没有多大意义......

标签: arrays postgresql indexing locking


【解决方案1】:

不可能在没有锁的情况下做到这一点。不过,您可以使用相对较少的短期强锁来做到这一点。

ALTER TABLE 目前会占用排他锁很长时间,因为它会重写全表。

相反,您需要:

  • ALTER TABLE sites ADD COLUMN rtb_id_new varchar[]
  • 创建一个BEFORE INSERT OR UPDATE ... FOR EACH ROW 触发器,为每一行设置NEW.rtb_id_new := string_to_array(NEW.rtb_id,' ')
  • 分批,UPDATE sites SET rtb_id_new = string_to_array(rtb_id,' ')
  • 一旦填充了所有值VACUUM sites; 然后ALTER TABLE sites ALTER COLUMN rtb_id_new NOT NULL。这将需要一个排他锁足够长的时间来进行顺序扫描,所以它不会是超快的。在 PostgreSQL 9.5 上,所采用的锁较弱,不会停止 SELECTs。
  • 建立您的索引CONCURRENTLY
  • ALTER TABLE sites DROP COLUMN rtb_id; ALTER TABLE sites RENAME COLUMN rtb_id_new TO rtb_column;
  • 如果您需要添加任何 UNIQUE 约束,请将它们添加到 USING 已构建的索引以最大限度地减少锁定持续时间。

这不是完全无锁的。特别是 NOT NULL 约束会受到伤害,因为 PostgreSQL 还不知道如何将 NOT NULL 约束添加为 NOT VALID 然后对其进行验证。

【讨论】:

  • 如何循环遍历 rtb_id 列中的每一行,应用 string_to_array 并插入 rtb_ids 工作?刚刚编辑了我的问题,我不确定我会如何做这部分查询。
  • @FranGoitia 使用 WHERE 子句中的键范围进行更新。一个简单的脚本会很有用。不要使用 plpgsql,因为您需要它们成为单独的事务并在它们之间进行真空处理才能获得任何好处。如果表很小(少于几十万行),只需对整个表执行一次 UPDATE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2017-11-25
  • 1970-01-01
相关资源
最近更新 更多