【问题标题】:Postgres Partial Unique Indexes in SymfonySymfony 中的 Postgres 部分唯一索引
【发布时间】:2013-12-19 01:33:04
【问题描述】:

Postgres 可以做部分唯一索引,但我找不到任何教义文档表明对此有任何支持。

http://www.postgresql.org/docs/current/interactive/indexes-partial.html#INDEXES-PARTIAL-EX3

如何在 Symfony 中拥有一个实体,例如电子邮件。我想在哪里存储默认电子邮件的布尔标志。

电子邮件表看起来像,

id,user_id,email,default
1,1,email@something.com,false
2,1,email2@something.com,true
3,1,email3@something.com,false

我想要一个对 user_id 和 default = true 的唯一约束。

SQL 我会做类似的事情,

CREATE UNIQUE INDEX default_constraint ON emails (user_id)
    WHERE default;

还有其他方法可以做到这一点吗?我考虑过实体中的 prePersist 函数,但这需要调用 db 来检查。

编辑:我也在考虑一个事件监听器,http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html

我不确定我是否要监听每个 prePersist 事件,我是否可以监听特定实体而不是使用 if 语句进行过滤。例如 if ($entity instanceof Product) {

【问题讨论】:

    标签: php postgresql symfony doctrine-orm


    【解决方案1】:

    Postgres 9.0+ 中有一个非常简洁的结构,称为排除约束。 CREATE TABLE 的文档中对此进行了简要说明。因为在这个例子中我们只依赖于排除约束的谓词部分而不是操作符的灵活性,所以我会使用 B-tree 索引,尽管文档有建议。如果您搜索“postgres 索引类型”,您可以阅读一些有关不同索引类型的信息。目前我不能在答案中发布多个链接,因为我是新来的,所以你只需要谷歌它。 :)

    fiddle 是其工作原理的一个示例。基本上,EXCLUDE 末尾的谓词将约束转换为仅适用于WHERE "default" = trueUNIQUE

    如果可能有其他应用程序与表交互,这可能是最佳路径,但如果信息可用并且在前端应用了约束,则向您的客户提供反馈可能会更快。

    【讨论】:

      【解决方案2】:

      我认为教义现在确实支持这一点!看在 doctrine annotation reference,特别是在@index 部分。

      <?php
      /**
       * @Entity
       * @Table(name="ecommerce_products",indexes={@Index(name="search_idx", columns={"name", "email"}, options={"where": "(((id IS NOT NULL) AND (name IS NULL)) AND (email IS NULL))"})})
       */
      class ECommerceProduct
      {
      }
      

      【讨论】:

      • 这似乎创建了部分索引,但它并没有使它唯一......(它正在执行CREATE INDEX default_constraint ON emails (user_id) WHERE default;(没有唯一)你知道有没有办法强制索引是唯一的?
      【解决方案3】:

      编写 UniqueConstraint 注释

      use Doctrine\ORM\Mapping as ORM;
      
      /**
       * @ORM\Table(
       *     name="my_table",
       *     uniqueConstraints={
       *         @ORM\UniqueConstraint(name="uc__my_table__field", columns={"field"}),
       *     },
       * )
       */
      

      然后尝试生成迁移

      ./bin/console doctrine:migrations:diff
      

      【讨论】:

        猜你喜欢
        • 2019-10-06
        • 2015-03-14
        • 2019-10-02
        • 2012-09-06
        • 1970-01-01
        • 2020-12-24
        • 2013-09-13
        • 2014-06-25
        相关资源
        最近更新 更多