问题描述
我正在尝试定义交错表,并且当父表的主列和交错表的外键具有相同的列名时,它可以工作。我已经将数据库从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上工作
,是的,主键规范的顺序很重要。
更具体地说:
如果您声明一个表是另一个表的子表,则父表的主键列必须是子表的主键的前缀。这意味着,如果父表的主键由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)
缺点是您不能使用级联删除,因为通用外键尚不支持该删除。