我有一个表;项目";具有此字段工作区,该工作区采用字符串数组。所以我已经将其转换为存储单个字符
create table("projects") do
add(:name, :string, null: false)
add(:title, :string, null: false)
add(:workspaces, {:array, :string})
timestamps()
end
我写了这个迁移来存储单个字符串
alter table(:projects) do
modify(:workspace, :string)
我想运行这个迁移,但我也想更新存储在数据库中的所有数据。我需要更新所有的工作空间数据来存储一个字符串。
假设工作空间具有此值{value1, value2}
。它将查找值1,如果找到,它将存储值1,否则将存储值2
{value1, value2}
就是这样存储在数据库表中的。所以当我们把它装进长生不老药里时,它看起来像这个["value1", "value2"]
我在这里能做什么?
如果我理解正确,您希望将workspaces
数组列更改为包含数组第一个元素的workspace
字符串列。如果是这样的话,你可以在迁移中做这样的事情:
# Add the `workspace` column:
alter table(:projects) do
add(:workspace, :string)
end
# Set the value of the new column:
execute("""
UPDATE projects SET workspace = CASE
WHEN 'value1' = ANY(workspaces) THEN 'value1'
WHEN 'value2' = ANY(workspaces) THEN 'value2'
ELSE 'default_value'
END
""")
# Remove the old column
alter table(:projects) do
remove(:workspaces)
end
看起来您正试图在关系数据库中创建一个无模式数据库。这会很快变得困难。使用无架构数据库(如couch或mongo(可能会为您提供更好的服务。
然而,如果您使用的是postgres,jsonb或json列类型将更好地服务于这种用例IMO。由于postgres运算符很有趣,因此数据查询起来有点困难,但一旦您了解了它,它就不会太差,并且具有适当索引的性能将与无架构的不相上下。此外,您还可以获得额外的好处,即不必将序列化/反序列化写入数据库层。