Активный флаг или нет? - PullRequest
       20

Активный флаг или нет?

20 голосов
/ 19 сентября 2008

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

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

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

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

SELECT * FROM people WHERE active=True;

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

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

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

Спасибо

Ответы [ 16 ]

21 голосов
/ 19 сентября 2008

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

Вот пример того, как создать секционированную таблицу в 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

8 голосов
/ 19 сентября 2008

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

3 голосов
/ 19 сентября 2008

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

2 голосов
/ 19 сентября 2008

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

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

2 голосов
/ 19 сентября 2008

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

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

1 голос
/ 21 сентября 2008

Двоичные флаги, подобные этому в вашей схеме, являются ПЛОХОЙ идеей. Рассмотрим запрос

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 голос
/ 19 сентября 2008

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

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

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

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

1 голос
/ 19 сентября 2008

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

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

0 голосов
/ 17 февраля 2011

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

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

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

0 голосов
/ 19 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...