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。或双引号标识符以强制使用驼峰大小写名称。我建议两者都不要做——这样你的生活会更轻松。但这只是我友好的建议。