gpt4 book ai didi

mysql - TypeORM复合外键

转载 作者:行者123 更新时间:2023-12-05 05:47:38 26 4
gpt4 key购买 nike

在第一类中,主键是复合的:

@Entity({
name: 'ClassA',
database: Constants.DATABASE_NAME,
})
export class ClassA {
@PrimaryColumn({
name: 'Field1',
type: 'varchar',
length: 4,
})
field1: string;

@PrimaryColumn({
name: 'Field2',
type: 'varchar',
length: 2,
})
field2: string;

@PrimaryColumn({
name: 'Field3',
type: 'integer',
})
field3: number;

@OneToMany(() => ClassB, (classB) => classB.classA)
classB: ClassB[];
}

在另一个类中,第一个类用作外键:

@Entity({
name: 'ClassB',
database: Constants.DATABASE_NAME,
})
export class ClassB {

...

@ManyToOne(() => ClassA, (classA) => classA.classB, {
cascade: true,
})
@JoinColumn([
{ name: 'Field1', referencedColumnName: 'field1' },
{ name: 'Field2', referencedColumnName: 'field2' },
{ name: 'Field3', referencedColumnName: 'field3' },
])
classA: ClassA;
}

当我使用 nest start 启动 NestJS 时,出现错误

code: "ER_FK_NO_INDEX_PARENT"
errno: 1822
sqlMessage: Failed to add the foreign key constraint. Missing index for constraint 'FK_1d19fe001872b5ee9ab545c18f8' in the referenced table 'ClassA'
sqlState: "HY000

尝试修改ClassA表,对主键的每一列加索引,然后对主键的所有列加索引,还是报错。

是否可以使用 TypeORM 来管理这种情况?

相关包:

  • typeorm:0.2.41
  • @nestjs/核心:8.0.0
  • @nestjs/typeorm: 8.0.3
  • mysql: 2.18.1

数据库:Docker 容器中的 MySQL v8.0 (mysql:latest)

谢谢。

编辑

问题似乎是使用 TypeORM 在多个步骤中创建了该表。错误消息后的表格如下所示。

CREATE TABLE `ClassB` (
`Date` datetime NOT NULL,
`ClassAField1` varchar(4) NOT NULL,
`ClassAField2` varchar(2) NOT NULL,
`ClassAField3` int NOT NULL,
PRIMARY KEY (`Date`,`ClassAField1`,`ClassAField2`,`ClassAField3`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

错误发生在以下查询中,其中 TypeORM 尝试添加外键:

ALTER TABLE `ClassB`
ADD CONSTRAINT `FK_479eaf779e0d5f0d0a83bb9e30d`
FOREIGN KEY (`ClassAField1`, `ClassAField2`, `ClassAField3`)
REFERENCES `LandPlots`(`Field1`,`Field2`,`Field3`) ON DELETE NO ACTION ON UPDATE NO ACTION

我做了一些测试,下面的查询按预期工作:

CREATE TABLE `ClassB` (
`Date` datetime NOT NULL,
`ClassAField1` varchar(4) NOT NULL,
`ClassAField2` varchar(2) NOT NULL,
`ClassAField3` int NOT NULL,
PRIMARY KEY (`Date`),
KEY `FK_e6b2926df2c758d8d8810e4345a` (`ClassAField1`, `ClassAField2`, `ClassAField3`),
CONSTRAINT `FK_e6b2926df2c758d8d8810e4345a`
FOREIGN KEY (`ClassAField1`, `ClassAField2`, `ClassAField3`)
REFERENCES `ClassA` (`Field1`, `Field2`, `Field3`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

差异似乎是 KEY `FK_e6b2926df2c758d8d8810e4345a` (`ClassAField1`, `ClassAField2`, `ClassAField3`), 行,TypeORM 生成的 SQL 中缺少它。

来自 MySQL documentationKEY 语句与 INDEX 同义:

 KEY | INDEX

KEY is normally a synonym for INDEX. The key attribute PRIMARY KEY can also be specified as just KEY when given in a column definition. This was implemented for compatibility with other database systems.

所以我尝试将 @Index 装饰器添加到该列,但它没有改变任何东西。我添加了所有已执行查询的日志记录,看起来 @Index 装饰器没有被执行,所以,也许 @JoinColumn 装饰器优先于它? (为了以防万一,尝试对装饰器进行不同的排序)。

我能想到的使用 TypeORM 的唯一解决方案是生成所有 3 个主键的散列或串联,并使其成为唯一的主键。两个缺点:插入前解析实体时的数据重复和 CPU 使用率。

如果有人有更好的建议,我想听听。

编辑来自@RickJames 的 2 个问题

更新语句:

UPDATE cb
SET cb.SomeField = 'NewValue'
FROM ClassB cb
JOIN ClassA ca
ON cb.Field1 = ca.Field1
AND cb.Field2 = ca.Field2
AND cb.Field3 = ca.Field3
WHERE ca.SomeOtherField LIKE '%partialvalue%'
AND cb.otherPK = 1

最佳答案

该 UPDATE 可能会受益于其中一些索引:

cb:  INDEX(otherPK, Field1, Field2, Field3)
ca: INDEX(Field1, Field2, Field3, SomeOtherField)

关于mysql - TypeORM复合外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70963321/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com