【问题标题】:Shared Primary key versus Foreign Key共享主键与外键
【发布时间】:2012-11-18 17:08:18
【问题描述】:

我有一个实验室分析数据库,我正在研究 bast 数据布局。我已经看到了一些基于使用“共享主键”的类似要求的建议,但我没有看到仅外键的优势。我正在使用 PostgreSQL:下面列出的表

Sample
___________
sample_id (PK)
sample_type (where in the process the sample came from)
sample_timestamp (when was the sample taken)


Analysis
___________
analysis_id (PK)
sample_id (FK references sample)
method (what analytical method was performed)
analysis_timestamp (when did the analysis take place)
analysis_notes

gc
____________
analysis_id (shared Primary key)
gc_concentration_meoh (methanol concentration)
gc_concentration_benzene (benzene concentration)

spectrophotometer
_____________
analysis_id
spectro_nm (wavelength used)
spectro_abs (absorbance measured)

我可以使用这种设计,或者我可以将分析表中的字段移动到 gc 和分光光度计表中,并在样品、gc 和分光光度计表之间使用外键。我看到的这种设计的唯一优势是,我只需要有关执行了多少或哪些类型的分析的信息,而不必加入实际结果。但是,确保共享主键之间的引用完整性以及管理额外连接和触发器(删除级联等)的附加规则似乎比次要优势更令人头疼。我不是 DBA,而是科学家,所以请告诉我我缺少什么。

更新: 共享主键(据我了解)就像一对一的外键,具有附加约束,即父表(分析)中的每个值必须出现在其中一个子表中一次,并且不超过一次。

【问题讨论】:

  • 共享主键在数据库设计者中并不是一个常用术语。编辑您的问题并粘贴指向定义的链接可能会有所帮助。 (对我来说它看起来像一个外键。)
  • 如果您从更多仪器中添加数据..,并且如果某些分析只需要一种仪器,而不是所有仪器?
  • 这是one to 0 or 1关系,一个子表每次分析可以有0条或1条记录。
  • 我认为这有时被称为超类型/子类型关系。如果您愿意迁移它,我认为您会在 dba.se 上得到很好的响应。
  • Damir:在任何一种情况下,如果使用新方法,都必须创建新表。分析表代表特定分析方法的执行。该方法将使用 GC、规格、原子吸收装置、pH 探针等。每个样品都可以对其进行零到无限次分析。在一个类模型中,我认为每个样本都包含一个分析数组,其中每个特定的分析类型(gc、spec)都继承了父类、分析类、类的字段。

标签: postgresql database-design shared-primary-key


【解决方案1】:

我看到了一些基于类似要求的建议 “共享主键”,但我没有看到与外国相比的优势 键。

如果我已经理解了您上面的 cmets,其优点是只有第一个实现了父项中的每一行匹配一个子项中的一行,并且 一个子项中的要求。这是一种方法。

create table analytical_methods (
  method_id integer primary key,
  method_name varchar(25) not null unique
);
insert into analytical_methods values
(1, 'gc'),(2, 'spec'), (3, 'Atomic Absorption'), (4, 'pH probe');

create table analysis (
  analysis_id integer primary key,
  sample_id integer not null, --references samples, not shown
  method_id integer not null references analytical_methods (method_id),
  analysis_timestamp timestamp not null,
  analysis_notes varchar(255),
  -- This unique constraint lets the pair of columns be the target of
  -- foreign key constraints from other tables.
  unique (analysis_id, method_id)
);

-- The combination of a) the default value and the check() constraint on 
-- method_id, and b) the foreign key constraint on the paired columns 
-- analysis_id and method_id guarantee that rows in this table match a 
-- gc row in the analysis table. 
--
-- If all the child tables have similar constraints, a row in analysis 
-- can match a row in one and only one child table.
create table gc (
  analysis_id integer primary key,
  method_id integer not null 
    default 1 
    check (method_id = 1),
  foreign key (analysis_id, method_id) 
    references analysis (analysis_id, method_id),
  gc_concentration_meoh integer not null,
  gc_concentration_benzene integer not null
);

【讨论】:

  • 我在询问这两种设计的优点以及在我的案例中使用哪种设计的建议。由于我发布的是对表格布局的真实外观的过度简化,因此不需要代码。不需要在不同的表之间共享主键,前提是该设计最适合我的情况。
  • 停止谈论共享主键是值得的,因为这就是 all 外键引用的作用。我发布的结构保证分析中的每一行都可以匹配一个且只有一个“子”表中的一行。 Damir 链接中的结构允许分析中的每一行匹配 every “子”表中的一行。您的更新说“父表(分析)中的每个值必须出现在其中一个子表中一次”。如果这确实是一个要求,我发布的结构将实现它,而链接结构不会。
  • 随便...我不是专家,只是使用我在别处看到的术语。
【解决方案2】:

在我的情况下,这种超类型/子类型模型似乎不是最佳选择。相反,我应该将分析表中的字段移动到所有子表中,并建立一系列简单的外键关系。超类型/子类型模型的优点是当使用超类型的主键作为另一个表中的外键时。由于我不这样做,额外的复杂层不会增加任何东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2012-09-02
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    相关资源
    最近更新 更多