Database design 我如何避开这种关系数据库设计的气味?

Database design 我如何避开这种关系数据库设计的气味?,database-design,relational-database,rdms,Database Design,Relational Database,Rdms,我有一个非常简单的mediaTypes表,其中包含以下列: id string name string 每个mediaType记录可以有许多“位置”,可以很容易地设计如下: 安置 id string mediaTypeId string (links to mediaTypes.id) name string detail_col_1 detail_col_2 ...etc id string mediaTypeId string (links to mediaTypes.id)

我有一个非常简单的mediaTypes表,其中包含以下列:

id string
name string
每个mediaType记录可以有许多“位置”,可以很容易地设计如下:

安置

id string
mediaTypeId string (links to mediaTypes.id)
name string
detail_col_1
detail_col_2
...etc
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
但是,根据媒体类型的不同,放置可以包含不同的细节,因此,如果我以这种方式设计模式,可能最终会得到许多可为空的列

为了解决这个问题,我可以有一个aPlacements表和一个bPlacements表来匹配每种不同的媒体类型

a位置

id string
mediaTypeId string (links to mediaTypes.id)
name string
detail_col_1
detail_col_2
...etc
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
b位置

id string
mediaTypeId string (links to mediaTypes.id)
name string
detail_col_1
detail_col_2
...etc
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
  id string
  mediaTypeId string (links to mediaTypes.id)
  name string
  placement_details_relevant_to_media_type_col_1
  placement_details_relevant_to_media_type_col_2
这样做的缺点是,由于我必须跨所有表进行查询,因此如何按id查找位置:

SELECT * FROM aPlacements WHERE id = '1234'
UNION ALL
SELECT * FROM bPlacements WHERE id = '1234'
etc

整个设计感觉有点像设计的味道。有没有关于如何清理此模式的建议?

也许这是一个主观的解决方案。如果Placements表没有太多列,ej:(detail_col_1,detail_col_2,detail_col_3..detail_col_6)表的设计没有那么糟糕,我的意思是,它不取决于有多少空列,也许它看起来很难看,但它应该可以工作。现在,如果你想要一个复杂的方法,我建议你:

  • 包含json的简单放置表:
  • 具体而言,我可以将属性定义为json,并为每种类型设置正确的值:

    第1行:{'attr1':valx,'attr2':valy} 第2行:{'attr4':valz,'attr1':valw}

    现在,这里的问题是查询过滤器(您不能)。如果你想保存额外的信息,这应该是可行的

  • 优雅的方式:

  • 使用这种方法,您可以根据需要添加许多属性。按属性进行查询筛选也应该有效

    也许这是一个主观的解决方案。如果Placements表没有太多列,ej:(detail_col_1,detail_col_2,detail_col_3..detail_col_6)表的设计没有那么糟糕,我的意思是,它不取决于有多少空列,也许它看起来很难看,但它应该可以工作。现在,如果你想要一个复杂的方法,我建议你:

  • 包含json的简单放置表:
  • 具体而言,我可以将属性定义为json,并为每种类型设置正确的值:

    第1行:{'attr1':valx,'attr2':valy} 第2行:{'attr4':valz,'attr1':valw}

    现在,这里的问题是查询过滤器(您不能)。如果你想保存额外的信息,这应该是可行的

  • 优雅的方式:
  • 使用这种方法,您可以根据需要添加许多属性。按属性进行查询筛选也应该有效

    注意“关系”数据库标记

    整个设计感觉有点像设计的味道

    对。它闻起来有两个原因

  • 每个表中都有
    id
    作为标识符。这将使您感到困惑,并使代码容易出错。对于标识符:
    • 为它标识的东西命名
      例如,
      mediaType
      placementCode
      (它们是字符串,这是正确的)
    • 在作为外键的位置,将其命名为完全相同的名称,这样就不会混淆列是什么以及它引用了什么PK
    但是,根据介质类型的不同,放置可以包含不同的详细信息

  • 在逻辑术语中,您所寻求的是一个或门
    在关系方面,它是一个子类型,这里是一个独占子类型
    也就是说,具有完整性和约束。
    mediaType
    鉴别器
  • 如果我以这种方式设计模式,那么最终可能会有许多可为空的列

    是的,你说得对。可为空的列表示建模练习“归一化”不完整。两个子类型表是正确的

    关系数据模型

    注•符号
    • 我所有的数据模型都在中呈现,这是自1993年以来建立关系数据库模型的标准

    • 我的是初学者的必备读物

    注•内容
    • 独占子类型

    • 每个
      Placement
      都是
      PlacementA
      xor a
      PlacementB

    • 有关子类型实现的完整详细信息,请参阅

    • 关系键

    • 正如你所说,它们是字符串

    • 根据关系模型的要求,它们是“由数据组成的”

    • 这些键是逻辑键,它们确保行是唯一的

    • 此外,它们还提供了关系完整性(与引用完整性不同),这在这个小数据模型中无法显示

    • 请注意,系统制造的ID(不是数据,用户看不到)是物理的,指向记录(不是逻辑行)。它们提供记录唯一性,但不提供行唯一性。它们不能提供关系完整性

    • RM要求行(而不是记录)是唯一的

    SQL 这样做的缺点是,由于我必须跨所有表进行查询,因此如何按id查找位置:

    SELECT * FROM aPlacements WHERE id = '1234'
    UNION ALL
    SELECT * FROM bPlacements WHERE id = '1234'
    etc
    
    按照上述升级,即:

    这样做的缺点是如何通过PK
    Placement
    找到相关的Placement列,因为我必须跨所有表查询:

    SELECT * FROM aPlacements WHERE id = '1234'
    UNION ALL
    SELECT * FROM bPlacements WHERE id = '1234'
    etc
    
    首先,要理解SQL非常适合关系数据库,但它本质上是一种低级语言。在现实世界中,我们大多数人都使用IDE(我不知道有谁不使用IDE),因此它的许多繁琐之处得到了缓解,许多编码错误也被消除了

    我们必须直接编写SQL代码,是的,这就是您必须做的。习惯它。这里只有两张桌子

    您的代码将不起作用,它假定列是相同的数据类型,并且顺序相同(这是联合所必需的)。没有

    • 不要强迫他们放弃