困惑于如何在我的场景中应用外键概念

时间:2015-08-18 08:47:38

标签: sql sqlite

我有一个名为Receipt的数据库表,如下所示:

enter image description here

  • 付款
  • 发票
  • custom_field
  • 组织

是独立的表格

约束是每张收据的不能超过上述中的任何一个。这意味着每张收据将有一个付款条目,一个发票条目,一个custom_field和组织条目。

现在我认为我可以删除上面提到的所有列名,而是将_id作为我的收据表的主键和与所有其他表的外键相同的_id。

在上面的结构中,我也很困惑,如果我采用上述结构,我应该如何为 - payment - invoice - custom_field - 组织生成唯一值。但是如果我选择使用后者,则主键和外键将自动生成并且是唯一的。我也很关心编辑。你有什么建议吗?

以下是我的结构:

enter image description here

2 个答案:

答案 0 :(得分:2)

约束是,对于每张收据,不能多于上述收据中的任何一个。

我的错,因为快速阅读。

更新:一对多

您在此处拥有的是ONE-TO-MANY relationship,因此简单的收据可以来自0(或1 ??是强制性的,其他每个表都与receipt相关联? ?)与N相关userspaymentorganization等...

注意: 如果每个用户只能收到一张收据:11,则需要ONE-TO-ONE relationship

如何解决?
你需要改变你的愿景,你在receipt表中有外键,你必须在其他表中有外键:

user
|-- id
|-- email
|-- other attributes
|-- receipt_id   // foreign key refering to a single receipt.

然后您的用户表将有额外的字段

user_id email     .....   receipt_id
1       a@a.com   others  1
2       b@b.com   others  1
3       c@c.com   others  2

您可以执行以下选择:

SELECT * FROM USERS WHERE receipt_id = 1

输出:

1       a@a.com   others  1
2       b@b.com   others  1

加入查询(选择收据并获取所有相关用户):

SELECT * from receipt r JOIN user u where r.id = u.receipt_id; 

MANY一对多

这意味着您需要一个联接表来映射many-to-many relationship

让我们向用户解释:

一个食谱可以引用多个用户(实际上,不同的用户可以访问此食谱,或者各种用户制作此食谱)。

你需要一个表recipe_users只有2个字段 FOREIGN KEYS

recipe_users
|---- recipe_id    // FK of recipe table
|---- user_id      // FK of user table

然后你可以用不同的用户推荐一个食谱

recipe_id    user_id
1            1
1            2 
1            3

或者为每个用户提供任意数量的食谱,

recipe_id    user_id
1            1
2            1 
3            1

答案 1 :(得分:2)

乔迪是对的,他说对了。只有我不认为许多关系适用于原始问题,因为它说" 不能多于一个......"

  

约束是每个收据不能超过一个   任何来自上面的。对于每张收据,这意味着一个   付款条目,一个发票条目,一个custom_field和组织   条目。

所以,对于每个收据:

  • 一次付款。

  • 一张发票。

  • 一个自定义字段

  • 以及更多'扩展'等等到你需要的收据表。

如果我理解正确,你可以在纯理论中将所有这些专栏放在一个单一的"大"有很多列的表格,当然在其他原因上也会出于丑陋和糟糕的情况。但是请注意,如果你只有一张桌子,你也可以拥有相同的主键,这是你似乎已经问过的东西,但也是你可能并不想要的东西。

如果你想对这样一张只有一张大桌子进行反规范化。到收据,发票,自定义领域等...然后收据表将有一个主键(比如说' ID')以及任何'扩展'和子表将有他们的主键(也可以说' ID')。

我们走了:

Receipt.ID,Invoice.ID,CustomFields.ID,Payment.ID等......

请记住,所有这些ID都与收据有关。 Invoice.ID和Receipt.ID 不得以任何方式相同

你需要什么'绑定'这些孩子中的任何一个孩子都是其父母的收据'是一个专用列(比如说' ReceiptID'),它是外来键到Receipt.ID。

现在作为最后一步,如果您在子表中的ReceiptID上定义UNIQUE KEY或UNIQUE INDEX,它将确保您最多可获得1次付款,最多1份发票等任何给定收据。

例如,如果将来您需要为收据或多个付款信息获取多个自定义字段,您只需将customfield表中的UNIQUE约束更改为简单的非唯一INDEX即可完成了。

由于声誉低,我无法发布图片。 我希望我能说清楚。