2009-04-01 3 views
1

У меня есть структура данных что-то вроде этого:Проектирование базы данных, на основе структуры данных

typedef struct tagSUB_DATA 
{ 
    double measuredValue; 
    double standardDeviation; 
    double calculatedValue; 
    double weightedError; 

} SUB_DATA; 

typedef struct tagALL_THE_DATA 
{ 
    int aNumber; 
    double aDouble; 
    SUB_DATA measurements1; 
    SUB_DATA measurements2; 

} ALL_THE_DATA; 

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

Мой запрос относится к двум полям, measurements1 и measurements2. Очевидно, что они одного типа, поэтому моя первая мысль была «давайте создадим таблицу SUB_DATA и создадим связь между ними».

Table: ALL_THE_DATA 
Field: ID (int, Primary Key) 
Field: aNumber (int) 
Field: aDouble (double) 
Field: measurements1 (int, Foreign Key referencing SUB_DATA) 
Field: measurements2 (int, Foreign Key referincing SUB_DATA) 

Table: SUB_DATA 
Field: ID (int, Primary Key) 
Field: measuredValue (double) 
Field: standardDeviation (double) 
Field: calculatedValue (double) 
Field: weightedError (double) 

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

Table: ALL_THE_DATA 
Field: ID (int, Primary Key) 
Field: aNumber (int) 
Field: aDouble (double) 
Field: appleMeasurements (int, Foreign Key referencing APPLE_MEASUREMENTS) 
Field: rocketMeasurements (int, Foreign Key referencing ROCKET_MEASUREMENTS) 

Table: APPLE_MEASUREMENTS 
Field: ID (int, Primary Key) 
Field: measuredValue (double) 
Field: standardDeviation (double) 
Field: calculatedValue (double) 
Field: weightedError (double) 

Table: ROCKET_MEASUREMENTS 
Field: ID (int, Primary Key) 
Field: measuredValue (double) 
Field: standardDeviation (double) 
Field: calculatedValue (double) 
Field: weightedError (double) 

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

Приветствия!

(Пожалуйста, простите мои яблоки/Ракета pseudodata - Я не могу отправлять фактический код здесь)

Экстренная Информация:
В этом случае мы можем быть уверены, что ракеты и яблоки не изменят их поля позже, поэтому я не слишком беспокоюсь о случае «что делать, если поля в ракетах или яблоках меняются позже».

ответ

1

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

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

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

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

+0

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

+0

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

+0

В этом случае мы можем быть уверены, что ракеты и яблоки не изменят свои поля позже. – Smashery

-1

Почему бы не создать две таблицы, но унаследовать их от общей таблицы измерений?

+0

Как вы наследуете таблицы в СУБД? – Smashery

+0

Я думаю, это зависит от базы данных, которую вы используете, но POSTGRES поддерживает INHERIT. – CookieOfFortune

+0

Вы можете имитировать наследование, это не так сложно, но это неуклюже, поэтому вы используете ORM для этого. – Uri

0

У вас всегда есть ровно два измерения? Если это так, вам вообще не нужно разбивать таблицу (для двух измерений есть одна таблица с двумя наборами столбцов).

Table: ALL_THE_DATA 
Field: ID (int, Primary Key) 
Field: aNumber (int) 
Field: aDouble (double) 
Field: measuredValue1 (double) 
Field: standardDeviation1 (double) 
Field: calculatedValue1 (double) 
Field: weightedError1 (double) 
Field: measuredValue2 (double) 
Field: standardDeviation2 (double) 
Field: calculatedValue2 (double) 
Field: weightedError2 (double) 

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

Это затрудняет добавление третьего типа измерения.

Смежные вопросы