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的某些部分定义为唯一的,那么你可以单独引用它。但是这是一个黑客攻击-你需要做这个实验