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

时间:2014-07-29 16:21:08

标签: 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)
)

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

下表我将countryID设为SERIAL 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)
)

以下解决了这个问题,但我认为它在技术上是不正确的,因为我的序列可能大于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)
)

这里有什么正确的方法?

2 个答案:

答案 0 :(得分: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
);
  • 请勿使用CaMeL案例名称。 Read the manual about identifiers.
  • 使用专有名称。从不idname,这些都不具有描述性。
  • serial的基础类型为integer。制作引用列integer 由于外键引用region.country_id只能保存country.country_id(或NULL)中的值。您对值的考虑> 2 ^ 31是不必要的。
  • 演示PK和FK定义的较短语法(可选)。 Read the manual on CREATE TABLE.

更多建议的代码示例:

答案 1 :(得分:0)

正确的方法是阅读the manual

  

数据类型serial和bigserial不是真正的类型,而只是一个   创建唯一标识符列的符号方便(类似   到某些其他数据库支持的AUTO_INCREMENT属性)。   在当前实现中,指定:

     

CREATE TABLE tablename(       colname SERIAL);相当于指定:

     

CREATE SEQUENCE tablename_colname_seq;

     

CREATE TABLE tablename(       colname integer NOT NULL DEFAULT nextval('tablename_colname_seq'));

     

ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

SERIAL基本上是一个自动递增的整数。如果您的数据大于int,则应使用bigint,而countries表应使用BIGSERIAL