0

我有四个表(A、B、C、D),其中 A 是与 B 和 C 的一对多关系的父级。C 和 D 是与表 D 的一对多关系的父级。从概念上讲,这些的主键表可以是:

  • 答:援助
  • B: Aid, bnum (外键指向 A)
  • C:aid,cnum(外键指向A)
  • D:Aid、bnum、cnum(带有 B 和 C 的外键)

其中“num”列根据关系中的每个父 id 而不是每条记录自动递增。我在以前的应用程序中使用了这种方法,这不是问题,因为 B 和 C 记录的创建是通过顺序过程通过“select max()”查询生成新的“num”值来完成的。我从未对这种方法感到真正满意,但它完成了工作。

对于我现在正在处理的特定情况,表 A 和 B 中的记录由用户输入,因此自动生成 id 不是问题。对于表 C 和 D,这些表中的记录是由多个并发批处理生成的,因此需要以某种方式生成它们的标识符。我列出的先前方法不适用于竞争条件。

请注意,这是针对 Oracle 数据库的,因此我将使用序列而不是自动递增列。

鉴于上述约束,您将如何设计表来表示 A、B、C 和 D,以便正确执行实体之间的关系并且不需要应用程序代码生成任何标识符?

4

2 回答 2

0

序列或自动编号应始终由数据库系统生成,而不是由应用程序生成。对于 MSSQL,这可以使用存储过程并从存储过程返回“select @@identity”来为应用程序提供插入行的 ID。

序列非常适合imo 主键,但是有些阵营崇拜“自然键”之神。

存储在表中的数据的含义以及关系的含义对于充分回答您的问题很重要,但关系可以允许级联删除。

就个人而言,我会在每个表中创建主键序列,并允许不属于主键的外键。您将通过主要对象(如员工、商品、商店)定义您的表,然后它们之间的关系将由组合组成因此商店中的员工将有一个表“storeemployee”,主键将是 empid , storeid 没有定义序列。通常,我会从对象(始终具有主键序列)和对象之间的关系(使用其他表的 ID 作为组合主键)来考虑它。

希望有帮助!

编辑:我应该补充一点,这很好地允许了钻石关系。想想“商店”和“员工”。一张表可以是 storeemployees,另一张表可以是“storesales”。两者都可以识别商店和员工,但它们的含义截然不同。一个是工作时间,另一个是销售额。

于 2008-12-10T20:28:21.970 回答
0

如果我理解正确,您可能有一个解决方案

Table A
-------
100
101
102

Table B
-------
100 1
100 2
101 1

Table C
-------
100 1
100 2
101 1


Table D
-------
100 1 1
100 2 1
100 1 2
101 1 1

等等

现在,'num' 值是否很小并且在无间隙序列中是否重要?如果没有,那么也只需使用序列。所以你可能会得到

Table B
-------
100 29125
100 29138
101 29130

Table D
-------
100 29125 401907
100 29138 404911
101 29130 803888

我会为 bnum 和 cnum 使用单独的序列。在选择时,您可以(如果需要)使用类似的东西

SELECT AID, 
      RANK(BNUM) OVER (PARTITION BY AID ORDER BY BNUM) bnum_seq,
      RANK(CNUM) OVER (PARTITION BY AID ORDER BY CNUM) cnum_seq
于 2008-12-10T21:52:07.403 回答