2012-03-06 20 views
5

我需要存储与“项目”相关的数据,其中将存在各种不同的项目类型,所有项目都具有公共属性,然后每个类型都有其自己的附加属性。我期望这是一个共同的要求;最佳实践解决方案是什么?我们正在使用SQL Server。项目和专用项目:具有重复列,主表和详细表或多个表的多个表?

让我们用一个虚构的例子:

车辆

  • 价格
  • 型号
  • 所有者

(在我们的真实数据,会有10-15公共列)

汽车是车辆加:

  • 风格(轿车,运动等)
  • 颜色
  • EngineSize

Boat is a vehicle plus:

  • 排量
  • PortOfOrigin

...等。对于几种类型的东西。在我们的实际数据中,每种专业类型通常会添加2-5列;将有5种类型开始。我们将随着时间的推移添加类型,但可能只有总共3或4个(如果有的话)。添加类型需要开发,所以它不像“标签”可以被最终用户无条件地添加。我们假设添加一个类型将需要更改数据库和客户端层,也可能需要更改中间层。这很好。

我们会对所有物品(车辆,在上面的例子中)做很多查询;我们很少只担心特定项目类型(汽车,小船)的细节。

我看到四种方式来存储这些数据:

  1. 车,船等单独的表,有重复列。
  2. 一张表,其中包含Vehicle数据,附加Car数据的表以及附加Boat数据的表。
  3. 一个项目表,一个单独的项目属性表,每个附加属性具有一行。例如,细节的软模式。
  4. 一个表的泛型列给出的含义只有非DB代码。

查看每个:

  1. 单独的表用于汽车,船等,具有重复列。例如,大致为:

    CREATE TABLE [Cars] (
        [Id] IDENTITY PRIMARY KEY, 
        [Price] DECIMAL (19, 4), 
        [Make] NVARCHAR(200), 
        [Model] NVARCHAR(200), 
        [Owner] INT, 
        [Id] INT PRIMARY KEY, 
        [Style] NVARCHAR(200), 
        [Color] NVARCHAR(200), 
        [EngineSize] DECIMAL(19, 2) 
    ) 
    CREATE TABLE [Boats] (
        [Id] IDENTITY PRIMARY KEY, 
        [Price] DECIMAL (19, 4), 
        [Make] NVARCHAR(200), 
        [Model] NVARCHAR(200), 
        [Owner] INT, 
        [Id] INT PRIMARY KEY, 
        [Displacement] DECIMAL(19, 4), 
        [PortOfOrigin] NVARCHAR(200) 
    ) 
    

    很简单,汽车走在Cars和船只Boats去。如果我们添加更多的车辆类型,我们添加一个表格。如果我们添加另一个通用列,我们必须返回并将其添加到所有车辆表。通常可以通过所有表格的联合视图来完成对车辆的报告(注意Id栏)。

  2. 一张表,其中有Vehicle数据,一张额外的Car数据,以及一张额外的Boat数据表。例如,大致为:

    CREATE TABLE [Vehicles] (
        [Id] IDENTITY PRIMARY KEY, 
        [Price] DECIMAL (19, 4), 
        [Make] NVARCHAR(200), 
        [Model] NVARCHAR(200), 
        [Owner] INT, 
        [Type] INT  -- A type ID, e.g. "Car" vs. "Boat" 
    ) 
    CREATE TABLE [Cars] (
        [Id] INT PRIMARY KEY, 
        [Style] NVARCHAR(200), 
        [Color] NVARCHAR(200), 
        [EngineSize] DECIMAL(19, 2) 
    ) 
    CREATE TABLE [Boats] (
        [Id] INT PRIMARY KEY, 
        [Displacement] DECIMAL(19, 4), 
        [PortOfOrigin] NVARCHAR(200) 
    ) 
    

    所以每一辆车将在CarsVehicles和一个联排一排。每艘船将在BoatsVehicles和一个联排一排。如果我们添加更多的车辆类型,我们添加一个表格。报告针对一般车辆可以针对刚刚Vehicle表来完成。当检索特定的CarBoat的详细信息时,我们使用连接。

  3. 一个项目表,一个单独的项目属性表和一个附加属性的行。例如,细节的软模式。例如,大致为:

    CREATE TABLE [Vehicles] (
        [Id] IDENTITY PRIMARY KEY, 
        [Price] DECIMAL (19, 4), 
        [Make] NVARCHAR(200), 
        [Model] NVARCHAR(200), 
        [Owner] INT, 
        [Type] INT 
    ) 
    CREATE TABLE [VehicleDetails] (
        [VehicleId] INT, 
        [Name] NVARCHAR(200), 
        [Value] NVARCHAR(MAX) 
    ) 
    

    所以每次租车获取VehicleDetailsVehicles和三排一排(每一个“样式”,“颜色”和“EngineSize”)。报告主要是针对Vehicle表完成的。关于细节的报道开始变得杂乱无章。软模式有其自己的位置,主要是围绕用户定义的数据,但我认为这不是一个好的选择。只有非DB代码中给出的含义通用列

  4. 一个表:

    CREATE TABLE [Vehicles] (
        [Id] IDENTITY PRIMARY KEY, 
        [Price] DECIMAL (19, 4), 
        [Make] NVARCHAR(200), 
        [Model] NVARCHAR(200), 
        [Owner] INT, 
        [Type] INT, 
        [Detail01] NVARCHAR(MAX), 
        [Detail02] NVARCHAR(MAX), 
        [Detail03] NVARCHAR(MAX), 
        [Detail04] NVARCHAR(MAX), 
        [Detail05] NVARCHAR(MAX), 
        [Detail06] NVARCHAR(MAX), 
        [Detail07] NVARCHAR(MAX), 
        [Detail08] NVARCHAR(MAX), 
        [Detail09] NVARCHAR(MAX), 
        [Detail10] NVARCHAR(MAX) 
    ) 
    

    因此汽车数据将指定样式为Detail01,颜色以Detail02,并EngineSize到Detail03;为船,我们就会把排量在Detail01和PortOfOrigin在Detail02。同样,对于最终用户定义的模式也可能有这样的地方,但我猜测这可能不是一个好的答案,因为您可以控制数据库结构。

+0

是关系数据库严格要求?看起来像使用这个模型的文档数据库会更合适。 – Oded 2012-03-06 13:18:22

+0

@Oded:好问题。在这种情况下,是的,至少在现在,它必须存储在RDBMS中。如果我们得到足够的这些要求,也许我们会用文档数据库来扩充RDBMS。 – 2012-03-06 13:21:25

+0

“我们将随着时间的推移添加更多类型” - 向我表明选项2。软模式(EAV模型)与通用列一样,不是起动器。 – Oded 2012-03-06 13:25:24

回答

6

这取决于。

方法1是最好的情况下大多数属性将是常见的大多数类型。

方法2适用于大多数类型都不常见的情况。

方法3基本上接近1,用实体 - 属性 - 值方法来处理特定类型的属性。这种方法适用于大多数属性对大多数类型都很常见的情况,并且很难预测需要哪些附加属性 - 在需要用户创建的字段的情况下,这种情况非常普遍。

方法4是不是在任何情况下一个好主意 - 它会从元数据层的语义内容到代码层,同时保持方法的僵化1.

也有另一种可能的方法 - 一个纯粹的Entity-Attribute-Value方法(基本上是方法3和4的混合)。这通常被认为是反模式,这是由于在RDBMS上实现时产生的复杂性和较差的性能。然而,在某些情况下,这是唯一可能的方法 - 主要是,在实体关系未知的情况下。

+0

谢谢,非常合理。我刚刚加入这个信息的问题:*“给你一个想法,我们的数字会有10-15共同属性(例如,车辆数据)的顺序,和任何给定的特殊类型(车,船)将增加2-4。“*这样就表明你会倾向于选择1 ...? – 2012-03-06 13:37:09

+0

@ T.J.Crowder - 我想说你需要考虑你期望有多少额外的类型。如果是少量的,瘦为1,如果大量,瘦到2 – Oded 2012-03-06 13:39:57

+0

@Oded:谢谢,你已经强调了别的东西,我离开了这个问题。 :-)我已经添加了它。 (五种类型,开始时,大概没有超过其他三个或四个随着时间的推移。) – 2012-03-06 13:45:58

相关问题