Советы по разработке базы данных

8

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

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

                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £25'500    | 1 | 1 |   |     |  | 
| RDOL2.2    | £2'000     | 1        |  £1'500    |   | 1 |   |     |  | 
| DOL5.0     | £1'000     | 1        |  £1'200    |   |   | 1 |     |  | 
+------------+------------+----------+------------+---+---+---+ --- +--+

Пользователь выбирает предопределенную сборку, вводит количество и выбирает любые требуемые «опции». Каждая сборка потенциально имеет до 50 доступных опций. Опция также является предопределенной сборкой (сборкой) с собственной ценой. «Общая стоимость» для каждой строки рассчитывается как (основная стоимость сборки * количество) + стоимость любых опций.

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

Теперь это где это становится сложным. Каждая сборка имеет свой список доступных опций. т. е. опция 1 для VSD55 представляет собой сборку, отличную от опции 1 для DOL5.0.

Что касается сборок, то здесь приведены упрощенные таблицы, которые я использую:

+-----------------+    +------------------------+    +-----------------------------+
| assembly        |    | assembly_option        |    | assembly_option_link        |
+-----------------+    +------------------------+    +-----------------------------+
| assembly_id (PK)|    | assembly_option_id (PK)|    | assembly_option_link_id (PK)|
| assembly_name   |    | assembly_option_name   |    | assembly_id (FK)            |
| unit_cost       |    | option_number          |    | assembly_option_id (FK)     |
+-----------------+    | unit_cost              |    +-----------------------------+
                       +------------------------+

Таблица "assembly_option_link" в основном определяет, какие опции доступны для каждой сборки.

Теперь для таблиц «цитата»:

 +-----------------+    +------------------------+    
 | quote           |    | quote_assembly         |    
 +-----------------+    +------------------------+    
 | quote_id (PK)   |    | quote_assembly_id (PK) |
 | quote_name      |    | assembly_id (FK)       |
 +-----------------+    | quantity               |
                        +------------------------+    

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

Я думаю, что «нормализованным» решением было бы создать еще одну таблицу, подобную этой:

+------------------------------+
| quote_assembly_option        |
+------------------------------+
| quote_assembly_option_id (PK)|
| quote_assembly_id (FK)       |
| assembly_option_id (FK)      |
| quantity                     |
+------------------------------+

Это решение означает, что сохраняются только выбранные параметры. Кроме того, вместо сохранения option_number, я могу сохранить фактический «assembly_option_id». Это упрощает вычисление общей стоимости цитаты, поскольку мне не нужно конвертировать между 'option_number' и 'assembly_option_id', чтобы посмотреть стоимость опции сборки. Однако основным недостатком этого решения является то, что оно плохо сочетается с формой ввода пользователя. Я думаю, что мне нужно будет применить какое-то причудливое кодирование, чтобы связать форму с таблицами.

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

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
Это также подробный отчет по предложениям, который расширяет любые выбранные параметры в виде отдельных позиций под основной сборкой. Например:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |   <-option 1
|   - Motor over temp protection  | £   500    | 1        |   £   500  |   <-option 2
+---------------------------------+------------+----------+------------+
|                                 |            |          |   £25'500  |
+---------------------------------+------------+----------+------------+
Дэвид
источник

Ответы:

3
                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £20'000    | 1 | 1 |   |     |  | 

Если бы кто-нибудь передал мне эту цитату, мой первый вопрос был бы «Какой вариант 1 для VSD55?» Ответ будет: «Я не знаю». Эта информация не в цитате. В том маловероятном случае, если этот человек задаст второй вопрос, этот вопрос будет «Сколько это будет стоить?» Опять же, ответ будет «я не знаю». Сразу наступит очень тревожное молчание, во время которого человек, который передал мне цитату, вообразит, насколько лучше чувствовать, когда его сбивает поезд.

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

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

Там нет ничего (много) не так с 50 флажками в форме пользовательского интерфейса. Это позволяет легко выбирать варианты. Но код пользовательского интерфейса должен прочитать флажки и вставить правильную информацию в нормализованные таблицы.

Майк Шеррилл 'Cat Recall'
источник
Похоже, вы предлагаете советы по бизнес-процессам, которые не могут быть выбраны, и Дэвид пытается описать лучший способ, который он знает для назначенного им проекта. ~ Теперь, я согласен, что DBA должен влиять на дизайн там, где это возможно, но иногда это не помогает. Также имейте в виду, что это внутренний инструмент (см. Первую строку)
jcolebrand
1
Достаточно справедливые комментарии, заставили меня смеяться! У нас, конечно же, есть отчет по котировкам, который делает именно то, что вы предлагаете. С тех пор я добавил эту деталь к исходному вопросу, чтобы избежать дальнейших обсуждений вне темы;)
Дэвид
3

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

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

Но твой дизайн звучит для меня правильно.

Jcolebrand
источник
0

Добавление вашей дополнительной таблицы мне тоже кажется вполне обоснованным.

Когда я решал похожую проблему, я решил сохранить дерево в таблице order_lines. Если вы рассматривали что-либо подобное, у меня было:

  • дополнительное parent_idполе для order_linesи внешний ключ, чтобы (parent_id, product_id)ссылаться(order_line_id, product_id)

  • Ограничение проверки для создания опции подразумевает родителя (в моем случае check((option_id is not null) = (parent_id is not null))).

Другими словами, я позволил интерфейсу сказать, как все должно храниться:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |
|   - Motor over temp protection  | £   500    | 1        |   £   500  |
+---------------------------------+------------+----------+------------+

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

Так что не рекомендуется ... Насколько я сталкивался с подобными случаями, ваш нынешний подход будет менее подвержен проблемам в будущем.

Дени де Бернарди
источник