php 一对一关系可空原则仍要创建唯一索引

cnwbcb6i  于 2023-03-11  发布在  PHP
关注(0)|答案(3)|浏览(150)

我有一个Person实体,它与Location表有两个关系(hometowncurrent),这两个字段都可以为空,否则它们必须存在于Location表中:

class Person {
.....
/**
 * @var Location
 * @ORM\OneToOne(targetEntity="Location")
 * @ORM\JoinColumn(name="hometown_id", referencedColumnName="id",nullable=true)
 **/
protected $hometown;

/**
 * @var Location
 * @ORM\OneToOne(targetEntity="Location")
 * @ORM\JoinColumn(name="current_id", referencedColumnName="id", nullable=true)
 **/     
 protected $current;
....
}

现在,我想基于doctrine:schema:update --dump-sql输出更新我的数据库模式,但是这会产生问题:

CREATE UNIQUE INDEX UNIQ_8D93D6494341EE7D ON person (hometown_id);
CREATE UNIQUE INDEX UNIQ_8D93D649B8998A57 ON person (current_id);

我无法定义这些索引,因为表中有多个空行。
你能帮帮我吗?

nwnhqdif

nwnhqdif1#

OneToOne关系是唯一的,因为它意味着只能将一个person分配给一个location,将一个location分配给一个person
在您的场景中,您希望一个person具有多个位置,一个location可以具有多个person,这将是一个ManyToMany关系。
在Doctrine中使用ManyToMany时,您将指定Doctrine将管理的JoinTable(不必为JoinTable创建实体)。JoinTableManyToMany分解为类似OneToMany的内容,例如一个person到多个location(s)如下例所示。JoinTable将存储您想要的值。

/**
 * @ORM\ManyToMany(targetEntity="Location")
 * @ORM\JoinTable(name="hometown_location",
 *      joinColumns={@ORM\JoinColumn(name="person_id", referencedColumnName="id", unique=true)},
 *      inverseJoinColumns={@ORM\JoinColumn(name="location_id", referencedColumnName="id")}
 *      )
 **/
protected $hometown;

/**
 * @ORM\ManyToMany(targetEntity="Location")
 * @ORM\JoinTable(name="current_location",
 *      joinColumns={@ORM\JoinColumn(name="person_id", referencedColumnName="id", unique=true)},
 *      inverseJoinColumns={@ORM\JoinColumn(name="location_id", referencedColumnName="id")}
 *      )
 **/
protected $current;

public function __construct() {
    $this->hometown = new \Doctrine\Common\Collections\ArrayCollection();
    $this->hometown = new \Doctrine\Common\Collections\ArrayCollection();
}

如果没有location可分配给hometowncurrent,也没关系,不会占用空间。如果有location可分配给hometowncurrent,则必须是location表中的有效location

hsgswve4

hsgswve42#

它看起来像你正在寻找外键
http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

ALTER TABLE `Person` ADD INDEX ( `hometown_id` ) ;
ALTER TABLE `Person` ADD FOREIGN KEY ( `hometown_id` ) REFERENCES `Location` ( `id` )
ON DELETE RESTRICT ON UPDATE RESTRICT ;

ALTER TABLE `Person` ADD INDEX ( `current_id` ) ;
ALTER TABLE `Person` ADD FOREIGN KEY ( `current_id` ) REFERENCES `Location` ( `id` )
ON DELETE RESTRICT ON UPDATE RESTRICT ;
nqwrtyyt

nqwrtyyt3#

迟回复只是因为它显示在搜索:
你所描述的不是一对一的关联。当我们想象一个人的当前位置是他/她的家乡时,这就变得很清楚了。在这种情况下,Person的两个属性将具有相同的id。一对一的关联通常共享相同的主键,因此Doctrine试图创建唯一的索引。
这是ManyToOne关联,可以声明为:

class Person {
.....
/**
 * @var Location|null
 * @ORM\ManyToOne(targetEntity="Location")
 * @ORM\JoinColumn(name="hometown_id", referencedColumnName="id",nullable=true)
 **/
protected $hometown;

/**
 * @var Location|null
 * @ORM\ManyToOne(targetEntity="Location")
 * @ORM\JoinColumn(name="current_id", referencedColumnName="id", nullable=true)
 **/     
 protected $current;
....
}

注:注解未测试。

相关问题