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

Sql 串行类型的外键-确保始终手动填充,sql,database,postgresql,database-design,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 ),

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

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)
)

正确的方法是什么?

正确的方法是阅读

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

创建表tablename( colname序列号);等同于指定:

创建序列tablename\u colname\u seq

创建表tablename( colname integer非空默认值nextval('tablename_colname_seq')

更改tablename.colname拥有的序列tablename\u colname\u seq

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

,我建议:

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
);
  • 不要使用驼峰大小写名称
  • 使用专有名称。切勿使用非描述性的
    id
    name
  • a的基本类型是
    整数
    。使引用列
    为整数

    由于外键引用的原因,
    region.country\u id
    只能保存
    country.country\u id
    (或
    NULL
    )中存在的值。您对大于2^31的值的考虑是不必要的
  • 演示PK和FK定义的较短语法(可选)
代码示例提供更多建议:


第8-2节。数字类型和8.1.4。串行类型。谢谢你的链接。所以连续剧实际上只是正片,只是它们是“31位(有效)”。伟大的谢谢。好吧,我不知道连载片不仅仅是正面的。我可以发誓我读过这样的东西。@user247077:默认的
serial
列仅为正数。你也可以修改它来插入负数。谢谢你花时间来教育我!我注意到了所有的要点。我阅读了有关标识符的手册,但尽管我可以选择不使用camel case,但我仍然希望在表名和列名中有某种区别,这使事情更容易理解。我知道我是非传统的,但我想以一种结构化的方式来结束。有什么潜在的不利因素吗?@user247077:具体的不利因素是什么?没有遵循惯例@user247077:我不太明白<代码>表名和列名之间的某种区别
?你在说什么?驼峰案例标识符?@user247077:你可以这么做。或者在代码中以这种方式键入,名称周围不带双引号。所有的标识符在内部都是小写的,所有的东西都应该工作,但是有一些警告,比如动态SQL。或双引号标识符以强制使用驼峰大小写名称。我建议两者都不要做——这样你的生活会更轻松。但这只是我友好的建议。