我有一个将大文件作为 blob 存储到数据库的实体。
我现在希望 Symfony 永远不会加载这些 blob,除非我通过适当的 getter 专门请求它们。
本质上,我想要与延迟加载关系相同的想法,但对于字符串属性。
到目前为止,我尝试的是将保存文件元数据的所有其他属性放入一个特征中,然后将该特征应用于两个实体。
namespace App\Entity\Traits;
use Doctrine\ORM\Mapping as ORM;
trait DocumentMetaData
{
/**
* @var int|null
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \DateTime|null
*
* @ORM\Column(type="datetime")
*/
private $date_uploaded;
}
一个实体除了特征之外什么都没有......
namespace App\Entity;
use App\Entity\Traits\DocumentMetaData;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="documents")
* @ORM\Entity()
*/
class Document
{
use DocumentMetaData;
}
...另一个添加了 blob 属性:
namespace App\Entity;
use App\Entity\Traits\DocumentMetaData;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="documents")
* @ORM\Entity()
*/
class DocumentFile
{
use DocumentMetaData;
/**
* @var string|null
*
* @ORM\Column(type="blob")
*/
private $blob;
}
现在,如果我不想加载 blob,例如文件列表,我只需使用没有 blob 的实体即可。
这种方法可行,但会导致问题,因为我需要将两个实体指向同一个表(请参阅类级别 ORM 注释)。
具体来说,它在运行迁移时使教条变得疯狂:
名称为“myapp.documents”的表已存在。
这非常有道理,我真的希望有人能给我指出一个更好的解决方案。
如何告诉原则不要加载 blob,除非明确要求?
因此,根据对我的问题的评论 - 实现这一点的方法是利用原则延迟加载表之间关系的能力,这样迁移就不会中断。
基本上,我必须去创建一个仅保存我的巨型斑点的新实体,然后在原始实体和斑点实体之间建立一对一的关系。
然后,我将该关系设置为加载 EXTRA_LAZY,因此我现在可以控制何时应该加载大量数据。
我认为这在标准化数据库设计方面并不理想,但它比其他任何东西都要好得多,对此我很满意。
我建议不要将文件存储在数据库中。将它们放在它们所属的文件系统上,并配置您的 Web 服务器/应用程序以(静态)为它们提供服务。如果需要,您仍然可以将所需的身份验证/授权方法放在前面。 这还允许您仅根据需要使用流式传输/读取,而无需将整个文件从数据库加载到 RAM 中。