Кращі практики для зміни схем та міграції даних до живої бази даних без простоїв?


43

Як ви вносите зміни схеми в живу базу даних без простоїв?

Наприклад, скажімо, що у мене є база даних PostgreSQL з таблицею, що включає різні дані користувачів, такі як адреси електронної пошти тощо, які пов'язані з конкретними користувачами. Якщо я хотів би перемістити адреси електронної пошти до нової спеціалізованої таблиці, мені доведеться змінити схему, а потім перемістити дані електронної пошти в нову таблицю. Як це можна було зробити, не зупиняючи запису до оригінальної таблиці? Безумовно, поки дані записуються зі старої таблиці в нову, нові дані продовжуватимуть записуватися у стару таблицю і пропускатимуться, правда?

Я думаю, що ця проблема виникає досить часто, але я не можу знайти жодного стандартного рішення для її вирішення.

У цій статті йдеться про проблему, але я дійсно не зрозумів крок 3. Він каже написати в обидві таблиці, а потім перемістити старі дані з першої таблиці в нову. Як переконатися, що ви переносите лише старі дані?

(Я використовую PostgreSQL на Heroku .)


2
Facebook розробив інструмент для цього для MySQL.
Нік Чаммас

2
К. Скотт Аллен писав про систему управління версіями схем тут . Я створив DbUpdater, інструмент з відкритим кодом для розгортання схеми, відомий версії. Більше тут - http://www.tewari.info/dbupdater
попел

@NickChammas Дякую за те, що поділився цим. У мене дуже багато питань. Чи можете ви запропонувати більш детальний підручник, бажано відео, в якому пояснюються такі речі, як журнал бітів, некластеризовані індекси та відповіді на запитання на кшталт - 1. Як вибір даних із вихідної таблиці в аутфілі зменшить навантаження порівняно з копіюванням у пункт призначення стіл безпосередньо. 2. Коли закінчиться фаза копіювання? Це лише кілька питань, які у мене є, і я лише почав її читати.
Сандепіан Натх

@SandeepanNath - Вибачте, я не такий знайомий з інструментом Facebook, тому не можу вказати на більше ресурсів. Я прочитав оголошення про це і опублікував свій коментар років тому, але ніколи його не використовував.
Нік Чаммас

Відповіді:


27

У вас майже є відповідь:

  1. Створіть нову структуру паралельно
  2. Почніть писати обом структурам
  3. Перенесення старих даних у нову структуру
  4. Лише записуйте та читайте нову структуру
  5. Видалити старі стовпці

Що стосується кроку 3 , використовуйте щось подібне (за одну транзакцію):

Вставте те, чого ще немає:

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

Оновіть що змінилося тим часом:

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

Нові дані торкатися не будуть, оскільки вони однакові в обох місцях.


У мене є кілька питань, намагаючись зрозуміти сценарій, на який ви запропонували цю відповідь - 1. Чи будуть розгорнуті зміни коду разом із початком змін db? 2. Чому виникне потреба писати обидві структури? 3. Чому не можна спочатку висувати нову структуру, а потім мігрувати існуючі дані, а потім застосовувати зміни коду, які заповнюватимуть нову структуру? 4. Чому виникає потреба з’ясувати те, чого немає (ваш 1-й запит)? Чи пропонуєте ви вставити кілька разів?
Сандепіан Натх

2
@SandeepanNath, щоб відповісти на запитання 3 у вашому коментарі: адже якщо ви (а) відкриєте нову структуру, (б) перенесіть до неї дані, (в) змініть свій код, щоб записати дані в нову структуру замість старої, то всі зміни даних, здійснені між кроком b і етапом c, будуть існувати лише в старій структурі. Питання полягало в тому, як зробити зміни схеми без простоїв. Прочитайте цю відповідь ще раз, уважно.
Wildcard
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.