Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-此关系可以有主键吗?_Sql_Mysql_Primary Key_Composite Primary Key - Fatal编程技术网

SQL-此关系可以有主键吗?

SQL-此关系可以有主键吗?,sql,mysql,primary-key,composite-primary-key,Sql,Mysql,Primary Key,Composite Primary Key,乐队和成员之间的关系“MemberOf”,包括成员id(Mid)、乐队id(Bid)、“StartYear”、“EndYear”和演奏的“Instrument”。Mid和Bid分别是成员关系和波段关系的外键,但在这种情况下,我很难确定“MemberOf”关系的主键 注意:如果一个成员从开始就在一个波段中,则开始年份可以为空;如果一个成员仍然在波段中,则结束年份也可以为空 在这种情况下,起始年和结束年不能用作主键,因为它们可能包含空值,但成员id和波段id的信息不足以唯一-例如,同一成员稍后返回同

乐队和成员之间的关系“MemberOf”,包括成员id(Mid)、乐队id(Bid)、“StartYear”、“EndYear”和演奏的“Instrument”。Mid和Bid分别是成员关系和波段关系的外键,但在这种情况下,我很难确定“MemberOf”关系的主键

注意:如果一个成员从开始就在一个波段中,则开始年份可以为空;如果一个成员仍然在波段中,则结束年份也可以为空

在这种情况下,起始年和结束年不能用作主键,因为它们可能包含空值,但成员id和波段id的信息不足以唯一-例如,同一成员稍后返回同一波段


这是否意味着不存在主键?谢谢。

您是对的,日期不能被视为PK的一部分,因为它们是随时间变化的数据。我认为你有两个选择:

1) 将MemberOf记录与子表(可能称为MemberOfYears)拆分为父子对,子表包含Mid、Bid和a年,父表MemberOf将变为Mid和Bid。因此,每年都会有一个成员的年度记录,该成员是该特定乐队的成员


2) 向MemberOf relationship表添加一个人工键,并将其用作主键。

日期不能被视为PK的一部分,这是正确的,因为它们是随时间变化的数据。我认为你有两个选择:

1) 将MemberOf记录与子表(可能称为MemberOfYears)拆分为父子对,子表包含Mid、Bid和a年,父表MemberOf将变为Mid和Bid。因此,每年都会有一个成员的年度记录,该成员是该特定乐队的成员


2) 向MemberOf relationship表中添加一个人工键,并将其用作主键。

一个可能的解决方案是在band启动的年份存储StartYear值。这样,您可以使用(MId、BId、StartYear)作为主键,假设成员每年只能加入和退出一次(根据您的设计建议)

要测试“原始成员”,请比较MemberOf.StartYear和Band.StartYear是否相等


否则不行,您没有有效的主键,需要添加某种类型的消歧列(JoinNumber或其他内容),这似乎是不必要的额外工作。

一种可能的解决方案是在频带开始的年份存储StartYear值。这样,您可以使用(MId、BId、StartYear)作为主键,假设成员每年只能加入和退出一次(根据您的设计建议)

要测试“原始成员”,请比较MemberOf.StartYear和Band.StartYear是否相等

否则不行,您没有有效的主键,需要添加某种消除歧义的列(JoinNumber或其他内容),这似乎是不必要的额外工作

注意:如果出现以下情况,则起始年份可以为空 这个成员从一开始就在一个乐队里

这个荒谬的要求是你最大的问题。储存一年

{BandId,MemberId,StartYear}作为主键

Bid     Mid     Start   End
  1       1      2003   2005   - α
  1       1      2004   2006   - β
  1       1      2004   2007   - γ
  1       1      2008   2011   - δ
不过,这不适合于2月份开始工作、3月份辞职、7月份重新开始工作的成员

注意:如果出现以下情况,则起始年份可以为空 这个成员从一开始就在一个乐队里

这个荒谬的要求是你最大的问题。储存一年

{BandId,MemberId,StartYear}作为主键

Bid     Mid     Start   End
  1       1      2003   2005   - α
  1       1      2004   2006   - β
  1       1      2004   2007   - γ
  1       1      2008   2011   - δ

但是,这不适用于2月份开始、3月份退出、7月份重新开始的会员。

这是一个常见问题。要了解发生了什么,我们需要将关系概念“主键”从SQL构造主键中分离出来

关系概念“主键”是表中行的唯一标识符。在表格的上下文中,乐队和成员显然是主键的一部分,成员为乐队演奏的时间段也是主键的一部分。比如说,一个成员可以在2003-2005年为一个特定的乐队演奏,在2006-2007年开始独奏生涯,并在2008-2011年重新加入他原来的乐队。表中的成员需要两个条目,两个期间各一个

理想情况下,您可以说“startYear”和“endYear”形成一个单独的“memberFor”期间列,主键是(bid、mid、memberFor),对于bid+mid的单个组合,memberFor值表示不相交的范围:即,对于两行R1、R2,R1.memberFor值不重叠或接触R2.memberFor。示例重叠:R1.memberFor=(2003-2005),R2.memberFor=(2004-2006)。触摸示例:R1.memberFor=(2003-2005),R2.memberFor=(2005-2007)

理论到此为止

实际上,SQL不支持时间段,在此上下文中,时间段具有开始和持续时间。间隔类型不合格,因为它们表示没有开始的持续时间,而日期、时间、时间戳类型不合格,因为它们缺少持续时间(忽略与当前问题无关的量化问题)。显然,您还可以通过(持续时间,结束)和(开始,结束)表示期间,在后一种情况下,您可以为开始和结束设置打开、关闭、打开-关闭或关闭-打开范围

因为SQL不支持必需的类型,更不用说必需的检查选项了,所以您必须自己进行检查,而且这样做很复杂。SQL主键只查找值的相等性。不受约束,这意味着如果在(bid,mid,start)或(bid,mid,end)或(bid,mid,start,end)上创建主键,则表中可能会出现不需要的数据,这些数据满足SQL主键,但不满足概念主键

Bid     Mid     Start   End
  1       1      2003   2005   - α
  1       1      2004   2006   - β
  1       1      2004   2007   - γ
  1       1      2008   2011   - δ
认为标记为α的行是正确的。如果SQL主键为on(bid、mid、start),则不允许标记为β的行,因为它与α重叠;γ也是如此。然而,