【问题标题】:Database Design (Oracle) - modelling business logic数据库设计 (Oracle) - 建模业务逻辑
【发布时间】:2016-10-02 18:08:41
【问题描述】:

我面临以下困境。

考虑下面的代码 - 这是我为描述问题而设计的 - 不是真正的实现,我省略了一些检查约束和 NOT NULL 以避免混淆图片。

CREATE TABLE Theater_Halls(
    thha_id NUMBER(2) CONSTRAINT pk_thha_id PRIMARY KEY,
    thha_name VARCHAR2(30) CONSTRAINT nn_thha_name NOT NULL,
    thha_no_of_seats NUMBER(4) CONSTRAINT ch_thha_no_of_seats CHECK (thha_no_of_seats > 0)
        CONSTRAINT nn_thh_no_of_seats NOT NULL
);     
CREATE TABLE Seats (
    seat_id NUMBER (8) CONSTRAINT pp_seat_id PRIMARY KEY,
    seat_no NUMBER (4) CONSTRAINT ch_seat_no CHECK (seat_no > 0),
    thha_id NUMBER(2) CONSTRAINT fk_seat_thha_id REFERENCES Theater_Halls(thha_id)
);


CREATE TABLE Events ( -- each event has a hall in theater associated with it
    evnt_id NUMBER(4) CONSTRAINT pk_evnt_id PRIMARY KEY,
    evnt_name VARCHAR2(30) CONSTRAINT nn_evnt_name NOT NULL,
    thha_id NUMBER(2) CONSTRAINT fk_evnt_thha_id REFERENCES Theater_Halls(thha_id),
    evnt_date TIMESTAMP CONSTRAINT nn_evnt_time NOT NULL
);

CREATE Table Users (
    user_id NUMBER(10) CONSTRAINT pk_user_id PRIMARY KEY
    );

CREATE TABLE Bookings (
    bkng_id NUMBER(10) CONSTRAINT pk_bkng_id PRIMARY KEY,
    evnt_id NUMBER(10) CONSTRAINT fk_bkng_evnt_id REFERENCES Events(evnt_id),
    seat_id NUMBER(8) CONSTRAINT fk_bkng_seat_id REFERENCES Seats(seat_id),
    user_id NUMBER(10) CONSTRAINT fk_bkng_user_id REFERENCES Users(user_id),
    bkng_price NUMBER(6,2) CONSTRAINT nn_bkng_price NOT NULL,
    CONSTRAINT un_evnt_seat_user UNIQUE (evnt_id, seat_id)
);

现在,这个实现在某种意义上满足了标准,它保存了没有(看起来)异常的数据。

不过,我有两个问题。

  1. 如果它保留在上面的表格中,最初创建时 user_id 为 NULL,一旦在应用程序中进行预订,user_id 将被填充,并且程序将跟踪预订的座位 (user_id NULL)
  2. 或者它是创建中间表的更好方法,例如

    CREATE TABLE Events_Seats (
    evse_id NUMBER(8) CONSTRAINT pk_evse_id PRIMARY KEY,
    evnt_id NUMBER(4) CONSTRAINT fk_evse_evnt_id REFERENCES Events(evnt_id),
    seat_id NUMBER(8) CONSTRAINT fk_seat_id REFERENCES Seats(seat_id),
    evse_price NUMBER(6,2) CONSTRAINT nn_evse_price NOT NULL,
    CONSTRAINT un_evnt_seat_user UNIQUE (evnt_id, seat_id));
    

    然后将外键链接到 Bookings,其中 Bookings 表将是“事务性的” - 这意味着,当为给定事件选择座位时,将插入新行。就业务逻辑建模和潜在错误/无效数据而言,给定方法有什么优势吗?

【问题讨论】:

    标签: database oracle database-design business-logic


    【解决方案1】:

    我认为您不需要EVENT_SEATS 表。您甚至不需要为userid 填充BOOKINGSNULL。只需将 Bookings 表留空即可。 您可以使用以下方式查询您可能的活动预订:

    select e.EVNT_NAME as EventName, s.seat_no as AvailableSeat
    from  events e
    join seats s
    on s.thha_id = e.thha_id
    left join Bookings b
    on b.seat_id = s.seat_id and
       b.evnt_id = e.thha_id
    where  e.evnt_id = 1 and
       b.bkng_id is null
    

    当创建预订记录时,b.bkng_id is null 将从可能的预订列表中删除结果。

    【讨论】:

    • 从技术上讲,是的,它可能只是从可用预订列表中删除,但是,如果我没记错的话,我们会丢失历史数据,所以像 Users_Bookings 这样的新表都需要要创建或记录此类更改的存档表将需要设置。对预订的任何修改或取消预订都需要重新插入该行。
    • 当然。如果您需要历史数据,那么您应该创建它。另一个故事是处理 Theatre_hall 下的座位变化。每次添加或删除新座位时,您都需要创建新的 Theatre_hall 条目,因为您过去的预订会受到影响。您需要处理您真正想要处理的事情以及不需要的事情......
    • 非常感谢。答案 + cmets 阐明了在设计过程中要考虑的事项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2013-02-18
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    相关资源
    最近更新 更多