【问题标题】:create unique constraints per user为每个用户创建唯一的约束
【发布时间】:2014-05-29 12:53:29
【问题描述】:

我正在构建一个小型应用程序,此时我正在创建数据库架构。我将 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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    UNIQUE (user_id, name)
    

    Per documentation:

    这指定指定列中的值组合 在整个表中是唯一的,尽管任何一列都需要 不是(通常也不是)唯一的。

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

    并且不要将第一个表称为“用户”,即a reserved word in standard SQL and in Postgres,不应用作标识符。

    【讨论】:

    • 我不想要 n:m 关系,一个用户可以有多个位置,但一个位置(或多个位置)不能属于多个用户。至于保留字,我知道它是保留的,但这不是 SQL 数据库(不是 Microsoft SQL DB),而且我只知道对于那些数据库,这个表名是保留的,还是我错了?
    • 是的,我也找到了reserved identifiers 的列表。似乎是。您对我可以将表格重命名为什么有什么建议吗?
    • SQL is the structured query language 与 MS 无关,他们只是像其他人一样在产品中使用该术语。我在上面的 Postgres 中添加了保留字的链接。您仍然可以使用“用户”,但必须双引号。总是。这很容易出错。将其命名为“usr”或“users”或其他任何名称。
    • 我知道 SQL 是一种语言,但它有一些特定的方面取决于所使用的数据库。我也找到了相同的链接,我检查了其他表的名称是否有保留字,我发现了一些:) 感谢您指出,我永远不会发现它...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 2020-09-08
    • 1970-01-01
    • 2016-06-04
    相关资源
    最近更新 更多