【问题标题】:Composite Primary Key with editable part具有可编辑部分的复合主键
【发布时间】:2023-03-23 06:40:01
【问题描述】:

(6/4 编辑)

我正在设计一个数据库,其中包含有关酒店及其位置的下表(在这个问题的上下文中,假设酒店名称是唯一的):

[Hotel]    
HotelId PK
HotelName AK

[HotelLocation]
HotelId FK
HotelLocationName

(HotelId, HotelLocationName) 是HotelLocation 中的PK。同一个Hotel中不能存在两个HotelLocations和同一个HotelLocationName

一些样本数据可能是:

| Hotelid | HotelName      |         | HotelId | HotelLocationName |
----------------------------         -------------------------------
| 1       | Holiday Inn(1) |         | 1       | Reception         |
| 2       | Four Seasons   |         | 1       | Pool              |
| 3       | Holiday Inn(2) |         | 2       | Reception         |
                                     | 2       | Dinning room      |
                                     | 3       | Room 100          |
                                     | 3       | Room 101          |

要求HotelNameHotelLocationName 都是可编辑的。

因此,对于 Hotel 表,我使用生成的不可变 HotelId 并将 HotelName 作为具有唯一约束的备用键 (AK)。

我可以对 HotelLocation 表执行相同的操作,然后将其更改为:

[HotelLocation]
HotelLocationId PK
HotelId
HotelLocationName 

其中 (HotelId, HotelLocationName) 是 AK。 问题是我有更多与之相关的表,其中像 (HotelId, HotelLocationName) 这样的 FK 给了我与我不想失去的Hotel 的直接关系。

我知道我仍然可以使用与HotelLocation 的 AK 类似的 FK,但级联更新的问题仍然存在。

我想以某种方式生成HotelLocationId,以便我可以有一个(HotelIdHotelLocationId)PK,例如,为每条新记录的特定HotelIdMAX(HotelLocationId) + 1,但我如果有替代解决方案,我会更喜欢。

这种情况有什么常用的处理方法吗?

【问题讨论】:

  • 常见的方法是不要将可变字段作为表键的一部分,但我们已经过去了。酒店多久更改一次名称?也许,您只是忍受昂贵的酒店名称更新。另外,每家酒店的名称有何独特之处?不是有数百家假日酒店吗?
  • @GilbertLeBlanc 1) 我们没有过去,这就是整个问题的意义所在。 2) 是的,很可能我可以使用罕见的昂贵更新,特别是对于特定项目,但无论如何我想提出更好的东西。此外,相关字段是酒店 location 名称 3) 你是对的。
  • 为每个表修改 DDL 的脚本并不难。修改主表后,您可以引用它以将所有位置替换为其新 ID。您可以导出、修改、导入或实时执行。只要确保你有一个好的备份以防万一。无论您现在或以后“付款”。我现在就完成它,而不是每次位置变化时都这样做。
  • @Nic3500 我编辑了这个问题,因为它不是很清楚。我还在设计数据库,它没有投入生产,也没有任何数据。我的问题是关于“正确”选择 HotelLocation 表 PK。
  • 啊,好吧,那么容易多了! @GilbertLeBlanc 的评论是正确的。 PK 和 FK 不应基于可变值。以后会省去很多工作。您的模型应确保您不必因为新值而对其进行修改。只有新的特性或功能。

标签: database-design relational-database composite-key


【解决方案1】:

我想我更能理解你的问题。您有一张像这样的酒店桌子。

Hotel
-----
Hotel ID
Hotel Name
...

酒店 ID 是主键。这是一把盲钥匙,意思是它没有任何意义,除了识别酒店,比如假日酒店。它是一个整数序列,从零开始,表中的每家酒店都加一。

您还有一个 Hotel Location 表。

Hotel Location
--------------
Hotel Location ID
Hotel Location
...

酒店位置 ID 是另一个盲主键。

您创建一个关联表以将这些表联系在一起。我假设一家假日酒店可以有许多位置,因此酒店表和酒店位置表之间存在一对多的关系。

Hotel Association
-----------------
Hotel ID
Hotel Location ID
Date location established
...

主键是酒店 ID 和酒店位置 ID。这是建立两个表之间关系的表。

你还应该有一个关于酒店位置ID的唯一索引,酒店ID,这样你就可以找到该位置的酒店。

如您所见,有一些与关联有关的特征,如创建日期、更新日期,也许还有其他特征。

关联表或联结表提供表之间的关联。

【讨论】:

  • 抱歉拖了这么久。我不知道你是否理解我的问题。无论如何,我发布了答案,但我不明白,为什么我要使用联结表进行一对多关系?
  • @GiannisTsim:您不必使用关联表。如果需要,您可以在 Hotel Association 表中放置一个外键。
  • 我了解您对 HotelLocation 的含义感到困惑。我的意思是酒店内的一个位置(例如接待处、房间……),而不是酒店作为建筑物的不同位置。我认为从表关系中可以清楚地看出,但我还添加了一些示例数据以供将来参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多