【问题标题】:Inserting record violates two unique indices in PostgreSQL. Which one is checked first?插入记录违反了 PostgreSQL 中的两个唯一索引。先检查哪一个?
【发布时间】:2019-03-11 14:43:10
【问题描述】:

我有一个 PostgreSQL 表,在不同的字段上有两个唯一索引(nickname 和 email)。我正在尝试插入一条违反这两个约束的记录。我希望首先检查并报告nickname。

我观察到首先检查首先创建的索引,所以我首先在nickname 上创建索引并且它有点工作。但是这种行为是指定的,我可以依赖它吗,还是只是偶然?

【问题讨论】:

    标签: postgresql unique-constraint


    【解决方案1】:

    PostgreSQL使用RelationGetIndexList获取索引列表,评论说:

    /*
     * RelationGetIndexList -- get a list of OIDs of indexes on this relation
    [...]
     *
     * The returned list is guaranteed to be sorted in order by OID.  This is
     * needed by the executor, since for index types that we obtain exclusive
     * locks on when updating the index, all backends must lock the indexes in
     * the same order or we will get deadlocks (see ExecOpenIndices()).  Any
     * consistent ordering would do, but ordering by OID is easy.
    [...]
     */
    

    OID(对象标识符)是向上计数的 4 字节无符号整数,因此通常后面的对象将获得更高的 OID。这与您观察到的相符。

    但是,一旦 OID 的范围用完,它们就会回绕并从 FirstNormalObjectId (16384) 重新开始,因此不能保证首先创建的索引具有较低的 OID。

    您可以使用如下查询:

    SELECT 'indexname'::regclass::oid;
    

    查找每个索引的 OID。

    要获取表上所有索引的 OID,请使用

    SELECT indexrelid AS oid, indexrelid::regclass
    FROM pg_index
    WHERE indrelid = 'tablename'::regclass;
    

    【讨论】:

    • 谢谢!那么问题的一种扩展:有没有办法通过 SQL 获取索引的 OID?这样我就可以断言一切正常(或不正常)。
    • 我在答案中添加了一个查询。
    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多