是否应将公共数据模式分成自己的sql表?

时间:2015-12-11 14:22:08

标签: sql database database-design

使用类型的键将多个表的公共子集分离到其自己的表中是否有优先权?

实施例: Hipmunk允许您搜索

的“旅行细节”的航班
{
   departure_location: Orlando,
   destination_location: Miami,
   departure_date: 2016-05-05,
   return_date: 2016-05-10
}

搜索后,有一个最近的搜索跟踪器,您可以将航班保存到“我已保存的航班”中。此外,如果您预订航班,那么可能还有一个记录。因此,以下表格将共同具有“旅行细节”以及其他一些位。

因此有必要复制所有表中的列或具有此公共对象的公用表。应该所有3个表都具有from,to,departure,arrival或者是否有必要将其抽象为trip_details表,然后具有a,to,arrival,departure,type。类型将是搜索,保存,预订的枚举。

我被要求提供一些样本表,所以这里是

方法1

recent -> id,from,to,departure,return,user_id
saved  -> id,from,to,departure,return,user_id,flight_id
booked -> id,from,to,departure,return,user_id,flight_id,confirmation_number,payment_type... etc

方法2

trip_details -> id,from,to,departure,return,user_id, type(recent,saved,booked)

recent -> id, trip_details_id, user_id
saved  -> id, trip_details_id, user_id, flight_id
booked -> id, trip_details_id, user_id, confirmation_number, payment_type... etc

注意: 三个表中永远不会共享旅行详细信息行。方法2不会减少冗余数据

修改 为了帮助澄清,这些不是我的表,我试图弄清楚这一点。也许编程的一个例子会有所帮助。 请不要过于沉溺于实现细节,因为我正在试图找出问题“如果3个表都有5个相同类型的列,并且在概念上表示对象应该'对象'存在它自己的表?即使将它移动到自己的表也不会减少数据冗余?“

var recentSearch = {
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }
}

var savedSearch = {
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }
}

var booked = {
    flight_id: 1234,
    confirmation_number: 3456,
    book_date: '2015-12-12'
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }

}

2 个答案:

答案 0 :(得分:0)

通常,您应该只在所有表中的每个数据单元中表示一次。例如,如果您希望用户预订航班,您可以使用三个表格:

用户,

飞行,

预订,

用户应包含与用户相关的所有数据(姓名,密码,地址等)。

航班应包含与航班相关的所有数据(飞机,起飞时间,目的地等)。每个飞机旅程在表格中都有一行来描述它。

然后预订将保留所有已保存的航班信息,并引用其他两个表(因此它必须包含userId和flightId作为foriegn键,但之后您可以根据需要添加其他信息)。

预订表也将作为已保存的航班列表加倍。

编辑:澄清一下,如果您想要保存未预订航班的航班,您有两种选择。 1)为保存的航班单独制作表格。 2)在预订/旅行表中添加一列,指示是否已预订或保存航班。

我个人会使用选项2,除非与常规预订相比,有可能存在大量已保存的搜索。

EDIT2:你应该重新设计这个数据库。你有三个表,都存储相同的信息。 “最近”和“已保存”没有理由成为单独的表格,或者根本就没有“最近”的表格。

尝试重新设计上述模式。因此,每个航班应该在您的数据库中只代表一次,每个用户只代表一次,然后预订的航班将是一个只有用户唯一身份证和航班唯一身份证的表。

如果您想在不预订的情况下保存航班,您可以复制预订航班表并将其称为已保存的航班,或者只是将它们添加到同一个表中,其中包含一些属性,用于确定航班是预订还是仅保存。

我在这里看到的最大问题是你的所有表都包含属性(from,to,departure和return)。所有这些都可以保存在一个表中,并使用单个属性(flight_id)进行跟踪。

即使你想保存已保存的,最近的和预订的表,你也可以这样做。目前,您有四个属性出现在三个表中,如果信息重复,这应该只是一个属性。

简短回答:

这样做:

航班(id(pk),出发时间,从,到,返回)

用户(id(pk),名称等)

近期(id(pk),User_id(fk),Flight_id(fk))

预订(id(pk),User_id(fk),Flight(fk),confirmation_no等)

这应该解决99%的问题。您将通过查询数据库而不是按照您的方式来处理其余功能。

答案 1 :(得分:0)

首先,是的,一般的想法主要是尽可能减少数据冗余/重复数据。

但是有一些情况就像你提出的那样,让我们​​总结一下,并告诉我在某处的解释是否错误:

有三个地方 1.旅行细节 2.我保存的航班 3.预订航班

此处的行程详情是可用行程的一般搜索,您已将其保存在表格" Trips"

我保存的航班是一个选项,用户可以保存该旅行,以便他们不必搜索。

直到最好的方法:
在" My_Saved_Flights"表保存" trip_ID"来自"旅行"包含" saved_on_date"等数据的表和" User_ID"
现在,当您显示我的已保存航班时,您可以使用LEFT JOIN获取行程及其当前价格和状态。

现在第三个是预订航班
这是历史上的事情,所以你需要看到正常的旅行时间确实会在某一天或其他地方发生变化吗?如果他们这样做,你需要存储这些细节,否则你可以存储ID。

我更喜欢部分存储,即存储在这样的单个文本列中有更改机会的东西

{departure_location: Orlando,destination_location: Miami,departure_date: 2016-05-05,return_date: 2016-05-10}

我希望我有所帮助