Структура SQL / MySQL - PullRequest
       10

Структура SQL / MySQL

1 голос
/ 21 октября 2009

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

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

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

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

Ответы [ 7 ]

1 голос
/ 21 октября 2009

Я бы предпочел нормализовать базу данных.

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

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

1 голос
/ 21 октября 2009

Как насчет того, чтобы сохранить его денормализованным и затем создать представление, чтобы снова собрать данные вместе. Вы получаете лучшее из обоих миров. IIRC, MySQL представил представления в версии 5.

0 голосов
/ 21 октября 2009

Вам необходимо взвесить следующие факторы:

  • Сколько места вы потратите, если поместить все данные в одну таблицу
  • Насколько сложными будут запросы SQL в любом случае.

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

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

0 голосов
/ 21 октября 2009

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

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

0 голосов
/ 21 октября 2009

Это частично зависит от используемой платформы (если таковая имеется). Например: способ Ruby on Rails обычно заключается в том, чтобы хранить тип платежа в таблице платежей и затем иметь разные отдельные таблицы для каждого типа платежа (PayPal, Кредитная карта и т. Д.).

В качестве альтернативы, если вы заметите, что вы повторяете одни и те же данные во многих таблицах, в Rails есть способ сохранить все данные в одной и той же таблице, используя только те поля, которые вам нужны, но все же позволяя вам иметь отдельные объекты. Например, у вас будет объект AbstractPayment с таблицей abstract_payments, но у вас также будут объекты PayPalPayment и CreditCardPayment, которые оба наследуют от AbstractPayment и используют таблицу abstract_payments. Все, что вам нужно для определения типа платежа, - это столбец в abstract_payments, который сообщает вам, какой это тип (вероятно, строка, но может быть целым числом, если вы того пожелаете). Это называется STI .

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

0 голосов
/ 21 октября 2009

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

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

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

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

Таким образом, база данных по-прежнему нормализована, и у вас нет пустых столбцов.

0 голосов
/ 21 октября 2009

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

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

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