Database design 关于复合主键的问题

Database design 关于复合主键的问题,database-design,composite-primary-key,database-integrity,Database Design,Composite Primary Key,Database Integrity,示例表: Ticket - id - tenant_id - foo TicketItem - id - tenant_id - ticket_id - bar 假设每个表上的id和tenant\u id构成复合主键,而ticket\u id是ticket的外键,此设置是否可以保护我免受TicketItem拥有tenant\u id=1和ticket\u id=5的ticket拥有tenant\u id=2的情况的影响?简单地说,数据库是

示例表:

Ticket
    - id
    - tenant_id
    - foo
TicketItem
    - id
    - tenant_id
    - ticket_id
    - bar
假设每个表上的
id
tenant\u id
构成复合主键,而
ticket\u id
ticket
的外键,此设置是否可以保护我免受
TicketItem
拥有
tenant\u id=1
ticket\u id=5
ticket
拥有
tenant\u id=2
的情况的影响?简单地说,数据库是否允许我将两个表中的行(每个表都有不同的
租户id
)链接在一起,从而破坏我的数据,还是保护我不受此影响


此外,上面的示例是否似乎是复合主键的“良好”使用?

如果我理解正确,TicketItem中的外键应该引用Ticket表中的id和tenant_id字段。外键应引用主键-如果仅引用id,则不会引用票证表的主键,因为票证表包含同时包含id和租户id字段的复合键

如果TicketItem中有一个外键引用了票证表的主键(id和tenant_id),那么您将无法在TicketItem表中插入/更新票证表中没有相应id+tenant_id记录的记录(这是您想要的)

股票价格: 外键应该引用ticket\u id->ticket.id和tenant\u id->ticket.tenant\u id


就复合键的“良好”使用而言,这取决于您的设计/需求,但并不存在任何“不好”的地方

如果我理解正确-TicketItem中的外键应该引用Ticket表中的id和tenant_id字段。外键应引用主键-如果仅引用id,则不会引用票证表的主键,因为票证表包含同时包含id和租户id字段的复合键

如果TicketItem中有一个外键引用了票证表的主键(id和tenant_id),那么您将无法在TicketItem表中插入/更新票证表中没有相应id+tenant_id记录的记录(这是您想要的)

股票价格: 外键应该引用ticket\u id->ticket.id和tenant\u id->ticket.tenant\u id


就复合键的“良好”使用而言,这取决于您的设计/需求,但并不存在任何“不好”的地方

如果您的
Ticket
表在
(TicketID,TenantID)
上有一个主键,那么引用
Ticket
表的任何表也必须同时引用两列,例如

TicketItem(TicketID,TenantID) ==> Ticket(TicketID,TenantID)

您不能仅引用(复合)主键的一部分,例如,您不能在
TicketItem
中引用
Ticket
表-您需要在引用它的每个外键中同时引用复合主键的两个部分(在我看来,复合索引的一个主要缺点是它使连接变得繁琐)

如果您的
票证
表在
(TicketID,TenantID)
上有一个主键,那么任何引用
票证
表的表也必须同时引用两列,例如

TicketItem(TicketID,TenantID) ==> Ticket(TicketID,TenantID)
您不能仅引用(复合)主键的一部分,例如,您不能在
TicketItem
中引用
Ticket
表-您需要在引用它的每个外键中同时引用复合主键的两个部分(在我看来,复合索引的一个主要缺点是——它使连接变得麻烦)

“其中id=5的票据的租户id=2”

基于该措辞(“票据”),是否只有一张id=5的票据?如果是,那就是您的主键,使用租户id生成复合密钥只会让事情变得更麻烦

如果您可以有多个id=5,那么您可以使用复合密钥,是的,它需要正确匹配这两个密钥,以便引用工作。

“其中id=5的票证具有租户id=2”

基于该措辞(“票据”),是否只有一张id=5的票据?如果是,那就是您的主键,使用租户id生成复合密钥只会让事情变得更麻烦


如果您可以有多个id=5,那么您可以使用复合键,是的,它需要正确匹配这两个id,以便引用工作。

谢谢Mark+1。显然,关于复合主键,我还有很多要学习的内容。这是否意味着
ticketim
的外键本身就是一个复合键?同时,这是否意味着每个表中都可以有相同的复合主键(
tenant\u id
id
)当我试图将
TicketItem
tenant\u id=2
链接到
Ticket
tenant\u id=1
链接时,数据库会抛出一个完整性错误?我想我问这些问题的原因是我没有看到复合主键的值。@mark\s-还有,你会不会避免使用大部分的复合字段(包括像这样的多租户)@orokusaki:默认情况下,我总是尽量避免使用复合键-它们很难使用,对性能有负面影响,而且它们只是一种痛苦。除非我有非常令人信服的理由不这样做,否则我总是使用单列键-如果没有自然键,我会使用代理
INT-IDENTITY
。@marc_:,“您不能仅引用(复合)主键的一部分”。实际上,您可以。如果ticket.id被声明为唯一的,您可以单独引用ticket.id,即使主键是(id,tenant\u id)@catcall:好的,是的-如果你能将PK的某些部分定义为唯一的,那么你可以单独引用它。但是这是一个黑客攻击-你需要做这个实验