为每个用户创建唯一约束

时间:2014-05-29 12:53:30

标签: ruby postgresql database-design unique-constraint sequel

我正在构建一个小应用程序,此时我正在创建数据库架构。我使用PostgreSQL Sequel,我有两个迁移:

Sequel.migration do
    change do

        Sequel::Model.db.run 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'

        create_table :user do
            String :id, :type => :uuid, :primary_key => true, :default => Sequel.function(:uuid_generate_v4)


            DateTime :created_at
            DateTime :updated_at


            index :id, :unique => true
        end
    end
end

Sequel.migration do
    change do

        Sequel::Model.db.run 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'

        create_table :location do
            String :id, :type => :uuid, :primary_key => true, :default => Sequel.function(:uuid_generate_v4)

            foreign_key :user_id, :user, :type => :uuid


            String :name, :unique => true, :null => false # TODO: unique, per user
            Float :latitude, :null => false
            Float :longitude, :null => false


            DateTime :created_at
            DateTime :updated_at


            index :id, :unique => true
            full_text_index :name, :index_type => :gist
        end
    end
end

正如您所看到的,name表上的location列是唯一的,但我对此表示怀疑。因为我想在名称上建立一个唯一约束,但是每个用户,所以用户只能有一个名称相同的位置,但在整个表中,许多用户可以拥有相同名称的位置(用户和位置之间的关系是一对多)。

我认为在列上添加的unique约束会使列通常是唯一的,因此在所有用户中,位置名称必须是唯一的。如果是这样,我如何创建一个约束,使name在每个用户的基础上唯一?

1 个答案:

答案 0 :(得分:1)

只需在两列上创建唯一约束:

UNIQUE (user_id, name)

Per documentation:

  

这指定了指示列中值的组合   虽然任何一个列都需要,但在整个表中都是唯一的   不是(并且通常不是唯一的)。

但从它的外观来看,你真的想要另一个表user_location而不是在位置和用户之间实现n:m关系 - 在(user_id, location_id)上使用主键。

请勿拨打第一个表格"用户",即a reserved word in standard SQL and in Postgres,并且不应将其用作标识符。