Вопрос

Итак, практически каждому приложению, работающему с базой данных, приходится иметь дело с «неактивными» записями.Либо мягкое удаление, либо пометка чего-либо как «игнорируемого».Мне любопытно, есть ли какие-либо радикальные альтернативные мысли по поводу «активного» столбца (или столбца статуса).

Например, если бы у меня был список людей

CREATE TABLE people (
  id       INTEGER PRIMARY KEY,
  name     VARCHAR(100),
  active   BOOLEAN,
  ...
);

Это означает, что чтобы получить список активных людей, вам нужно использовать

SELECT * FROM people WHERE active=True;

Кто-нибудь предполагает, что неактивные записи будут перенесены в отдельную таблицу и где будет уместно использовать UNION для объединения этих двух?

Любопытство поражает...

РЕДАКТИРОВАТЬ: Я должен прояснить: я подхожу к этому с пуристской точки зрения.Я понимаю, что архивирование данных может быть необходимо для больших объемов данных, но я пришел не к этому.Если вы выполните SELECT * FROM людей, для меня будет иметь смысл, что эти записи в некотором смысле «активны».

Спасибо

Это было полезно?

Решение

Вы разделяете таблицу по активному флагу, так что активные записи находятся в одном разделе, а неактивные записи — в другом разделе.Затем вы создаете активное представление для каждой таблицы, в которой автоматически применяется активный фильтр.Механизм запросов к базе данных автоматически ограничивает запрос разделом, в котором есть активные записи, что намного быстрее, чем даже использование индекса по этому флагу.

Вот пример того, как создать секционированную таблицу в Oracle.В Oracle нет логических типов столбцов, поэтому я изменил структуру вашей таблицы для целей Oracle.

CREATE TABLE people
(
   id       NUMBER(10),
   name     VARCHAR2(100),
   active   NUMBER(1)
)
PARTITION BY LIST(active)
(
   PARTITION active_records VALUES (0)
   PARTITION inactive_records VALUES (1)
);

Если вы хотите, вы можете поместить каждый раздел в разные табличные пространства.Вы также можете секционировать свои индексы.

Кстати, это похоже на повторение этот Вопрос, как новичку, я должен спросить: какова процедура борьбы с непреднамеренными дубликатами?

Редактировать: По запросу в комментариях предоставлен пример создания секционированной таблицы в Oracle.

Другие советы

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

В большинстве таблиц мы используем перечисление('ACTIVE','INACTIVE','DELETED'), поэтому у нас фактически есть трехсторонний флаг.Я считаю, что это хорошо работает для нас в разных ситуациях.Ваш пробег может отличаться.

Перемещение неактивных вещей обычно является глупой идеей.Это большие накладные расходы и большая вероятность ошибок, все становится более сложным, например, разархивирование и т. д.Что вы делаете со связанными данными?Если вы переместите все это, вам придется изменить каждый отдельный запрос.Если вы не переместите его, какое преимущество вы надеялись получить?

Это приводит к следующему пункту:ЗАЧЕМ вам его переместить?Правильно индексированная таблица требует одного дополнительного поиска, когда ее размер увеличивается вдвое.Любое улучшение производительности будет незначительным.И зачем вам вообще думать об этом до тех пор, пока в далеком будущем у вас действительно не возникнут проблемы с производительностью?

Я думаю, что если рассматривать это строго как часть данных, то то, что показано в исходном сообщении, является правильным.Часть данных активного флага напрямую зависит от первичного ключа и должна находиться в таблице.

В этой таблице хранятся данные о людях, независимо от текущего статуса их данных.

Активный флаг выглядит некрасиво, но он прост и хорошо работает.

Вы можете переместить их на другой стол, как вы предложили.Я бы предложил посмотреть процент активных/неактивных записей.Если у вас более 20–30 % неактивных записей, вы можете рассмотреть возможность перемещения их в другое место.В противном случае это не имеет большого значения.

Да, мы бы это сделали.В настоящее время во многих наших таблицах есть столбец «active='T/F'», в основном для отображения «последней» строки.При вставке новой строки предыдущая строка T помечается буквой F, чтобы сохранить ее для целей аудита.

Теперь мы переходим к подходу с двумя таблицами: когда вставляется новая строка, предыдущая строка перемещается в таблицу истории.Это дает нам лучшую производительность в большинстве случаев — если смотреть на текущие данные.

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

Выгода в производительности заключается в том, что индекс вашей основной таблицы значительно меньше, и вы можете лучше оптимизировать табличные пространства (они не будут так сильно расти!)

Подобные двоичные флаги в вашей схеме — ПЛОХАЯ идея.Рассмотрим запрос

SELECT count(*) FROM users WHERE active=1

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

ALTER TABLE users ADD INDEX index_users_on_active (active)

КРОМЕ!!Этот индекс бесполезен, поскольку мощность этого столбца равна ровно двум!Любой оптимизатор запросов к базе данных проигнорирует этот индекс из-за его низкой мощности и выполнит сканирование таблицы.

Прежде чем наполнять схему полезными флагами, подумайте, как вы собираетесь получить доступ к этим данным.

https://stackoverflow.com/questions/108503/mysql-advisable-number-of-rows

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

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

В большинстве случаев достаточно двоичного поля, указывающего на удаление.Часто существует механизм очистки, который удаляет эти удаленные записи через определенное время, поэтому вы можете запустить схему с удаленной меткой времени.

Переход к отдельному столу и возвращение их обратно требует времени.В зависимости от того, сколько записей отключается от сети и как часто вам нужно их возвращать, это может быть хорошей идеей, а может и нет.

Если большинство из них не возвращаются после того, как они похоронены, и используются только для сводок/отчетов/что-то еще, то это уменьшит вашу основную таблицу, а запросы упростит и, возможно, ускорит.

Мы используем оба метода для работы с неактивными записями.Используемый нами метод зависит от ситуации.Для записей, которые по сути являются значениями поиска, мы используем поле Активный бит.Это позволяет нам деактивировать записи, чтобы они не использовались, но также позволяет нам сохранять целостность данных в отношениях.

Мы используем метод «переместить в таблицу разделения», когда данные больше не нужны и они не являются частью отношения.

Ситуация действительно диктует решение, я думаю:

Если таблица содержит пользователей, то можно использовать несколько полей «флагов».Один для удаленных, отключенных и т. д.Или, если пространство является проблемой, тогда будет достаточно установить флажок «Отключено», а затем фактически удалить строку, если она была удалена.

Это также зависит от политики хранения данных.Если существуют политики архивирования данных, то по прошествии длительного времени, скорее всего, потребуется отдельная таблица.

Нет, это довольно распространенная вещь — несколько вариантов в зависимости от конкретных требований (но вы их уже рассмотрели):

1) Если вы ожидаете, что у вас будет целая КУЧА данных - например, несколько терабайт или более - неплохая идея немедленно заархивировать удаленные записи - хотя вы можете использовать комбинированный подход: пометить как удаленные, а затем скопировать в архивные таблицы.

2) Конечно, возможность принудительного удаления записи все еще существует - хотя мы, разработчики, как правило, занимаемся сбором данных - я предлагаю вам взглянуть на бизнес-процесс и решить, есть ли сейчас необходимость вообще хранить данные - если есть - сделай так...если нет - вам, вероятно, следует просто выбросить эти вещи.....опять же, в зависимости от конкретного бизнес-сценария.

С «пуристской точки зрения» реальная модель не делает различия между представлением и таблицей — оба являются отношениями.Таким образом, использование представления, использующего дискриминатор, вполне значимо и допустимо при условии, что объекты правильно названы, например.Человек/Активный Человек.

Кроме того, с «пуристской точки зрения» таблица должна называться person, а неpeople, поскольку имя отношения отражает кортеж, а не весь набор.

Что касается индексации логического значения, почему бы и нет:

ALTER TABLE users ADD INDEX index_users_on_active (id, active) ;  

Не улучшит ли это поиск?
Однако я не знаю, насколько этот ответ зависит от платформы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top