Две разные таблицы или только одна с колонкой bool? - PullRequest
11 голосов
/ 29 марта 2010

У нас есть две таблицы: OriginalDocument и ProcessedDocument. В первом мы помещаем оригинальный, не обработанный документ. После того, как он проверен и обработан (преобразован в наш формат XML и проанализирован), он помещается в таблицу ProcessedDocument. Обработанный документ может быть действительным или недействительным. Что имеет больше смысла: иметь две разные таблицы для действительных и недействительных документов или просто иметь одну со столбцом «Действительный»? Некоторые из столбцов (~ 5-7) не имеют значения для недействительного документа. Хранение как недействительных, так и действительных документов также приведет к заполнению таблицы документов столбцами «NULL» (если документ недействителен, такая информация, как номер документа, получатель может быть неизвестна). Что еще мы должны учитывать и взвешивать при принятии этого решения?

Ответы [ 7 ]

6 голосов
/ 29 марта 2010

Является ли документ действительным или недействительным, он по-прежнему является документом, поэтому имеет смысл иметь их всех в одной таблице.

Однако, если ваше приложение по-разному воспринимает недействительный документ до того момента, когда оно почти забыто (не запрошено, не обновлено и т. Д.), То разбейте таблицы. Объединение двух типов документов в одной таблице ничего не даст, кроме как замедлит ваши запросы без немедленной выгоды.

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

5 голосов
/ 29 марта 2010

Мне кажется, что имеет смысл иметь битовый столбец, так как все документы фактически обработаны, просто некоторые из них были признаны недействительными. И в зависимости от количества столбцов, если у вас есть только 5 или около того из 10-15 столбцов, которые не применяются, нет необходимости управлять двумя структурами для одних и тех же данных.

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

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

3 голосов
/ 29 марта 2010

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

Это VLDB? Вы говорите о 100 туберкулезе, 100 о ГБ, 1-10 ГБ?

Это сверхвысокая производительность БД? Вам нужно выжать микросекунды?

Большинство советов склоняются к тем крайностям, когда вы можете нарушить несколько основных правил ради производительности.

В предыдущем плакате говорилось:

"Является ли документ действительным или недействительный, это все еще документ, так что имеет смысл для них всех быть в той же таблице. "

Он был на правильном пути. И в этом отношении, является ли это обработанным или необработанным, это - также документ. Я сильно сомневаюсь, что первое разделение таблицы.

Затем он говорит,

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

Я понятия не имею, на чем основан этот совет. Если ваша СУБД поддерживает индексы, дополнительные данные будут иметь очень незначительные дополнительные затраты при определенных размерах вашего индекса, потому что ваше b-дерево становится на один уровень глубже. Если вы возьмете его утверждение в чистом виде, вы должны ограничить свою таблицу n строками и продолжать делать новые, потому что "больше данных в вашей таблице = медленные запросы" Я понятия не имею, почему люди упорствуют в этом понятии. Если у вас есть запросы, требующие полного сканирования таблицы для одного или другого типа, давайте поговорим о разделении, а не о новой таблице. Чтобы найти строку в таблице с миллиардными строками, требуется около 10 миллисекунд, чем в таблице с миллионными строками, потому что индекс, вероятно, будет только на один уровень глубже между этими двумя.

Другой плакат сказал:

"5-7 столбцов, которые не относятся к недействительные документы NOT NULL, поэтому действительный документы должны иметь их. На мой взгляд, с таким количеством столбцов пусто для недействительных документов, это оправдывает другую таблицу. "

Я бы хотел, чтобы люди объяснили причины. КАК это оправдывает? На каком основании вы бы приняли это решение. 4 слишком много? Почему бы и нет? Но 5 это слишком много? Возможно, он предполагает, что вы используете древнюю СУБД с фиксированной длиной поля. Я не могу сказать. Если вы поместите пустые столбцы в конец строки, вы не заплатите за них. Посередине несколько лишних байтов. Если это ОГРОМНАЯ сделка, если вы действительно стараетесь сделать этот мультитабитный стол крошечным ... мы поговорим о вертикальном разделении ... не совсем новом столе. Поскольку вы будете увеличивать длину n% строк, вам нужно будет тщательно выбирать PCTFREE или как-то иначе это делает ваша база данных. Кроме этого, есть небольшие недостатки обнуляемых столбцов.

Итак, давайте поговорим обо всех недостатках трех таблиц.

Я предполагаю, что ваш стол выглядит так;

A surrogate PK column with a unique index.
A candidate key column with a unique index.
a few foreign keys to 'lookup' tables.
Several data fields.
the 5-7 nullable columns that are filled if a document becomes invalid.

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

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

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

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

Я видел подобные системы. Один из основных оперативных запросов: «Где мой документ?»

Вам нужно найти 3 таблицы, чтобы найти ее состояние. Далее большинство людей создают представление UNION ALL для всех трех таблиц, чтобы облегчить множество подобных вопросов. Если другой автор думает, что ваши запросы замедляются с другими данными в вашей таблице, посмотрите, как они действительно замедляются, когда вы выполняете UNION ALL, чтобы выполнить то же самое. 1 индекс уровня 3, в отличие от 3 показателей уровня 2.

Пример / РЕДАКТИРОВАТЬ * * одна тысячи пятьдесят-два Я работаю в торговой компании. Мы заключаем сделки с контрагентами . По бухгалтерским и юридическим причинам наша компания определяется как несколько компаний. Хорошо называть их Трейдинг, Холдинг, СП. Нашим контрагентам мы позвоним. JonesCo, SmithBarely, GoldSax. Так что, если я считаю, что у внутренних компаний есть уникальный набор столбцов, а у контрагентов - уникальный набор столбцов. Вы бы сказали, что правильная нормализация вынудит их создать две таблицы. Итак, давайте сделаем это. INT_CO_T 1 Торговая 2 Холдинг 3 СП CNTR_PTY_T 1 JonesCo 2 SmithBarely 3 GoldSax Теперь мне нужна таблица trade , где я отображаю транзакцию между нашей компанией (компаниями) и контрагентами TRADE_T (Int_co_T.ID, Ctr_pty_T.ID, другие торговые столбцы) Отлично. Ой, Бизнес говорит, что СП будет заключать сделки с Трейдингом. Кстати, это очень распространенный сценарий, это происходит постоянно. Торговый дом будет называть эти сделки между книгами. Теперь у меня есть два варианта. (Действительно три) но. 1 заключается в том, что я мог бы сделать что-то очень глупое и поместить JointVenture и Trading в таблицу Counterparty, чтобы моя таблица отображения все еще работала. Это приводит к кошмарным запросам, которые, я уверен, распознают те, кто участвует в этом разговоре. Или я могу создать отдельную таблицу сопоставления ... и это также приведет к созданию некоторых союзов, если я захочу увидеть все сделки определенной компании. Третий и лучший способ - создать единую таблицу для контрагентов и внутренних компаний, которая называется Trading_entities или чем-то еще. Теперь мне нужна одна таблица сопоставления для отображения внутренних или внешних сделок. Я легко могу увидеть чистую позицию и чистую экспозицию с помощью одного запроса, двух таблиц. и т.д. Если вы действительно зациклены на пустых полях, разделите эту таблицу по вертикали и используйте три таблицы. Но основная таблица будет иметь список и, что важнее всего, один ключ для любого подтипа участника торговли.

2 голосов
/ 30 марта 2010

Старайтесь проводить различие между логическим и физическим моделированием.

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

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

С точки зрения производительности это не так уж и плохо:

  • когда вам все равно, с каким типом документа вы работаете, вы запросите таблицу суперкласса (усиление)
  • когда вы знаете, что вам нужны только определенные свойства, найденные в таблице подклассов, вы будете работать только с этой таблицей (это может быть реальным преимуществом)
  • вы заплатите цену только тогда, когда вам нужно объединить две таблицы (объединения имеют цену по сравнению с денормализованными структурами, такими как хранение всего в одной таблице)
  • вы также заплатите цену при вставке записей подкласса, потому что вы будете вставлять в две таблицы (это может быть очень низким и / или оправданным)

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

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

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

1 голос
/ 29 марта 2010

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

1 голос
/ 29 марта 2010

Думайте о OriginalDocuments как о промежуточной таблице. Он может меняться при изменении форматов ввода. И он будет содержать поля, которые недопустимы для импортированных («обработанных») документов, таких как дата импорта или описание ошибки импорта. И вы можете периодически чистить эту таблицу.

В отличие от OriginalDocument, таблица ProcessedDocument будет содержать только документы и поля, действительные для вашей системы, со всеми проверочными ограничениями, индексами и связанной бизнес-логикой. Его структура будет меняться по мере изменения внутренней логики вашей системы.

1 голос
/ 29 марта 2010

Какую форму ваши запросы? Вы часто хотите иметь дело с групповыми (всеми?) Документами, независимо от того, являются ли они действительными? Или каждый запрос касается только каждой действительной (или недействительной) документации.

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

...