Таблиця надгробних таблиць проти видаленого прапора в сценаріях синхронізації бази даних та програмного забезпечення для видалення


17

Мені потрібно стежити за видаленими елементами для потреб синхронізації клієнтів.

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

Відповіді:


17

Взагалі краще знати конкретні вимоги і не приймати дизайнерські рішення на основі того, що найкраще працює в більшості ситуацій. Будь-яке може бути кращим. Ось деякі особливості, які потрібно зібрати:

  • Наскільки швидко повинні бути видалені?
  • Наскільки швидко потрібно виконувати видалення?
  • Як часто запитувані дані будуть запитуватися і чи будуть запитуватися дані, які не були видалені?
  • Наскільки швидко повинні бути запити на видалені дані?
  • Чи потрібно також зберігати лише видалені елементи чи зміни?
  • Чи потрібно тримати таблицю / індекси на первинній таблиці невеликою?
  • Які технології розділення та / або зміни стеження доступні на платформі бази даних?
  • Скільки місця на диску?
  • Чи відбудеться видалення на льоту або в пакетних операціях?

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

Ти отримав це. Можуть бути навіть випадки, коли кращий інший варіант. Наприклад, якщо вам потрібні були лише м'які видалення, щоб вони були доступні протягом 24 годин, в Oracle ви можете розглянути можливість встановлення гарантованого часу утримання, а потім використати запити flashback, щоб побачити видалені дані.
Лі Риффель

5

Можливо, вам слід поєднати ці два способи спеціально. Чому ???

Давайте скористаємося цією таблицею (MySQL-діалект)

CREATE TABLE mydata
(
    id int not null auto_increment
    firstname varchar(16) not null,
    lastname varchar(16) not null,
    zipcode char(5) not null,
    ...
    deleted tinyint not null default 0
    KEY (deleted,id),
    KEY (deleted,lastname,firstname,id),
    KEY (deleted,zipcode,id),
    KEY (lastname,firstname),
    KEY (zipcode),
    PRIMARY KEY (id)
);

Зауважте, що, за винятком ОСНОВНОГО КЛЮЧА, кожному введеному вами індексу повинен передувати deletedпрапор і закінчуватися символом id.

Давайте створимо надгробну таблицю

CREATE TABLE mytomb SELECT id FROM mydata WHERE 1=2;
ALTER TABLE mytomb ADD PRIMARY KEY (id);

Якщо на вашому столі вже є deletedпрапор, ви можете заповнити таблицю з надгробками

INSERT INTO mytomb SELECT id FROM mydata WHERE deleted = 1;

Гаразд, дані та надгробна плита підготовлені. Як виконувати видалення?

Скажімо, ви видаляєте кожну особу в поштовому індексі 07305. Ви виконаєте наступне:

INSERT IGNORE INTO mytomb SELECT id FROM mydata WHERE deleted=0 AND zipcode='07305';
UPDATE mydata SET deleted=1 WHERE deleted=0 AND zipcode='07305';

Гаразд це здається великим накладним способом будь-який спосіб ви дивитесь на це.

Тепер ви хочете побачити всі видалені дані? Ось два різні способи:

  • SELECT * FROM mydata WHERE deleted=1;
  • SELECT B.* FROM mytomb A INNER JOIN mydata B USING (id);

Якщо кількість ідентифікаторів в mytomb перевищує 5% від кількості рядків моїх даних, це сканування повної таблиці. В іншому випадку - індексне сканування з пошуком для кожного рядка. Зверніть увагу на будь-які орієнтири з цього приводу. Пошук планів пояснення.

Тепер ви хочете бачити кожну людину за поштовим індексом 07304? Ось два різні способи:

  • SELECT * FROM mydata WHERE deleted=1 AND zipcode='07304';
  • SELECT A.* FROM mydata A LEFT JOIN mytomb B USING (id) WHERE B.id IS NULL AND A.zipcode='07304'

Як щодо масових делетів? Ось два різні способи:

  • DELETE FROM mydata WHERE deleted=1;
  • DELETE B.* FROM mytomb A INNER JOIN mydata B USING (id); DELETE FROM mytomb;

ВИСНОВОК

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


Чи є перевага використовувати обидві методики на постійній основі? Або ви пропонуєте просто використовувати їх паралельно для оцінки ефективності, а потім виконувати зобов'язання перед тим чи іншим?
Йон усіх торгів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.