带有 UUID 主键的 ActiveRecord 迁移

Posted

技术标签:

【中文标题】带有 UUID 主键的 ActiveRecord 迁移【英文标题】:ActiveRecord Migrations with UUID primary key 【发布时间】:2011-02-14 19:29:46 【问题描述】:

在我要创建的迁移中,表的主键是一个名为“id”的字段,但它不是一个自动递增的整数。它的数据类型应该是唯一标识符(一个 uuid)。这是我尝试过的:

create_table :some_things, :id => false do |t|
  t.column :id, :uniqueidentifier, :primary => true
  t.column :name, :string, :limit => 255
  t.column :type, :tinyint
  t.column :deleted_flag, :bit
  t.column :class_id, :uniqueidentifier
  t.timestamps
end

这可以创建表,但是没有主键(因为我说:id=>false)。如果我说“create_table :some_things, :id => true, :primary => :id”,那么“id”将成为主键,但它是一个自动递增的整数,而不是非自动递增的 uuid。

我怎样才能使这个迁移工作,以便主键是一个名为“id”的字段,类型为“uniqueidentifier”(非自动递增)?

我正在使用: SQL Server 2008, Rails/ActiveRecord 3.0.3, activerecord-sqlserver-adapter gem, 和 ODBC 连接。

【问题讨论】:

这是***.com/questions/1200568/… 的副本——我们应该合并问题吗? 【参考方案1】:

我不知道如何直接解决问题,但我有一个解决方法。

在没有“primary”指令的情况下输入您的迁移列 ID。并在迁移中的方法“create_table”之后执行 SQL 的添加约束

execute "ALTER TABLE some_things ADD PRIMARY KEY (id);"

(不要使用 MSSQL,它的 SQL 语法可能是错误的)

在您的模型中通过添加定义主键

self.primary_key = "id"

set_primary_key :id

【讨论】:

【参考方案2】:

我是这样解决这个问题的:

1) 在我的迁移中,我允许迁移自动生成 id 和 id_sequence,并添加了一个虚拟 uuid 列(此处称为 guid)。这只是进入开发路径的最简单方法。所以对于

class Thing < ActiveRecord::Base
  attr_accessible :name, :description, :guid
end

我使用迁移

class CreateThings < ActiveRecord::Migration
  def change
    create_table :things do |t|
      t.string :name
      t.string :description
      t.uuid :guid

      t.timestamps
    end
  end
end

2)迁移后,我可以通过sql客户端运行以下内容

ALTER TABLE things DROP CONSTRAINT things_pkey;
ALTER TABLE things ADD PRIMARY KEY (guid);
ALTER TABLE things DROP COLUMN id;
ALTER TABLE things RENAME COLUMN guid TO id;

3) 我正在使用两个 gem 来帮助解决这个问题

gem 'uuidtools'
gem 'postgres_ext'

显然,我的解决方案是针对 Postgres 数据库...但我发布此内容是因为它似乎与您的一个问题相关,即您如何使用 Rails 来保持数据库的距离?无论如何,UUIDtools 与数据库无关。

4) 在我的 Thing 类中我使用这个

class Thing < ActiveRecord::Base
  include Extensions::UUID

UUID 只是一个类似这样的模块

module Extensions
  module UUID
    extend ActiveSupport::Concern

    included do
      # set_primary_key 'guid'
      before_create :generate_uuid

      def generate_uuid
        self.id = UUIDTools::UUID.random_create.to_s
      end
    end
  end
end

顺便说一句,我在这个要点中找到了后者:

https://gist.github.com/rmoriz/937739

但我的解决方案有点不同。

【讨论】:

以上是关于带有 UUID 主键的 ActiveRecord 迁移的主要内容,如果未能解决你的问题,请参考以下文章

JPA Hibernate 使用UUID做为主键的问题

PostgreSQL 9.4 中 UUID 列索引的填充因子建议

MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)

MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)

mysql自增主键怎么用

mysql自增主键怎么用