Я знаю, что это старый вопрос, но на протяжении многих лет ему уделялось много внимания, и я думаю, что ему не хватает концепции, которая может помочь кому-то в аналогичном случае. Я добавляю его сюда для полноты картины.
Если вы не можете изменить исходную схему базы данных, значит, было предоставлено много хороших ответов, которые отлично решают проблему.
Однако, если вы можете изменить свою схему, я бы посоветовал добавить в свою customer
таблицу поле , содержащее id
последнюю customer_data
запись для этого клиента:
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
);
Запрос клиентов
Запросы настолько просты и быстры, насколько это возможно:
SELECT c.*, d.title, d.forename, d.surname
FROM customer c
INNER JOIN customer_data d on d.id = c.current_data_id
WHERE ...;
Недостатком является дополнительная сложность при создании или обновлении клиента.
Обновление клиента
Каждый раз, когда вы хотите обновить клиента, вы вставляете новую запись в customer_data
таблицу и обновляете customer
запись.
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;
Создание клиента
Создание клиента - это просто вопрос вставки customer
записи, а затем выполнения тех же операторов:
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;
Подведение итогов
Дополнительная сложность создания / обновления клиента может быть пугающей, но ее можно легко автоматизировать с помощью триггеров.
Наконец, если вы используете ORM, этим очень легко управлять. ORM может позаботиться о вставке значений, обновлении идентификаторов и автоматическом объединении двух таблиц за вас.
Вот как Customer
будет выглядеть ваша изменяемая модель:
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();
}
}
И ваша неизменяемая CustomerData
модель, содержащая только геттеры:
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;
}
}