我正在设计一个数据库来存储一些艺术家的信息。这些艺术家可以属于一个或多个组织。从这些组织中,我只想存储他们的名字,我正在考虑用这些组织创建一个表,这些组织只是将名称作为主键,没有别的。有一个只有主键字段的表的事实是概念错误吗?在这种情况下,我会很感激一些解决这个问题的建议。
3 回答
有一个只有主键字段的表的事实是概念错误吗?
不是自己。在某些完全合法的情况下,所有字段都包含一个 PK。
在这种特殊情况下,组织名称是一个键,但这并不一定意味着它应该是主键 - 您可以“发明”另一个更小(通常是整数)且更易于维护并使其成为主键的键,就像这样:
这organizarion_id
被称为“代理键”,这样做的一些优点包括:
- 子 FK 会更苗条(因为只有整数迁移到子代,而不是整个字符串)。
- 您可以在不更新 的
organization_name
情况下更新organization_id
,因此无需将此更新级联给子级。 - 一个小的整数代理可能比一个更复杂的自然键对 ORM 更友好。
缺点:
- 可能需要更多的加入。
- 需要多一个索引,并且每个额外的索引都会带来开销(即使在基于堆的表中,尤其是在聚簇表中)。
正如您所看到的,这是一个平衡问题,您是唯一拥有足够领域知识来做出正确决定的人。
organization_artist
注意:事项中的字段顺序。如果您需要有效地查询给定组织的艺术家,请使用上面显示的顺序,如果您需要给定艺术家的组织,请反转它。如果您需要两个方向,则需要在这两个字段(在 PK 下的索引旁边)上使用另一个复合索引,但顺序相反。如果您只能使用一个索引,请考虑对这张表进行集群(如果您的 DBMS 支持它)。
您需要一个 OrganizationId,来处理组织名称更改的情况。
您可能还会遇到不同组织似乎具有相同名称的情况。有多少“现代艺术博物馆”?(好吧,对于纽约人来说,只有一个 ;-)
您的组织表可能会随着时间的推移而扩展,其中包含短名称、地址、联系人、首选语言等列。因此,表格应如下所示:
create table Organizations (
OrganizationId int not null identity(1,1),
Name varchar(255),
CreatedBy varchar(255) default system_user,
CreatedAt datetime default getdate()
)
在成熟的数据库中,您甚至会认识到组织会更改名称、合并,有时甚至会拆分。您可以通过在记录中添加生效日期和结束日期来处理此问题。
此类事情的标准做法是为艺术家提供 1 个表格,为组织提供 1 个表格,以及为艺术家与 1 个或多个组织相关联的 1 个关联表。
ARTIST (id, firstName, lastName)
ORGANIZATION (id, name)
ARTIST_ORGANIZATION(artist_id, org_id)
即使组织名称可能/应该是唯一的,最好将数字 id 作为主键,这样您就可以进行关联。并且查询与 id 的关联比搜索字符串的性能更好。