Uczymy się czym tak naprawdę jest klucz obcy. Większość poznamy w tej lekcji, nieco więcej w następnej. Do dzieła.

Ok, idziemy do tabeli reviews, do structure. Widzimy, że movie_id to bigint 20 unsigned not null. Taki sam typ ma id w movies. Tak, jeżeli chcemy porównywać ze sobą id, robić joiny, to kolumna odnosząca się do innej tabeli musi być tego samego typu.

To oczywiście nie znaczy jeszcze, że movie_id jest kluczem obcym. Wejdźmy w relacyjny widok, tak zobaczymy:

  • constraint name reviews_movie_id
  • on delete cascade
  • on update restrict
  • column movie_id
  • table movies
  • column id

I to oznacza, że do reviews nie wrzucimy recenzji mającej movie_id, który w movies w kolumnie id nie istnieje. Plus kilka innych rzeczy, zaraz to ogarniemy.

Ok, skaczemy do innej bazy danych, gdzie poprzednio zrobiliśmy sobie coś takiego:

CREATE TABLE `people` ( 
    id BIGINT  UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    age INT UNSIGNED NOT NULL,
    PRIMARY KEY(id)
    );


INSERT INTO `people` (name, age)
VALUES("John Doe", 33);

INSERT INTO `people` (name, age)
VALUES("Jane Doe", 33);

INSERT INTO `people` (name, age)
VALUES("Jim Doe", 33);

Mam nadzieję, że jeszcze to pamiętamy. Teraz tworzymy tabelkę:

CREATE TABLE `contacts` ( 
    id BIGINT  UNSIGNED NOT NULL AUTO_INCREMENT,
    person_id BIGINT  UNSIGNED NOT NULL,
    city VARCHAR(255) NOT NULL,
    street VARCHAR(255) NOT NULL,
    PRIMARY KEY(id)
   );

Ta tabelka nie ma klucza obcego. Ma tylko pole person_id, którego typ zgadza się z polem id w tabeli people. To wystarczy, aby robić joiny.

Najpierw dodajmy sobie to i owo:

INSERT INTO `contacts` (person_id, city, street)
 VALUES(1, "London", "London Street");

INSERT INTO `contacts` (person_id, city, street)
  VALUES(2, "Warsaw", "Warsaw Street");


INSERT INTO `contacts` (person_id, city, street)
  VALUES(3, "Warsaw", "Warsaw Street");

Ok, teraz join:

SELECT * FROM `people` AS p
LEFT JOIN `contacts` AS c
ON p.id = c.person_id;

Fajnie to wygląda. Ale zobaczmy na ten kod:

UPDATE `contacts` 
SET `person_id` = '4' 
WHERE `contacts`.`id` = 3; 

Nie ma osoby z id 4 a taki person_id przypisaliśmy ostatniemu adresowi. Mało tego, dodajmy:

INSERT INTO `contacts` 
(person_id, city, street)
  VALUES
(30, "Warsaw", "Warsaw Street");

Nie ma osoby z ID 30 a taki person_id sobie brutalnie dodaliśmy do contacts. Właśnie dlatego używamy kluczy obcych.

Utwórzmy taką tabelkę:

CREATE TABLE `addresses` ( 
    id BIGINT  UNSIGNED NOT NULL AUTO_INCREMENT,
    person_id BIGINT UNSIGNED NOT NULL,
    city VARCHAR(255) NOT NULL,
    street VARCHAR(255) NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY (person_id) REFERENCES people(id)
   );

Jak rzucimy okiem na widok relacyjny to jesteśmy już blisko zrozumienia tego, co laravel nam robi automatycznie w naszej bazie danych.

Spróbujmy dodać coś, co nie istnieje:

INSERT INTO `addresses` (person_id, city, street)
  VALUES(10, "London", "London Street"); 
#fail

Foreign key constraint error, czyli koszmar ludzi, którzy zaczęli używać ORMa bez rozumienia czystego SQLa. Albo inaczej – próbujesz jako person_id mi 10 ustawić, ale w tabeli people nie ma id o wartości 10.

Ok, dodajmy „legitne” numery id:

INSERT INTO `addresses` 
(person_id, city, street) 
VALUES
(1, "London", "London Street"); 

INSERT INTO `addresses` 
(person_id, city, street) 
VALUES
(2, "Warsaw", "Warsaw Street"); 


INSERT INTO `addresses` 
(person_id, city, street) 
VALUES
(3, "Warsaw", "Warsaw Street"); 

Teraz zróbmy left-join, bo choć tak nie jest, mogłoby tak być, że jakaś osoba (tabela po prawej) nie ma adresu (tabela po lewej), ale to jeszcze nie powód, aby osobę z result setu usuwać tylko dlatego, że adresu nie ma:

SELECT * FROM `people` AS p
LEFT JOIN `addresses` AS a
ON p.id = a.person_id;

Właściwie to możemy dodać osobę bez adresu:

INSERT INTO `people` (name, age)
VALUES("Tim Homeless", 33);

Teraz left join będzie pokazywał pana bezdomnego, ale już join nie:

SELECT * 
FROM `people` AS p 
JOIN `addresses` AS a 
ON p.id = a.person_id; 

Jeszcze kilka zagadnień musimy lepiej poznać, ale już na dobrej drodze jesteśmy.