在Google Cloud Spanner中用不同的外键定义交错表

问题描述

我正在尝试定义交错表,并且当父表的主列和交错表的外键具有相同的列名时,它可以工作。我已经将数据库从mysql迁移到扳手。所有表均以“ id”作为主键列名称。

请考虑以下示例:

CREATE TABLE Singers (
  Id   INT64 NOT NULL,FirstName  STRING(1024),LastName   STRING(1024),SingerInfo BYTES(MAX),) PRIMARY KEY (Id);

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,Id      INT64 NOT NULL,AlbumTitle   STRING(MAX),) PRIMARY KEY (SingerId,Id),INTERLEAVE IN PARENT Singers ON DELETE CASCADE;

这对我不起作用,因为父(歌手)表的主键列为“ id”,子表的外键为“ SingerId”。

解决方法

我能够使用Google Cloud Console创建表。

在这里您可以找到等效的DDL:


CREATE TABLE Singers (
    Id INT64 NOT NULL,FirstName STRING(MAX),LastName STRING(MAX),SingerInfo STRING(MAX),) PRIMARY KEY (Id)

CREATE TABLE Albums (
    Id INT64 NOT NULL,SingerId INT64 NOT NULL,AlbumeTitle STRING(MAX),) PRIMARY KEY (Id,SingerId),INTERLEAVE IN PARENT Singers ON DELETE CASCADE

似乎列的顺序很重要。

父级的主键应该是第一个,因为它是继承的。

## EDIT

它正在控制台UI上工作

enter image description here enter image description here

,

是的,主键规范的顺序很重要。

更具体地说:

如果您声明一个表是另一个表的子表,则父表的主键列必须是子表的主键的前缀。这意味着,如果父表的主键由N列组成,则其每个子表的主键也必须由相同的N列组成,并且顺序相同,并且从同一列开始。 >

参考:https://cloud.google.com/spanner/docs/schema-and-data-model#primary_keys

,

只需切换相册主键的顺序即可解决此问题:

CREATE TABLE Albums (
    SingerId INT64 NOT NULL,Id INT64 NOT NULL,) PRIMARY KEY (SingerId,Id),INTERLEAVE IN PARENT Singers ON DELETE CASCADE

顺便说一句,如果您只需要一般外键关系,而不需要物理数据交织,则可能需要考虑Cloud Spanner中更通用的外键。 您可以在此处参考文档:https://cloud.google.com/spanner/docs/foreign-keys/overview

要使用通用外键而不是交织,专辑表应如下所示(您将能够保持主键的旧顺序)

CREATE TABLE Albums (
    Id INT64 NOT NULL,FOREIGN KEY (SingerId) REFERENCES Singers(SingerId),SingerId)

缺点是您不能使用级联删除,因为通用外键尚不支持该删除。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...