串行类型的外键 - 确保始终手动填充

0fn*_*fnt 1 sql database postgresql database-design

我有两张桌子:国家和地区.

CREATE TABLE Countries(
    id     SERIAL,
    name   VARCHAR(40) NOT NULL,
    PRIMARY KEY(id)
)

CREATE TABLE Regions(
    id           SERIAL,
    countryId    SERIAL,
    name         VARCHAR(40) NOT NULL,
    PRIMARY KEY(id       ),
    FOREIGN KEY(countryId) REFERENCES Countries(id)
)
Run Code Online (Sandbox Code Playgroud)

当我插入区域时,我希望如果我没有提到countryId,我会被停止,但是,countryId会自动增加.有什么方法可以自动停止进行插入吗?

下面的表格,我设置countryIDSERIAL NOT NULL不解决问题.

CREATE TABLE Pigeons(
    id           SERIAL,
    countryId    SERIAL NOT NULL,
    name         VARCHAR(40) NOT NULL,
    PRIMARY KEY(id       ),
    FOREIGN KEY(countryId) REFERENCES Countries(id)
)
Run Code Online (Sandbox Code Playgroud)

以下解决了这个问题,但我认为它在技术上是不正确的,因为我的序列可能大于2 ^ 31,但int永远不会> = 2 ^ 31.

CREATE TABLE Legions(
    id           SERIAL,
    countryId    INT NOT NULL,
    name         VARCHAR(40) NOT NULL
    PRIMARY KEY(id       ),
    FOREIGN KEY(countryId) REFERENCES Countries(id)
)
Run Code Online (Sandbox Code Playgroud)

这里有什么正确的方法?

Erw*_*ter 7

我会建议:

CREATE TABLE country(
    country_id serial PRIMARY KEY
  , country    text NOT NULL
);

CREATE TABLE region(
    region_id  serial PRIMARY KEY
  , country_id int NOT NULL REFERENCES country
  , region     text NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
  • 不要使用CaMeL案例名称.阅读有关标识符的手册.
  • 使用专有名称.从不idname不具有描述性.
  • a的基础类型serialinteger.创建引用列integer.
    由于外键引用region.country_id只能保存country.country_id(或NULL)中存在的值.您对值> 2 ^ 31的考虑是不必要的.
  • 演示PK和FK定义的较短语法(可选).阅读手册CREATE TABLE.

代码示例包含更多建议: