我正在为我的大学创建一个Delphi应用程序,现在我被卡住了。该程序是关于数据库的,我使用FireBird 2.1作为数据库服务器。我的数据库和应用程序是关于Linux发行版的。
我正在尝试链接Firebird数据库中的两个表。第一个表提供了有关分发内容的信息,第二个表则提供了有关桌面环境的信息。我想链接两个字段:Distributions表中的Default Desktop Environment和DE表中的Desktop Environment Name。
一个发行版只能有一个默认的桌面环境,即安装光盘上的环境(或用户在安装过程中选择的环境)。在DE表中,有一个唯一的字段,描述了DE的名称,因此它应该链接到Distributions的Default DE字段。
但是,一个DE可以被多个发行版用作默认DE,这就是冲突所在:发行版表中的默认DE字段必须是唯一的,但事实并非如此。我试图达到的是引用完整性:使DE表依赖。
此外,我曾尝试创建第三个表,该表仅由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字段),DE表应具有外键(ENV_NAME字段,与分发表的DE字段链接)。
但我不能这样做,因为SQL要求分布表的DE字段是主键。而且主键必须是唯一的。然而,一个桌面环境可以被许多linux发行版使用,所以这个字段不可能是唯一的。我只是不知道如何正确地连接这两个表。
正如您所描述的,分发具有默认的桌面环境。这意味着一个从DISTROS
到DES
的外键,但相反,您可以反过来建模外键。外键的目的地需要PRIMARY KEY
或UNIQUE CONSTRAINT
,因此当前解决方案存在问题。
解决方案是删除DES
到DISTROS
的外键,并将其替换为:
ALTER TABLE DISTROS
ADD CONSTRAINT FK_DISTROS_DES FOREIGN KEY (DE) REFERENCES DES (ENV_NAME);
我建议重新研究SQL和关系建模,因为这些是使用SQL和(关系)数据库时真正需要了解的基础知识。
此外,我知道Firebird中标识符的31个字符限制可能会有问题,但您确实应该尝试使用更长的描述性名称(尤其是DES
和DE
)。
您所描述的听起来像是多对多关系。而且听起来你几乎是一个人在那里。正如你所描述的,M2M关系中总是有第三张表。你的最终结构会是这样的。
**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。