Wiem, że to pytanie jest stare, ale przez lata poświęcano mu dużo uwagi i myślę, że brakuje w nim koncepcji, która może pomóc komuś w podobnej sprawie. Dodam to tutaj dla kompletności.
Jeśli nie możesz zmodyfikować oryginalnego schematu bazy danych, oznacza to, że podano wiele dobrych odpowiedzi i rozwiązano problem.
Jeśli jednak możesz zmodyfikować swój schemat, radziłbym dodać do customer
tabeli pole id
zawierające najnowszy customer_data
rekord dla tego klienta:
CREATE TABLE customer (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
current_data_id INT UNSIGNED NULL DEFAULT NULL
);
CREATE TABLE customer_data (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
customer_id INT UNSIGNED NOT NULL,
title VARCHAR(10) NOT NULL,
forename VARCHAR(10) NOT NULL,
surname VARCHAR(10) NOT NULL
);
Zapytania klientów
Zapytania są tak proste i szybkie, jak to tylko możliwe:
SELECT c.*, d.title, d.forename, d.surname
FROM customer c
INNER JOIN customer_data d on d.id = c.current_data_id
WHERE ...;
Wadą jest dodatkowa złożoność podczas tworzenia lub aktualizowania klienta.
Aktualizacja klienta
Jeśli chcesz zaktualizować klienta, wstaw nowy rekord do customer_data
tabeli i zaktualizuj customer
rekord.
INSERT INTO customer_data (customer_id, title, forename, surname) VALUES(2, 'Mr', 'John', 'Smith');
UPDATE customer SET current_data_id = LAST_INSERT_ID() WHERE id = 2;
Tworzenie klienta
Utworzenie klienta to tylko kwestia wstawienia customer
wpisu, a następnie uruchomienia tych samych instrukcji:
INSERT INTO customer () VALUES ();
SET @customer_id = LAST_INSERT_ID();
INSERT INTO customer_data (customer_id, title, forename, surname) VALUES(@customer_id, 'Mr', 'John', 'Smith');
UPDATE customer SET current_data_id = LAST_INSERT_ID() WHERE id = @customer_id;
Podsumowując
Dodatkowa złożoność tworzenia / aktualizowania klienta może być przerażająca, ale można ją łatwo zautomatyzować za pomocą wyzwalaczy.
Wreszcie, jeśli używasz ORM, może to być naprawdę łatwe w zarządzaniu. ORM może zająć się wstawieniem wartości, aktualizacją identyfikatorów i automatycznym połączeniem dwóch tabel.
Oto jak wyglądałby Twój zmienny Customer
model:
class Customer
{
private int id;
private CustomerData currentData;
public Customer(String title, String forename, String surname)
{
this.update(title, forename, surname);
}
public void update(String title, String forename, String surname)
{
this.currentData = new CustomerData(this, title, forename, surname);
}
public String getTitle()
{
return this.currentData.getTitle();
}
public String getForename()
{
return this.currentData.getForename();
}
public String getSurname()
{
return this.currentData.getSurname();
}
}
I Twój niezmienny CustomerData
model, który zawiera tylko metody pobierające:
class CustomerData
{
private int id;
private Customer customer;
private String title;
private String forename;
private String surname;
public CustomerData(Customer customer, String title, String forename, String surname)
{
this.customer = customer;
this.title = title;
this.forename = forename;
this.surname = surname;
}
public String getTitle()
{
return this.title;
}
public String getForename()
{
return this.forename;
}
public String getSurname()
{
return this.surname;
}
}