Две различных таблицы или всего один с bool столбцом?

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

12
задан Brian Tompsett - 汤莱恩 27 May 2017 в 12:57
поделиться

7 ответов

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

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

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

6
ответ дан 2 December 2019 в 18:52
поделиться

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

Это VLDB? Вы говорите о сотнях ТБ, сотнях ГБ, 1-10 ГБ?

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

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

Ранее на плакате говорилось:

«Независимо от того, действителен ли документ или недействителен, он все равно остается документом, поэтому для них всех имеет смысл быть в той же таблице »

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

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

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

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

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

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

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

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

Я предполагаю, что ваша таблица выглядит так:

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-е состояние? Вы собираетесь добавить 4-ю таблицу документов для тех, кто находится в состоянии неподтвержденных или отправленных. В конце концов, новое состояние отправки имеет 5-7 столбцов, которые не нужны другим состояниям.

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

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

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

ПРИМЕР / РЕДАКТИРОВАТЬ

Я работаю в торговой компании.Мы заключаем сделки с контрагентами . По бухгалтерским и юридическим причинам наша компания определяется как несколько компаний. Назовите их торговлей, холдингом, совместным предприятием. Мы позвоним нашим контрагентам. JonesCo, SmithBarely, GoldSax.

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

INT_CO_T 1 Trading 2 Holding 3 JointVenture

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 или что-то в этом роде.Теперь мне нужна одна таблица сопоставления для отображения внутренних или внешних сделок. Я легко могу увидеть чистую позицию и чистую прибыль с помощью одного запроса, двух таблиц. и т.д.

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

3
ответ дан 2 December 2019 в 18:52
поделиться

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

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

1
ответ дан 2 December 2019 в 18:52
поделиться

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

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

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

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

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

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

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

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

2
ответ дан 2 December 2019 в 18:52
поделиться

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

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

1
ответ дан 2 December 2019 в 18:52
поделиться

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

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

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

5
ответ дан 2 December 2019 в 18:52
поделиться

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

1
ответ дан 2 December 2019 в 18:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: