我正在构建一个小应用程序,此时我正在创建数据库架构。我使用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
在每个用户的基础上唯一?
答案 0 :(得分:1)
只需在两列上创建唯一约束:
UNIQUE (user_id, name)
这指定了指示列中值的组合 虽然任何一个列都需要,但在整个表中都是唯一的 不是(并且通常不是唯一的)。
但从它的外观来看,你真的想要另一个表user_location
而不是在位置和用户之间实现n:m关系 - 在(user_id, location_id)
上使用主键。
请勿拨打第一个表格"用户",即a reserved word in standard SQL and in Postgres,并且不应将其用作标识符。