MySQL Rails 迁移创建表主键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4769725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 18:26:44  来源:igfitidea点击:

Rails Migration Create Table Primary Key

mysqloptimizationruby-on-rails-3migration

提问by Ryan

I am writing a migration script to create a table with a primary key column that is named guidand is a VARCHAR(25). The issue is I feel like I am having to double my effort to achieve what should be possible in one step.

我写一个迁移脚本来创建一个表名为一个主键列guid,并且是VARCHAR(25)。问题是我觉得我必须加倍努力才能在一步中实现应该可能的目标。

If I run:

如果我运行:

create_table(:global_feeds, :primary_key => 'guid') do |t|
  t.string :guid, :limit => 25
  t.text :title
  t.text :subtitle

  ...

  t.timestamps
end

I get a table with a primary key called guidno column called id(which is what I want). However, the issue is the guidcolumn is an INT(11)with auto increment turned on. So I have to run one additional command:

我得到一个主键名为guidno column的表id(这就是我想要的)。但是,问题是该guid列是INT(11)启用了自动增量的。所以我必须运行一个额外的命令:

change_column :global_feeds, :guid, :string, :limit => 25

Seems a bit convoluted to have to basically run two SQL commands to get what I believe should be possible in one.

似乎有点令人费解,必须基本上运行两个 SQL 命令才能获得我认为应该可以在一个中实现的功能。

Any suggestions on how to optimize this?

关于如何优化这个的任何建议?

回答by kakoni

In Rails 4 you can do;

在 Rails 4 中你可以做到;

create_table :global_feeds, id: false do |t|
  t.string :guid, primary_key: true
 ...
end

回答by Max Al Farakh

I suppose you're using mySQL, so here is what you can try

我想你正在使用 mySQL,所以这是你可以尝试的

create_table :global_feeds, {:id => false} do |t|
  t.string :guid
  t.text :title
  t.text :subtitle
  t.timestamps
end
execute "ALTER TABLE global_feeds ADD PRIMARY KEY (guid);"

If you're not on mySQL you should change the query in the executecommand to work on your DB engine. I'm not sure if you can do that on SQLite though. And don't forget to put this line somewhere in global_feed.rb model:

如果您不在 mySQL 上,您应该更改execute命令中的查询以在您的数据库引擎上工作。我不确定你是否可以在 SQLite 上做到这一点。并且不要忘记将此行放在 global_feed.rb 模型中的某处:

set_primary_key :guid

Anyway you're getting the most out of Rails while you're sticking to its conventions. Changing primary key name and type might not be a very good idea.

无论如何,当您坚持其惯例时,您就可以充分利用 Rails。更改主键名称和类型可能不是一个好主意。

回答by Philip Wernersbach

You need to use #column instead of #string. For instance:

您需要使用#column 而不是#string。例如:

create_table(:global_feeds, :primary_key => 'guid') do |t|
  t.column :guid, "varchar(25)", :null => false
  ...
end

Note that the varchartype is not portable to databases other than MySQL.

请注意,该varchar类型不可移植到 MySQL 以外的数据库。

回答by Jordan Sitkin

This is possible in Rails 3. try:

这在 Rails 3 中是可能的。尝试:

  def self.up
    create_table(:signups, :id => false) do |t|
      t.string :token, :primary => true

check out this gist for a great solution for using UUIDs as a primary key col: https://gist.github.com/937739

查看此要点以获取使用 UUID 作为主键 col 的绝佳解决方案:https: //gist.github.com/937739

回答by hxpax

In Rails 5, for thoes who got problem ArgumentError: Index name '*' on table '*' already existswhen rails db:setupwith migration as from @kakoni, the following works for me

在 Rails 5 中,对于从@kakoni 迁移ArgumentError: Index name '*' on table '*' already exists时遇到问题的人rails db:setup,以下对我有用

create_table(:global_feeds, primary_key: :guid, id: false) do |t|
  t.string :guid
 ...
end

For more information, check create_table.

有关更多信息,请查看create_table