Отношения 1: 1. я должен создать новую таблицу для одного необязательного значения? - PullRequest
0 голосов
/ 11 февраля 2020

Допустим, у меня есть покупки. Эти покупки можно при желании вернуть.

Я хочу знать, была ли возвращена покупка и в какую дату это произошло.

Должен ли я иметь одну таблицу для покупок и столбец с именем "refunded_date", который по умолчанию равен null и в котором будет указана дата возврата?

Или я должен создать новую таблицу с именем refunds, где у меня есть purchase_id и refund_date?

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

Пример первый:

Purchases
============
id | product | purchase_date | email | license | refund_date
-------------------------------------------------------------
1  |    X    |        X      |    X  |    X    |     NULL
2  |    X    |        X      |    X  |    X    |  2020-02-12

Случай 2:

Purchases
============
id | product | purchase_date | email | license
---------------------------------------------- 
1  |    X    |        X      |    X  |    X   
2  |    X    |        X      |    X  |    X    


Refunds
============
id | product_id | date
---------------------------------------------- 
30  |    2      |  2020-02-12    

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Я был бы склонен добавить, чтобы добавить это как отдельную таблицу.

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

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

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

Если запросы проиндексированы правильно и записаны в оптимизированным способом вы должны увидеть небольшую разницу в производительности

(обычные предостережения относительно размера ваших данных и YMMV применяются)

1 голос
/ 11 февраля 2020

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

То, что вы узнали, неверно. Фактический ответ зависит от ряда факторов. Но в большинстве баз данных дата NULL и число NULL по-прежнему будут занимать место на страницах данных. Таким образом, вы расширяете каждую строку в таблице purchases, даже те, которые не возвращаются. Это дополнительное пространство замедляет всю обработку таблицы.

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

Что касается производительности соединений. Обе таблицы предположительно имели бы один и тот же первичный ключ. JOIN s должно быть довольно быстрым - хотя есть некоторые издержки по сравнению с простым чтением данных в одной строке.

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

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

...