【问题标题】:Make sure no duplicates in "parent" of parent确保父级的“父级”中没有重复项
【发布时间】:2020-12-14 14:56:26
【问题描述】:

我正在使用 MariaDB 和 PHPMyAdmin,但我的代码都是中性的,很高兴切换到 Postgres 或其他任何东西,但这应该足够直截了当。我还没有设计任何东西,就在最佳方法之后。

我有 3 个描述场所的数据库表。假设是一家酒店。

这家理论上的酒店拥有多个场所 - 2 间餐厅和一个酒吧。每个都有几个不同的房间/区域。这些房间里有可供顾客坐的桌子。

在 SQL 中,我想表格应该是这样的

Venues
Venue ID Venue Name
1 Restaurant 1
2 Restaurant 2
3 Bar
Rooms
Room ID Room Name Parent Venue (foreign key)
1 Patio 1
2 Function Room 1
3 Alcove 3
4 Private Dining 2
Tables
Table ID Table Name Parent Room (foreign key)
1 Table 1 1
2 Table 2 1
3 Table 3 1
4 Table 4 2
5 Table 1 3
6 Table 2 3
7 Table 3 3
8 Table 4 3
9 Table 1 4
10 Table 2 4
11 Table 3 4

我希望数据是正确的:p

我想要做的是定义一个关系,而如果它已经存在于该场所,则不可能添加一个表名。桌子在什么房间里并不重要。

例如,如果我要添加另一个“Table 4”,如果它进入到 Room 4,它会成功进入,因为 Room 4 属于 Restaurant 2,它还没有“Table 4”。但是,如果它被输入到任何其他房间,它会失败,因为餐厅 1 和酒吧已经在他们的一个房间里有一个“桌子 4”。

现在在服务器端代码中这很容易检查,因为我可以执行多个查询或连接或无数其他方式,但是我想知道如何直接在 SQL/PhpMyAdmin 中执行此操作。我在 MyAdmin 中找不到路。

干杯

【问题讨论】:

    标签: mysql sql database mariadb


    【解决方案1】:

    我的建议是在表中冗余地包含父场地。所以tables 会有额外的列:

    venueID
    

    rooms 会有一个唯一的约束(这是多余的):

    alter table rooms add constraint unq_rooms_venueId
        unique (venueId, roomId);
    

    那么表就会有一个唯一的约束:

    alter table tables add constraint unq_table_venueId
        unique (tableName, venueId);
    

    这解决了问题,而无需求助于触发器。

    【讨论】:

    • 是的,这是我最初的想法,只是不知道是否有一种简单的方法可以完成额外的步骤。谢谢!
    • @JoshDredge 。 . .这实际上是“简单”的方式。另一种方法涉及触发器。
    • 我很乐意避免,我会尽快回答!
    【解决方案2】:

    我要做的是从技术 ID 切换到复合自然键。您可以为此使用数字(即,给场地一个数字,一个房间一个数字,也许是一个桌子一个数字)或使用名称,如果这些保证不会改变。例如:

    venues
    (
      venue_name,
      primary key (venue_name)
    );
    
    rooms
    (
      venue_name,
      room_name,
      primary key (venue_name, room_name),
      foreign key (venue_name) references venues (venue_name)
    )
    
    tables
    (
      venue_name,
      room_name,
      table_name,
      primary key (venue_name, room_name, table_name),
      foreign key (venue_name, room_name) references rooms (venue_name, room_name),
      unique constraint (venue_name, table_name)
    )
    

    (如果使用键名并且您的表不包含除名称之外的任何其他信息,您当然可以轻松删除表venuesrooms,只保留tables 表,如果你想要的。)

    数字也一样:

    venues
    (
      venue_no,
      name,
      primary key (venue_no)
    );
    
    rooms
    (
      venue_no,
      room_no,
      name,
      primary key (venue_no, room_no),
      foreign key (venue_no) references venues (venue_no)
    )
    
    tables
    (
      venue_no,
      room_no,
      table_no,
      name,
      primary key (venue_no, room_no, table_no),
      foreign key (venue_no, room_no) references rooms (venue_no, room_no),
      unique constraint (venue_no, name)
    )
    

    【讨论】:

      猜你喜欢
      • 2015-05-31
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 2011-10-12
      • 2013-06-24
      • 2021-07-15
      • 1970-01-01
      • 2013-04-27
      相关资源
      最近更新 更多