SQL和外键:如何正确链接这两个表?

时间:2013-02-14 00:29:39

标签: sql firebird

我正在为我的大学创建一个Delphi应用程序,现在我被困住了。该程序是关于数据库的,我使用FireBird 2.1作为数据库服务器。我的数据库和应用程序是关于Linux发行版的。

我正在尝试链接Firebird数据库中的两个表。第一个表提供有关分发的信息,第二个表提供有关桌面环境的信息。我想链接两个字段:Distributions表中的Default Desktop Environment和DEs表中的Desktop Environment Name。

一个发行版只能有一个默认桌面环境,即安装光盘上的环境(或者在安装过程中由用户选择)。在DEs表中,有一个唯一的字段,描述了DE的名称,因此它应该链接到Distributions的Default DE字段。

但是,一个DE可以被多个分布用作默认DE,这就是冲突所在:发行版表中的默认DE字段必须是唯一的,但它不是。我想要达到的是参照完整性:使DEs表依赖。

另外,我试图创建一个仅包含DISTR_NAME和ENV_NAME字段的第三个表,但我唯一能够使用这个表来使第三个表依赖于DISTROS和DES表,但它是错误。 DES表应该依赖于DISTROS表,我不知道该怎么做。所以任何帮助将不胜感激!如何正确链接这两个表?

所以我创建了这两个表:

CREATE TABLE DISTROS (
    DISTR_NAME  VARCHAR(50) NOT NULL,
    ARCHITECT   VARCHAR(50) NOT NULL,
    DEFAULT_DE  VARCHAR(50) NOT NULL,
    LASTSTABLE  VARCHAR(50) NOT NULL,
    PACKMANAGE  VARCHAR(50) NOT NULL
);

CREATE TABLE DES (
    ENV_NAME    VARCHAR(50) NOT NULL,
    USED_LANG   VARCHAR(50) NOT NULL,
    LASTSTABLE  VARCHAR(50) NOT NULL,
    SUPPORT_3D  SMALLINT,
    FILEMANAGE  VARCHAR(50) NOT NULL
);
ALTER TABLE DES ADD CONSTRAINT PK_DES PRIMARY KEY (ENV_NAME);
ALTER TABLE DES 
   ADD CONSTRAINT FK_DES_1 FOREIGN KEY (ENV_NAME) REFERENCES DISTROS (DE);

我无法弄清楚如何解决这个问题:发布表必须是父表,DE表必须是子表。分发表应具有主键(DISTR_NAME字段),DEs表应具有外键(ENV_NAME字段,与分发表的DE字段链接)。

但是我不能这样做,因为SQL要求分发表的DE字段是主键。主键必须是唯一的。但是,许多Linux发行版可以使用一个桌面环境,因此该字段不可能是唯一的。我只是无法弄清楚如何正确地链接这两个表。

2 个答案:

答案 0 :(得分:4)

正如您所描述的那样,发行版具有默认的桌面环境。这意味着从DISTROSDES的外键,而是您反过来模拟外键。外键的目的地需要PRIMARY KEYUNIQUE CONSTRAINT,因此您当前的解决方案存在问题。

解决方案是将外键从DES移除到DISTROS并将其替换为:

ALTER TABLE DISTROS 
   ADD CONSTRAINT FK_DISTROS_DES FOREIGN KEY (DE) REFERENCES DES (ENV_NAME);

我建议重新学习SQL和关系建模,因为这些是您在使用SQL和(关系)数据库时真正需要了解的基础知识。

此外,我知道Firebird中标识符的31个字符限制可能有问题,但您应该尝试使用更长,更具描述性的名称(尤其是DESDE)。

答案 1 :(得分:2)

您所描述的内容听起来像是多对多的关系。听起来你几乎就是自己在那里。如您所述,M2M关系中始终存在第3个表格。你的最终结构看起来像这样。

**DISTROS**
DISTR_NAME - PK/Unique

**DISTROS_TO_DES** (PK contains both fields which are collectively unique)
DISTR_NAME FK to Distros.DISTR_NAME 
ENV_NAME  FK to DES.ENV_NAME

**DES**
ENV_NAME  - PK/Unique

再多一点建议。您真的不希望主键值可能经常更改,因此varchar字段通常是一个糟糕的选择。我建议在DES和DISTROS表中添加一个自动递增(或标识)ID字段,以用作PK。