Sql 规范化数据库表

Sql 规范化数据库表,sql,database-normalization,Sql,Database Normalization,我是一个数据库设计新手,我正在尝试一个测试用例来跟踪学生。 在下图中,学生可以在学校或俱乐部。为此,我在LocationId上创建了一个全局id,作为学生所在位置的全局id。 但问题是,我依靠TypeId来决定它是俱乐部还是学校。 因此,在我的数据访问查询中,我必须创建案例。伪代码是: if TypeId == 1 search in club for the LocationId and get the clubId. else if TypeId == 2 search in school

我是一个数据库设计新手,我正在尝试一个测试用例来跟踪学生。 在下图中,学生可以在学校或俱乐部。为此,我在LocationId上创建了一个全局id,作为学生所在位置的全局id。

但问题是,我依靠TypeId来决定它是俱乐部还是学校。 因此,在我的数据访问查询中,我必须创建案例。伪代码是:

if TypeId == 1
search in club for the LocationId and get the clubId.
else if TypeId == 2
search in school for the LocationId and get the schoolId.
我怎样才能摆脱这些情况,仍然保持规范化规则

非常感谢你的阅读。欢迎提出任何意见。
你好

这似乎是表继承的一种情况,解决方法不止一种。使用
LOC\u CONTAINER
的解决方案不起作用(正如您所注意到的),因为它需要外部代码来执行检查


请看一下关于继承的内容。例如,您可以将
SCHOOL
CLUB
表统一到一个名为
PLACE
的表中,或者在表
STUDENT
中同时包含
SCHOOL
CLUB
列,并限制其中一列必须为
NULL

不确定是否需要
locu CONTAINER
表完全您可以使用
CLUB
SCHOOL
左键联接
,只使用您需要的字段。您的意思是完全删除LocationId吗?你能在解决方案may中写下这个查询吗?把你的学校表和俱乐部表合并在一起,并添加额外的列作为类型来区分它们,在这种情况下你也可以删除LOC_容器。合并
学校和
俱乐部是我的第一次尝试,但后来就好像“好吧,也许以后它们会有所不同”。获取id的查询将是,例如,
select student.id,coalesce(CLUB.id,SCHOOL.id)from student left join CLUB.id=student.location\u id left join SCHOOL.id=student.location\u id
@keltar you is right keltar,合并不是一个选项,因为这两个表以后会有所不同,我还想在使用ODATA wcf数据服务时使用FK而不是join,因为它不支持join,而是支持使用FK进行“扩展”。但我想我想得太多了:)谢谢,但我不能合并学校和俱乐部,因为以后会有所不同,加入是其他同事提到的一个选项,但表之间的关系也会丢失,这可能是客户端使用dataservice所需的。好的,看看我链接到的答案中提供的类表继承案例。在这种情况下,你有学校和俱乐部的主键引用一个公共表,这与你的
LOC\u容器
没有什么不同。再次感谢你,我查看了你的类表继承链接,它非常接近于解决我的问题,我唯一的问题是,例如,X有policyId,如何知道它是否有“property\u address”或“property\u address”“车辆注册号”,一种方法是在所有子表中搜索policy_id,但我猜这是一种糟糕的方法。在我的例子中,它反映在知道locationId如何可能知道这是在学校还是在俱乐部。我希望你得到d点。你可以
连接
表并测试
NULL
值,或者在这一点上使用编程逻辑。无论如何,您都需要UI端的逻辑,因为UI可能会根据学生是在学校还是在俱乐部而略有不同。是的,我现在正在做与您提到的相同的事情,但我只是想知道,如果您说的是10个子表而不是2个子表,那么UI逻辑会变得更混乱,我想DBA可能会以某种方式避免这种情况。谢谢你的回答和评论,因为它帮助我了解不同的案例。对于这件事,我将你的解决方案作为答案。