Avatar billede VC1 Seniormester
09. maj 2022 - 03:40 Der er 17 kommentarer og
1 løsning

Problemer med foreign key i MySQL

Jeg har 3 tables indeholdende følgende:

1) teamtable
teamid (primary key)
teamname

2) playertable
playerid (primary key)
playername
teamid

3) matchtable
matchid (primary key)
teamida
teamidb

Jeg har lavet en foreign key mellem de to øverste tables via. 'teamid'.
Nu vil jeg selvfølgelig gerne lave det samme på matchtable til teamid.a og teamid.b, men det bliver ved med at sige fejl.
Først troede jeg det var pga. navnet, så slette jeg a og b, virkede ikke.
Så prøvede jeg at linke fra playertable's teamid, istedet for teamtable's, virkede heller ikke.

Nogen der kan komme med inputs til hvad der er galt her? Jeg tænker det sikkert er ret simpelt for en der bare har en smule forstand på MySQL, hvilket jeg ikke har :P


ERROR 1822: Failed to add the foreign key constraint. Missing index for constraint 'teamid' in the referenced table 'teamtable'
Avatar billede arne_v Ekspert
09. maj 2022 - 04:06 #1
Bruger du direkte SQL eller PHPMyAdmin?
Avatar billede arne_v Ekspert
09. maj 2022 - 04:07 #2
ERROR 1822: Failed to add the foreign key constraint. Missing index for constraint 'teamid' in the referenced table 'teamtable'

virker mystisk da teamtable.teamid er primary key og derfor har et index.
Avatar billede VC1 Seniormester
09. maj 2022 - 04:08 #3
Hmm, er SQL software og PHP over nettet?

I så fald så bruger jeg Workbench software.
Avatar billede arne_v Ekspert
09. maj 2022 - 04:13 #4
Jeg har faktisk aldrig brugt workbench. Skriver du SQL ind og klikker execute? Eller bruger du en GUI til at vælge FK?
Avatar billede VC1 Seniormester
09. maj 2022 - 04:22 #5
Skriver ikke SQL, det gør den selv.

ALTER TABLE `bttest`.`match`
ADD INDEX `teamid_idx` (`teamid.a` ASC, `teamid.b` ASC) VISIBLE;
;
ALTER TABLE `bttest`.`match`
ADD CONSTRAINT `teamid`
  FOREIGN KEY (`teamid.a` , `teamid.b`)
  REFERENCES `bttest`.`teamtable` (`teamid` , `teamid`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION;
Avatar billede VC1 Seniormester
09. maj 2022 - 04:23 #6
Og så her med fejlen...

Operation failed: There was an error while applying the SQL script to the database.
Executing:
ALTER TABLE `bttest`.`match`
ADD INDEX `teamid_idx` (`teamid.a` ASC, `teamid.b` ASC) VISIBLE;
;
ALTER TABLE `bttest`.`match`
ADD CONSTRAINT `teamid`
  FOREIGN KEY (`teamid.a` , `teamid.b`)
  REFERENCES `bttest`.`teamtable` (`teamid` , `teamid`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION;

ERROR 1822: Failed to add the foreign key constraint. Missing index for constraint 'teamid' in the referenced table 'teamtable'
SQL Statement:
ALTER TABLE `bttest`.`match`
ADD CONSTRAINT `teamid`
  FOREIGN KEY (`teamid.a` , `teamid.b`)
  REFERENCES `bttest`.`teamtable` (`teamid` , `teamid`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
Avatar billede arne_v Ekspert
09. maj 2022 - 04:43 #7
Jeg tror at du skal have 2 foreign keys med 1 felt hver i.s.f. 1 foreign key med 2 felter.
Avatar billede arne_v Ekspert
09. maj 2022 - 04:45 #8
Teknisk er problemet at der er index paa teamid men ikke paa (teamid,teamid).

Men du vil ikke lave index paa (teamid,teamid) - du vil have 2 FK.
Avatar billede VC1 Seniormester
09. maj 2022 - 05:10 #9
Som jeg forstår din løsning, så vil du have at jeg laver to connections via foreign key.
Hvor jeg prøvede at lave
(teamtable) teamid <> (matchtable) teamid.a & teamid.b

Så vil du have
(teamtable) teamid <> (matchtable) teamid.a
(teamtable) teamid <> (matchtable) teamid.b

Hvis det er forstået korrekt, så virkede det ikke. Jeg har nu også prøvet at ændre navn til teamid, så det er helt ens og KUN på den ene. Virker stadig ikke.


Operation failed: There was an error while applying the SQL script to the database.
Executing:
CREATE TABLE `bttest`.`match` (
  `matchid` INT NOT NULL,
  `teamid` INT NULL,
  `teamid` INT NULL,
  PRIMARY KEY (`matchid`),
  INDEX `teamid_idx` (`teamid` ASC) VISIBLE,
  CONSTRAINT `teamid`
    FOREIGN KEY (`teamid`)
    REFERENCES `bttest`.`teamtable` (`teamid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

ERROR 1060: Duplicate column name 'teamid'
SQL Statement:
CREATE TABLE `bttest`.`match` (
  `matchid` INT NOT NULL,
  `teamid` INT NULL,
  `teamid` INT NULL,
  PRIMARY KEY (`matchid`),
  INDEX `teamid_idx` (`teamid` ASC) VISIBLE,
  CONSTRAINT `teamid`
    FOREIGN KEY (`teamid`)
    REFERENCES `bttest`.`teamtable` (`teamid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
Avatar billede erikjacobsen Ekspert
09. maj 2022 - 13:57 #10
Eksempel der umiddelbart ser ud til at virke:

CREATE TABLE teamtable (
  teamid int NOT NULL PRIMARY KEY,
  teamname VARCHAR(255)
) ENGINE=InnoDB;

CREATE TABLE `match` (
  `matchid` INT NOT NULL PRIMARY KEY,
  `teamida` INT NULL,
  `teamidb` INT NULL, 
  CONSTRAINT `fk_teamida`
    FOREIGN KEY (`teamida`)
    REFERENCES teamtable (`teamid`),
  CONSTRAINT `fk_teamidb`
    FOREIGN KEY (`teamidb`)
    REFERENCES teamtable (`teamid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    )ENGINE=InnoDB;
Avatar billede arne_v Ekspert
09. maj 2022 - 14:38 #11
#9

Man kan ikke have 2 felter med samme navn.

Løsningen er 2 FK.

match.teama -> team.teamid
match.teamb -> team.teamid

betyder at man kun kan oprette en match hvis begge teams eksisterer. Det giver mening!

(match.teama,match.teamb) -> (team.teamid,team.teamid)

betyder at man kun kan oprette matche hvor et team spiller mod sig selv. Det giver ikke mening.
Avatar billede arne_v Ekspert
09. maj 2022 - 14:39 #12
Eneste alternativ til de 2 FK er ingen FK og så lade applikations logikken håndtere integriteten.
Avatar billede VC1 Seniormester
11. maj 2022 - 02:28 #13
Tak for jeres input, det lykkedes aldrig at få til at virke så jeg tænker at det bliver som arne's sidste forslag, ingen FK til den.
Avatar billede arne_v Ekspert
11. maj 2022 - 02:51 #14
Erik's eksempel burde virke.

Jeg kan ogsaa godt lave et eksempel hvis du vil.

PS: Hvad bruger du for at tilgaa databasen?
Avatar billede VC1 Seniormester
11. maj 2022 - 02:55 #15
Jeg bruger IntelliJ til programmering, hvori jeg selvfølgelig tilgår databasen og MySQL Workbench til at opsætte tables osv.
Avatar billede arne_v Ekspert
11. maj 2022 - 03:01 #16
Via JDBC eller JPA eller?
Avatar billede VC1 Seniormester
11. maj 2022 - 18:15 #17
JDBC
Avatar billede arne_v Ekspert
11. maj 2022 - 18:51 #18
Engang når du har god tid bør du nok kigge på JPA.

:-)

Hvis du vil see en masse kode:
    http://external.vajhoej.dk:81/arne/articles/javadb.html
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester