Отход от STI - SQL, чтобы разбить одну таблицу на новую структуру с несколькими таблицами - PullRequest
0 голосов
/ 26 мая 2009

Я перемещаю старый проект, который использовал наследование одной таблицы, в новую базу данных, которая более структурирована. Как бы я написал сценарий SQL для переноса этого?

Старая структура

Я упростил SQL для удобочитаемости.

CREATE TABLE customers (
  id int(11),
  ...
  firstName varchar(50),
  surname varchar(50),

  address1 varchar(50),
  address2 varchar(50),
  town varchar(50),
  county varchar(50),
  postcode varchar(50),
  country varchar(50),

  delAddress1 varchar(50),
  delAddress2 varchar(50),
  delTown varchar(50),
  delCounty varchar(50),
  delPostcode varchar(50),
  delCountry varchar(50),

  tel varchar(50),
  mobile varchar(50),
  workTel varchar(50),
);

Новая структура

CREATE TABLE users (
  id int(11),
  firstName varchar(50),
  surname varchar(50),
  ...
);

CREATE TABLE addresses (
  id int(11),

  ForeignKey(user),
  street1 varchar(50),
  street2 varchar(50),
  town varchar(50),
  county varchar(50),
  postcode varchar(50),
  country varchar(50),
  type ...,
);

CREATE TABLE phone_numbers (
  id int(11),
  ForeignKey(user),
  number varchar(50),
  type ...,
);

Ответы [ 2 ]

1 голос
/ 26 мая 2009

Сначала обязательно сделайте резервную копию ваших существующих данных!

Процесс отличается, если вы собираетесь использовать исходное поле id или сгенерировать новое.

Предполагая, что вы собираетесь использовать оригинал, убедитесь, что у вас есть возможность вставлять поля идентификаторов в таблицу перед началом работы (эквивалент SQL Server, если вы автоматически генерируете число: Установить идентификацию Вставить, не уверен, что такое mysql будет использовать). Записать вставку из старой таблицы в родительскую таблицу:

insert newparenttable (idfield, field1, field2) 
select idfield, field1, field2 from old parent table

затем напишите аналогичные вставки для всех дочерних таблиц в зависимости от того, какие поля вам нужны. Например, если у вас несколько телефонных номеров в разных полях, в качестве выбора вставки вы будете использовать объединение всех.

Insert newphone (phonenumber, userid, phonetype)
select home_phone, id, 100 from oldparenttable
union all
select work_phone, id, 101 from oldparenttable
Union all
select cell_phone, id, 102 from oldparenttable

Если вы собираетесь создать новый идентификатор, то создайте таблицу с полем для старого идентификатора. Вы можете оставить это в конце (хотя я бы оставил это на шесть месяцев). Затем вы можете присоединиться из новой родительской таблицы к старой родительской таблице на oldid и получить новый идентификатор из новой родительской таблицы, когда вы вставляете в дочерние таблицы. Что-то вроде:

Insert newphone (phonenumber, userid, phonetype)
select home_phone, n.id, 100 from oldparenttable o
    join newparenttable n on n.oldid = o.id
union all
select work_phone, n.id, 101 fromoldparenttable o
    join newparenttable n on n.oldid = o.id
Union all
select cell_phone, n.id, 102 from oldparenttable o
    join newparenttable n on n.oldid = o.id
1 голос
/ 26 мая 2009

С соответствующими примечаниями к базе данных для ссылок на таблицы, если необходимо:

INSERT INTO Users(id, firstname, surname, ...)
    SELECT id, firstname, surname, ...
        FROM Customers;
INSERT INTO Addresses(id, street1, street2, ...)
    SELECT id, street1, street2, ...
        FROM Customers;
INSERT INTO Phone_Numbers(id, number, type, ...)
    SELECT id, phone, type, ...
        FROM Customers;

Если вам нужен как новый, так и старый адрес (версия del *), повторите операцию с адресами для двух наборов исходных столбцов с соответствующей маркировкой. Аналогично, для трех телефонных номеров повторите операцию с телефонным номером. Или используйте СОЮЗ в каждом случае.

...