Я разрабатываю таблицу предметов, которая (потенциально) будет содержать десятки миллионов записей. Некоторые элементы не будут доступны для использования, пока они не будут «одобрены» администратором. Под «использованием» я подразумеваю, что на такие элементы не будут ссылаться никакие другие таблицы, пока они не будут «одобрены». До 50% элементов могут быть «не одобрены» в любой момент времени. Записи могут стать «одобренными», но не наоборот.
Я рассматриваю два варианта дизайна:
- битовый флаг
- отдельная таблица «неутвержденных» элементов - когда элемент утвержден, он перемещается в «обычную» таблицу (обновление идентификатора элемента не является проблемой)
Я думаю, что второй вариант намного лучше. Битовый флаг занимает только байт на строку, поэтому это не проблема. Но если у нас есть миллион утвержденных и миллион неутвержденных записей в одной таблице - время сканирования увеличивается для операций с утвержденными записями.
Вопрос в том, должен ли я рассмотреть первый вариант (битовый флаг)? Есть ли какие-то преимущества в описанной ситуации?
WHERE status='A'
а в запросе естьWHERE status = 'A' AND (... other columns and parameters here...)
, то этот индекс все еще может использоваться.Ответы:
Вы можете использовать оба способа с разделенными представлениями .
Вы создаете базовую таблицу для каждого статуса, поддерживаемого ограничениями, со взаимоисключающими значениями. Затем рассмотрим, какие объединения объединяют основные таблицы. На представление или на каждую базовую таблицу можно ссылаться явно. Если статус строки ОБНОВЛЕН через представление, СУБД УДАЛЕТ его из одной базовой таблицы и вставит в таблицу, соответствующую новому статусу. Каждая базовая таблица может быть проиндексирована независимо в соответствии со схемой ее использования. Оптимизатор разрешит ссылки индекса на одну соответствующую базовую таблицу, если это возможно.
Преимущества
а) более мелкие индексы. Тем не менее, сделайте математику на разветвлении индекса. При таком масштабе и разделении между значениями вашего состояния возможно, что индексы в таблицах разделения будут иметь такую же глубину, как и в объединенной таблице.
б) код приложения не должен меняться. Данные продолжают появляться как единое целое.
c) будущие новые значения статуса могут быть включены путем добавления новой базовой таблицы с ограничением и повторного создания представления.
Стоимость - все это движение данных; две страницы и соответствующие индексы пишутся для каждого обновления статуса. Много IO, чтобы иметь дело с. Это большое движение также приведет к фрагментации.
источник
Это на самом деле не так уж много, учитывая, что SQL Server может эффективно обрабатывать. Конечно, я помню одно из моих ранних заданий, когда в одной из самых больших таблиц (система с одним экземпляром) было 2 миллиона строк, и это было больше всего, с чем я когда-либо имел дело. Затем у следующего задания было 17 производственных экземпляров с несколькими таблицами, имеющими сотни миллионов строк, и все они были объединены в хранилище данных с несколькими таблицами фактов, имеющими более 1 миллиарда строк. Не поймите меня неправильно, я не издеваюсь над десятками миллионов строк, я просто подчеркиваю, что с хорошей моделью данных и надлежащим индексированием (и ведением индекса) SQL Server может справиться с большим количеством проблем .
Хм. Это не звучит правильно. Скорость «одобрения» записей будет вдвое меньше, чем получение новых записей? На каждые 2 новые записи только 1 будет «одобрено»? В вашем примере, состоящем из 2 миллионов строк и 1 миллиона для «утвержденных» и «неутвержденных», через несколько лет еще с 10 миллионами записей вы ожидаете 6 миллионов для «утвержденных» и «неутвержденных»? Или это то, что 1 миллион «неутвержденных» останется неизменным, так что с 10 миллионами новых заявок будет 11 миллионов «одобренных» и еще 1 миллион «неутвержденных»?
Это верно сегодня , но со временем все меняется, и поэтому всегда есть вероятность, что бизнес может принять решение о том, что он может быть «не одобрен», или, возможно, какой-то другой статус, например, «заархивирован» и т. Д.
Итак, давайте посмотрим на выбор:
Флаг (или, возможно, даже
TINYINT
«статус»)TINYINT
столбцаДве отдельные таблицы (одна для «утвержденных», одна для «не утвержденных»)
IDENTITY
столбцом, а в утвержденной таблице есть столбец идентификатора, который не являетсяIDENTITY
(так как в этом нет необходимости). Следовательно, значения идентификаторов остаются согласованными при перемещении записей между таблицами.Лично я бы склонялся к одной таблице с
StatusID
колонкой для начала. Использование двух таблиц кажется слишком сложной, преждевременной оптимизацией. Этот тип оптимизации можно обсудить, если / когда число записей составляет несколько сотен миллионов, и индексация не обеспечивает какого-либо увеличения производительности.источник