SQL复合主键

SQL复合主键,sql,Sql,我整个下午都在努力实现这一点,但在创建第二、第三和第四个表时(外键引用第一个表上的复合主键的表)出现了一个错误。它表示引用的表上没有PK。我在谷歌上搜索过,检查过stackoverflow,检查过我的笔记,但仍然不知道为什么它会给我这个错误 对不起,代码是西班牙语的,请提前感谢 create database proyecto_camiones go use proyecto_camiones go create table servicios ( ruta int not null,

我整个下午都在努力实现这一点,但在创建第二、第三和第四个表时(外键引用第一个表上的复合主键的表)出现了一个错误。它表示引用的表上没有PK。我在谷歌上搜索过,检查过stackoverflow,检查过我的笔记,但仍然不知道为什么它会给我这个错误

对不起,代码是西班牙语的,请提前感谢

create database proyecto_camiones
go
use proyecto_camiones
go

create table servicios (
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha date not null
    primary key (ruta, nif, matricula)
    )

create table camiones (
    matricula varchar(10) not null unique references servicios (matricula),
    fecha_alta date not null,
    ultima_inspeccion date not null
    )

create table transportistas (
    nif varchar(9) not null references servicios (nif),
    nombre varchar(30) not null,
    direccion varchar(30) not null,
    fecha_nac date not null
    )

create table rutas (
    codigo int not null unique references servicios (ruta),
    inicio varchar(15) not null,
    final varchar(15) not null
    )

因为它是复合主键,所以您必须使用PK中包含的所有列。 对于
camiones
表,它看起来像

create table servicios (
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha date not null
    primary key (ruta, nif, matricula)
    )

create table camiones (
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha_alta date not null,
    ultima_inspeccion date not null,
    primary key (ruta, nif, matricula),
    FOREIGN KEY (ruta, nif, matricula) REFERENCES servicios(ruta, nif, matricula)
    )
但是如果您不想存储冗余列(
nif
matricula
),您可以将PK更改为一个单独的列
id
,如下所示

create table servicios (
    id int,
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha date not null
    primary key (id)
    )

create table camiones (
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha_alta date not null,
    ultima_inspeccion date not null,
    idservicios int,
    primary key (ruta),
    FOREIGN KEY (idservicios) REFERENCES servicios(id)
    )
可以从“属于不同表”(措辞不当)的列列表中形成复合(超级)键(唯一非空或主键),而不管它们中的任何一个参与了任何FK(外键)。但是复合FK必须引用表中声明为复合(超级)键的列列表。因此,错误是因为引用的目标表和列没有声明相应的超级键

因此,您可能希望每个基表中的codigo、nif、matricula和外键

FOREIGN KEY (codigo, nif, matricula)
    REFERENCES servicios(ruta, nif, matricula)
您更可能希望servicios ruta、nif和matricula值始终作为值显示在其他三个表的相应列中。(即你的FK声明方向错误。)


但是,由于您没有给出基的含义,甚至没有给出输入和输出的示例查询,并且您承认您的代码是错误的,因此我们只能猜测什么是正确的。

外键必须由3列组成,所以基本上我不能从属于不同表的列中形成一个组合PK?我的意思是,他们必须属于同一张桌子?谢谢,你必须在引用表中包含PK的所有列。我将我的评论扩展为一个答案。(此外,海报总是会收到评论通知,但如果有多个其他评论,则必须使用@才能通知其中一个。此外,不鼓励使用“谢谢”评论。)因此,基本上我无法从属于不同表的列中形成复合PK?我的意思是,他们必须属于同一张桌子?thanks@ArturAlvaro不,你不能。看我对这个问题的评论:它是一个复合FK而不是PK,必须引用一个表。
create table servicios (
    ruta int not null,
    nif varchar(9) not null,
    matricula varchar (10) not null,
    fecha date not null
    primary key (ruta, nif, matricula),
    foreign key (ruta) references rutas (codigo),
    foreign key (nif) references transportistas (nif),
    foreign key (matricula) references camiones (matricula)
    )

create table camiones (
    matricula varchar(10) primary key,
    fecha_alta date not null,
    ultima_inspeccion date not null
    )

create table transportistas (
    nif varchar(9) primary key,
    nombre varchar(30) not null,
    direccion varchar(30) not null,
    fecha_nac date not null
    )

create table rutas (
    codigo int primary key,
    inicio varchar(15) not null,
    final varchar(15) not null
    )