Goo*_*ber 0 t-sql sql-server database-relations
我有3个数据库表.一个是图像,另外两个是人物和地方.由于每个人可以拥有许多图像,并且每个地方都可以拥有许多图像,因此我希望人与图像以及地点和图像之间存在一对多的关系.
外键是否必须与主键名称相同?或者我可以在images表中调用一些通用的外键,例如"PKTableID".这样我只需要一个图像表.
非常感谢.
问候,
想要只有一个图像表的原因是因为每个图像只引用一个其他表.除此之外,我在这里使用了两个表的示例,我将使用的实际数据库将有20个表,所以我想知道是否仍然可以使用单个图像表来实现20个一对多的关系?
编辑
如果一个图像仅由二十个表中的一个拥有,则此设计可能有效:
People (PersonId, Name)
Places (PlaceId, Name)
Dogs (DogId, Breed)
Doors (DoorId, Height, Width)
Images (ImageId, ImageBinary, OwnerId, OwnerTable)
Run Code Online (Sandbox Code Playgroud)
其中OwnerTable是OwnerId所属的表的名称或代码.
这样可以在图像表或20个关联表中保存20个FK.然后,在联接中,您将指定OwnerTable,具体取决于您要加入的表.
您需要为Ids使用可转换类型(例如,TINYINT,SMALLINT和INT),并且最好为所有类型(例如,INT)使用一种类型,并且您必须通过触发器或其他代码自己管理参照完整性.
/编辑
你需要5个表,而不是3个表:
People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary)
ImagesPeople (ImageId, PersonId)
ImagesPlaces (ImageId, PlaceId)
Run Code Online (Sandbox Code Playgroud)
您可以随意调用字段.People.Id,ImagesPeople.PersonId等
但你不能做的是这样的事情:
People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary, PlaceOrPersonId)
Run Code Online (Sandbox Code Playgroud)
好吧,你可以,但数据库不会帮助你强制执行关系,或告诉你FK属于哪个表.你怎么知道的?有一些讨厌的解决方法,比如错开id增量,向Images添加类型列或使用GUID.
或者:
Things (ThingId PK, Type)
People (ThingId PK/FK, Name, Age)
Places (ThingId PK/FK, Name, LatLon)
Images (ImageId PK, ImageBinary, ThingId FK)
Run Code Online (Sandbox Code Playgroud)
你也可以把图像变成"事物".有时你会看到这样的设计.它确实为您提供参照完整性,但不是类型排他性.您可以在人物,地点和图像中拥有相同的ThingId,数据库也不会关心.你必须自己编写规则.
编辑:在Cylon Cat的建议中,方案4:
People (PersonId, Name)
Places (PlaceId, Name)
PeopleImages (PeopleImageId, ImageBinary)
PlaceImages (PlaceImageId, ImageBinary)
Run Code Online (Sandbox Code Playgroud)
在这里,图像由一个人或地方独家拥有.与版本2类似,但具有声明的外键.与5表设计相比,它可能具有一些性能优势,因为需要更少的连接.你将"Image"作为一个独特的实体丢失,取而代之的是"PeopleImage"和"PlaceImage".
| 归档时间: |
|
| 查看次数: |
1045 次 |
| 最近记录: |