数据库建模:按实体类型的空外键
Posted
技术标签:
【中文标题】数据库建模:按实体类型的空外键【英文标题】:database modeling: null foreign keys by entity type 【发布时间】:2021-02-05 06:56:20 【问题描述】:我需要一些帮助来设计我的数据库关系。 我有这些表:文档、公司、个人和用户。文档可以是内部的或外部的。
如果是外部的,可以由公司或个人签名。 如果是内部的,则必须由用户签名。在任何情况下,文档都是由单个实体(公司、个人或用户)签署的。我正在考虑通过以下方式创建文档表:
documents
----------
id_document
...
type
id_user
id_company
id_indiv
其中type
可以是0:内部,1:外部,id_user
、id_company
、id_indiv
是各个表的外键,可以为空。这个逻辑可以吗?有人可以建议我一个更好的主意吗?
【问题讨论】:
【参考方案1】:Laravel 的 Eloquent ORM
提供了 Polymorphic
关系来处理这类问题。
更具体地说,您可以放置两个字段; documentable_type
和 documentable_id
在您的 document
表中。然后将这些关系方法添加到每个模型中;
class Document extends Model
/**
* Get the owning imageable model.
*/
public function signer()
return $this->morphTo();
class User extends Model
/**
* Get the documents signed by this user.
*/
public function documents()
return $this->morphMany('App\Models\Document', 'documentable');
class Company extends Model
/**
* Get the documents signed by this company.
*/
public function documents()
return $this->morphMany('App\Models\Document', 'documentable');
class Individual extends Model
/**
* Get the documents signed by this individual.
*/
public function documents()
return $this->morphMany('App\Models\Document', 'documentable');
那么就可以使用下面的sn-ps;
$document->signer; // This returns either user or company or individual
$company->documents; // This returns a collection of document models which is signed by this company
$individual->documents;
$user->documents;
更多详情,请查看此链接; https://laravel.com/docs/8.x/eloquent-relationships#polymorphic-relationships
【讨论】:
我真的很喜欢你的回答。但我有一个疑问。公司,个人用户是旧表,我无法修改。例如,individal 有两列:first_name,last name,company 有:bussines_name,user 有一个名为:names 的列。如何获取包含歌手姓名的文件列表。class Individual: public function name() return $this->first_name . ' ' . $this->last_name;
class Company: public function name() return $this->bussines_name;
所以我可以做 $document->signer->name();对吗?
$document->signer
的类型因上下文而异。正如我在回答中提到的,它既不能是 User
模型,也不能是 Company
模型或 Individual
模型。因此,最好为每个模型添加名为 name()
的常用方法。
或者也定义自定义访问器(例如getNameAttribute
)。以上是关于数据库建模:按实体类型的空外键的主要内容,如果未能解决你的问题,请参考以下文章
如何定义一个维度,以便在显示所有值时不忽略 FK 中的空值?
《Entity Framework 6 Recipes》翻译系列 -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模 (转)