这是 3NF 中的一个好的数据库设计吗?

Is this a good database design in 3NF?

我试图通过在 MySQL 中创建电影院数据库来了解数据库的工作原理。我创建了以下需求并尝试根据 3NF 绘制我的 ER 图。很多资源都说我应该使用关联表,所以我尝试这样做,但我不确定我是否正确理解了它们之间的关系。这是满足需求的良好数据库设计吗?这些关联是否正确? enter image description here

要求:

• 一个人可以是员工或客户。
• 员工也可以是客户。
• 员工可以在多个剧院工作。
• 剧院有很多放映室(每个剧院的放映室数量不同)。
• 放映室可以有不同的座位安排/容量/配置。

示例:
Table: Screen_Rooms

| room_id (PK)   | theater_id (PK, FK) | capacity | rows | seats |
|----------------|---------------------|----------|------|-------|    
|1               |0001                 |10        | 2    |5      | 
|2               |0001                 |15        |5     |3      | 
|1               |0002                 |10        |5     |2      |
|2               |0002                 |20        |4     |5      |  


Table: Seat
| theater_id (PK, FK)   | room_id (PK, FK) | seat_id (PK) | seat_row | seat_number |
|-----------------------|------------------|--------------|----------|-------------|    
|0001                   |1                 |A1            |A         |1     
|0001                   |1                 |A2            |A         |2 
|...                    |                  |              |          | 
|0001                   |2                 |E5            |E         |5  

• 放映室有放映时间。他们一次只能放映一部电影,但可以全天放映多部电影(即上午 8 点蜘蛛侠和中午 12 点罗宾汉)。
• 电影可以有很多放映时间。
• 电影可以有多种类型。
• 电影只能有一位导演,但可以有多名演员。 • 导演可以是演员。
• 客户可以做很多销售。
• 客户可以为销售支付多种款项,但只能以一种方式支付(即现金或银行卡,不能同时支付)。
• 员工可以做很多销售(即卖票)。
• 可以销售多张门票。
• 有不同的票种(儿童、成人、老人、军人)。
• 每张票都分配了一个电影座位,在房间里,在剧院里。

虽然我不会做一个完整的,但我会尝试给出一些例子来规范化。你所拥有的一些东西很接近。你可能有很多剧院,从那个开始。

Theater
TheaterID (PK, ex integer, auto-increment)
TheaterName
Location, address, phone, etc

在每个剧院内,您有很多屏幕...每个屏幕都是一个房间。但是拥有多个影院,您需要将每个屏幕绑定到其特定的影院。例如:剧院 A 可能有 5 个屏幕,剧院 B 可能有 11 个,等等

Screen
ScreenID (PK, ex integer, auto-increment)
TheaterID (FK, link to which theater it is)
Capacity, Seats, Rows

现在,根据您的座位table

Seat
SeatID (PK, integer, auto-increment)
ScreenID (FK, link to screen.  From Screen, you know the Theater)
SeatRow    (constraint on Seat Row + Number for uniqueness to prevent duplicates)
SeatNumber

所以此时,只需一个 SeatID,您就知道显示哪个屏幕以及它显示的剧院

现在开始放映的电影

Movie
MovieID (PK, integer, auto-increment)
MovieName

现在您拥有了所有屏幕和可用的电影。现在你需要知道有哪些放映。

ShowTimes
ShowTimeID (PK, integer, auto-increment)
ScreenID (FK to screens, which also then gives you the specific theater)
MovieID (FK to Movie)
BeginTime
EndTime

现在供人买票

Ticket
TicketID (PK, integer, auto-increment)
ShowTimeID (FK to ShowTimes, which gives you the screen, theater )
SeatID (FK to Seat which also gets you to screen, theater )
TicketType (for the age groups)

因此,正如您在此处看到的那样,每个 table 都有一个主键,这将您与其他一切联系在一起。不处理表示主键的复合键(多列),而是处理简化连接的特定唯一 ID。 table 的“ID”键的 table 上下文如上

Table    PK
Theater  TheaterID
Screen   ScreenID
Seat     SeatID
etc

因此,如果您在 table 中看到一个非此用途的 ID,您就知道它是外键,但它也表明它来自哪个 table

Foreign Key        To Primary Table
Screen.TheaterID   Theater.TheaterID
Seat.ScreenID      Screen.ScreenID

您至少有 3 个“实体”表:Person、Theater、ScreenRoom。它们在“列”中具有合适的属性。 Person 和 Theatre 之间可能存在多对多关系。 ScreenRoom 可能需要对其引用的剧院的引用。

至于 nNF,我不能说,那个表示法是在我建表很久之后发明的。